如何创建带圆角的 surfaceview
How to create surfaceview with rounded corners
我很难将 SurfaceView 的边角圆化。我正在使用 MjpegView
(继承自 surfaceview 的自定义视图。
我已经尝试过这个解决方案:
1)用带圆角的自定义绘图设置背景
2) 看完这篇 post http://androidtutorialsandtips.blogspot.co.il/2012/01/overriding-ondraw-method-in-surfaceview.html
我不确定如何实现圆角,因为我已经实现了一个锁定 canvas.
的线程
while (mRun)
{
if (surfaceDone)
{
try
{
c = mSurfaceHolder.lockCanvas();
synchronized (mSurfaceHolder)
{
try
{
if (mIn != null)
{
Bitmap bm = mIn.readMjpegFrame();
destRect = destRect(bm.getWidth(), bm.getHeight());
if (streamHeight == -1 && streamWidth == -1)
{
streamWidth = bm.getWidth();
streamHeight = bm.getHeight();
}
c.drawColor(Color.BLACK);
c.drawBitmap(bm, null, destRect, p);
if (showFps)
{
p.setXfermode(mode);
if (ovl != null)
{
height = ((ovlPos & 1) == 1) ? destRect.top : destRect.bottom - ovl.getHeight();
width = ((ovlPos & 8) == 8) ? destRect.left : destRect.right - ovl.getWidth();
c.drawBitmap(ovl, width, height, null);
}
p.setXfermode(null);
frameCounter++;
if ((System.currentTimeMillis() - start) >= 1000)
{
fps = String.valueOf(frameCounter) + "fps";
frameCounter = 0;
start = System.currentTimeMillis();
ovl = makeFpsOverlay(overlayPaint, fps);
}
}
}
}
catch (IOException e)
{
}
}
}
finally
{
if (c != null) mSurfaceHolder.unlockCanvasAndPost(c);
}
}
}
如果我正确理解你的问题:
创建一个包含 2 个子项的 <FrameLayout ...>
:表面视图及其上方的部分透明覆盖层。 (FrameLayout
将其子级绘制在另一个之上。)
在覆盖层上画圆角
也就是说,您将在 SurfaceView
上方有一个不透明层,并且该不透明层的中心将有一个带圆角的透明孔。
这是一个示例,其中我用 50% 透明的黑色层(visibility="invisible" 覆盖 SurfaceView,默认情况下)和一个内部带有按钮的 RelativeLayout。
<FrameLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<SurfaceView
android:id="@+id/camera_preview"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_centerInParent="true" />
<View
android:id="@+id/transparency"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#80000000"
android:visibility="invisible"
/>
<RelativeLayout
android:id="@+id/xxxxx"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
...
要达到你的要求,很容易做到。你只需要使用下一个XML:
<androidx.cardview.widget.CardView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:cardCornerRadius="12dp">
<SurfaceView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center" />
</androidx.cardview.widget.CardView>
要使用此 CardView,请将此依赖项添加到您的 build.gradle 应用程序:
implementation 'androidx.cardview:cardview:1.0.0'
我很难将 SurfaceView 的边角圆化。我正在使用 MjpegView (继承自 surfaceview 的自定义视图。 我已经尝试过这个解决方案: 1)用带圆角的自定义绘图设置背景 2) 看完这篇 post http://androidtutorialsandtips.blogspot.co.il/2012/01/overriding-ondraw-method-in-surfaceview.html 我不确定如何实现圆角,因为我已经实现了一个锁定 canvas.
的线程while (mRun)
{
if (surfaceDone)
{
try
{
c = mSurfaceHolder.lockCanvas();
synchronized (mSurfaceHolder)
{
try
{
if (mIn != null)
{
Bitmap bm = mIn.readMjpegFrame();
destRect = destRect(bm.getWidth(), bm.getHeight());
if (streamHeight == -1 && streamWidth == -1)
{
streamWidth = bm.getWidth();
streamHeight = bm.getHeight();
}
c.drawColor(Color.BLACK);
c.drawBitmap(bm, null, destRect, p);
if (showFps)
{
p.setXfermode(mode);
if (ovl != null)
{
height = ((ovlPos & 1) == 1) ? destRect.top : destRect.bottom - ovl.getHeight();
width = ((ovlPos & 8) == 8) ? destRect.left : destRect.right - ovl.getWidth();
c.drawBitmap(ovl, width, height, null);
}
p.setXfermode(null);
frameCounter++;
if ((System.currentTimeMillis() - start) >= 1000)
{
fps = String.valueOf(frameCounter) + "fps";
frameCounter = 0;
start = System.currentTimeMillis();
ovl = makeFpsOverlay(overlayPaint, fps);
}
}
}
}
catch (IOException e)
{
}
}
}
finally
{
if (c != null) mSurfaceHolder.unlockCanvasAndPost(c);
}
}
}
如果我正确理解你的问题:
创建一个包含 2 个子项的
<FrameLayout ...>
:表面视图及其上方的部分透明覆盖层。 (FrameLayout
将其子级绘制在另一个之上。)在覆盖层上画圆角
也就是说,您将在 SurfaceView
上方有一个不透明层,并且该不透明层的中心将有一个带圆角的透明孔。
这是一个示例,其中我用 50% 透明的黑色层(visibility="invisible" 覆盖 SurfaceView,默认情况下)和一个内部带有按钮的 RelativeLayout。
<FrameLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<SurfaceView
android:id="@+id/camera_preview"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_centerInParent="true" />
<View
android:id="@+id/transparency"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#80000000"
android:visibility="invisible"
/>
<RelativeLayout
android:id="@+id/xxxxx"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
...
要达到你的要求,很容易做到。你只需要使用下一个XML:
<androidx.cardview.widget.CardView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:cardCornerRadius="12dp">
<SurfaceView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center" />
</androidx.cardview.widget.CardView>
要使用此 CardView,请将此依赖项添加到您的 build.gradle 应用程序:
implementation 'androidx.cardview:cardview:1.0.0'