带有绘图线程的自定义视图可防止显示所有视图

时间:2015-06-19 17:09:57

标签: android android-layout android-canvas surfaceview

我创建了一个自定义视图类并为其附加了一个线程。然后,我使用相应活动的xml布局文件添加了视图,该文件中还有其他视图,例如工具栏和textview。但是,添加自定义视图时不显示任何视图;只是具有默认颜色的背景。没有错误。线程工作正常,我可以从调试日志中看到每个帧的时间差。但是,我看不出为什么没有显示任何视图。谢谢你的帮助...

xml布局:

;WITH Src AS
    (
        SELECT
            *
            ,ID-ROW_NUMBER() OVER (PARTITION BY ActionCode, Group1,Type ORDER BY ID) AS ContiguousGroupID
        FROM #TestTable
    )

SELECT
    ContiguousGroupID
    ,ActionCode
    ,Group1
    ,Type
    ,min(ID) AS LowerIDBound
    ,max(ID) AS UpperIDBound
    ,min(convert(int,Low)) AS Low
    ,max(convert(int,High)) AS High
FROM Src
GROUP BY
    ContiguousGroupID
    ,ActionCode
    ,Group1
    ,Type
ORDER BY
    ContiguousGroupID
    ,ActionCode
    ,Group1
    ,Type

自定义视图类:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
    android:layout_height="match_parent"

    android:orientation="vertical"
    android:focusable="false">

    <android.support.v7.widget.Toolbar
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/toolbar"
        android:minHeight="?attr/actionBarSize"
        android:background="?attr/colorPrimary"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
        android:popupTheme="@style/ThemeOverlay.AppCompat.Light">
    </android.support.v7.widget.Toolbar>



    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
        android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
        android:paddingRight="@dimen/activity_horizontal_margin"
        android:paddingTop="@dimen/activity_vertical_margin"
        android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".HomeActivity"
        android:orientation="vertical"
        android:id="@+id/background"
        android:focusable="false"
        android:animateLayoutChanges="true">

        <com.puppetlabs.canvastutorial.MyCanvasView
            android:layout_width="100dp"
            android:layout_height="100dp"
            android:id="@+id/mycanvasview"/>

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textAppearance="?android:attr/textAppearanceLarge"
            android:text="Large Text"
            android:id="@+id/textView" />

    </LinearLayout>

</LinearLayout>

和我对应的线程类是:

package com.mert.canvastutorial;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.util.AttributeSet;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

/**
 * Created by Pc on 19.6.2015.
 */
public class MyCanvasView extends SurfaceView implements SurfaceHolder.Callback{

    private MyCanvasThread thread;

    private void init() {
        getHolder().addCallback(this);
        Log.d("SURFACE_VIEW", "Initialized.");
        // create the game loop thread
        thread = new MyCanvasThread(getHolder(),this);
        // make the GamePanel focusable so it can handle events
        setFocusable(true);
    }
    public MyCanvasView(Context context) {
        super(context);
        init();
    }

    public MyCanvasView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();

    }

    public MyCanvasView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();

    }

    public void update(){

    }

    public void render(Canvas c){
        c.drawColor(Color.RED);

    }

    @Override
    protected void onDraw(Canvas canvas) {
        //super.onDraw(canvas);
        //canvas.drawColor(Color.parseColor("#00dd00"));

    }


    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        thread.setRunning(true);
        thread.start();
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
        boolean retry = true;
        while (retry) {
            try {
                thread.join();
                retry = false;
            } catch (InterruptedException e) {}
        }
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {

    }
}

我将自定义视图添加到xml布局文件中的活动:

1 个答案:

答案 0 :(得分:0)

“自定义视图”与子类化SurfaceView不同。 SurfaceView有两个部分,Surface和View。如果您要在View部件上绘图,则需要使用自定义View,而根本不需要SurfaceView。 (有关此方法的更多信息,请参阅Creating Custom Views。)

由于您尝试在SurfaceView的Surface上绘图,您可能不希望覆盖onDraw(),实际上您根本不需要继承SurfaceView。最佳做法是favor composition over inheritance

SurfaceView的View部分旨在成为透明矩形,布局代码使用该矩形在View图层中留下“洞”。 SurfaceView Surface位于单独的图层上,默认情况下位于View图层后面。如果您为视图设置背景或在其上绘制,您将模糊Surface,并且将无法看到任何内容。

使用onCreate()中的setZOrderOnTop()(在创建Surface后调用无效),您可以通过在顶部移动SurfaceView来轻松确定是否是这种情况。如果您执行此操作时突然出现Surface内容,那么您的问题是您已填写SurfaceView的View部分。

Grafika中的“multi-surface test”活动演示了多个重叠SurfaceView上的动画画布渲染。

FWIW,我建议您查看图形架构文档的SurfaceView lifecyclegame loop部分。