防止自定义SurfaceView在其他视图之上绘制

时间:2016-07-19 11:11:14

标签: android android-layout drawing

我创建了一个用于绘制形状的自定义SurfaceView,用户可以缩放和平移视图以与形状进行交互。这一切都很有效,但现在的问题是形状总是在我的屏幕上的所有之上绘制,也可以在其他视图(如按钮和textview)之上绘制。我尝试在XML布局中以不同的方式排序自定义视图和我的按钮,尝试将视图父级化为FrameLayouts和RelativeLayouts(as suggested here)。

我想将按钮和其他布局元素浮动在我的自定义视图之上。如下图所示,当我平移视图时,矩形会遮挡按钮。

如何阻止我的自定义SurfaceView绘制在所有内容之上?

enter image description here

我的绘图代码在SurfaceView类的一个单独的线程中运行:

public class CustomShapeView extends SurfaceView implements Runnable, SurfaceHolder.Callback {

/* Other implementation stuff */

@Override
public void run() {
    while (isDrawing) {
        if (!holder.getSurface().isValid())
            continue; //wait till it becomes valid  

        Canvas canvas = null;
        try {
            canvas = holder.lockCanvas(null);
            synchronized (holder) {
                try {
                    lock.lock();                                
                    canvas.concat(sampleMatrix);
                    canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
                    drawShapes(canvas);                     
                } finally {
                    lock.unlock();
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (canvas != null) {
                holder.unlockCanvasAndPost(canvas);
            }
        }       
    }
}
}

我的测试XML布局,我希望创建一个位于自定义视图后面的按钮(左)和一个浮动在自定义视图上方的按钮(右):

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">

<Button
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Left"
    android:id="@+id/button"
    android:layout_alignParentBottom="true"
    android:layout_alignParentLeft="true"/>

<FrameLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <com.example.CustomShapeView
        android:id="@+id/floor_plan_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        />
</FrameLayout>

<RelativeLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Right"
        android:id="@+id/button2"
        android:layout_alignParentBottom="true"
        android:layout_alignParentRight="true"
        android:layout_alignParentEnd="true"/>
</RelativeLayout>   
</RelativeLayout>

2 个答案:

答案 0 :(得分:4)

在我的代码中,我调用函数setZOrderOnTop(true);,确保表面视图始终绘制在所有内容之上。这段代码由前一个开发人员保留,以便为画布提供自定义背景,而不是仅使用纯色。使用SurfaceView,可以在为画布设置自定义背景或在画布顶部绘制视图之间进行权衡。

选项是

  1. 使用setZOrderOnTop(true);可以有自定义背景,但没有重叠视图。
  2. 使用setZOrderOnTop(false);可以覆盖视图但只有纯色背景(通过调用例如canvas.drawColor(Color.WHITE);来清除绘制调用之间)。
  3. 我选择了第二个选项,因为我重视在自定义背景上覆盖视图。

答案 1 :(得分:2)

我面临类似的问题。我想在SurfaceView中设置动画的其他视图之间添加透明RelativeLayout。当我这样做时,在动画视图中有时会消失,有时只有部分可见,这很奇怪。然后我发现我是先将SurfaceView放到布局上(所以在底部),然后我调用SurfaceView.setZOrderMediaOverlay(true),在窗口底部绘制SurfaceView的内容,视图是画在上面。如果我将SurfaceView放在布局中的任何位置然后调用SurfaceView.setZOrderOnTop(true),则内容始终绘制在窗口的顶部(也位于视图的顶部)。如果我在视图之间放置SurfaceView,它的行为是疯狂的,也许是因为SurfaceView的内容是从分离的线程中提取的,而视图是从GUI(主)线程中提取的,因此它们是&# 34;战斗&#34;这就是为什么这种行为。我发现的唯一方法是在底部或顶部绘制。尝试创建一个透明背景的新Fragment,其中SurfaceView位于底部,正如我在第一种情况下所描述的那样,并将您想要的按钮放在上面(所以稍后将其添加到某些按钮中) RelativeLayoutFrameLayout)然后将此片段显示在活动的顶部,该活动包含您希望在其下方拥有的内容。希望我帮了一下。