从布局xml中绘制SurfaceView

7
对于我从代码中创建的SurfaceView,我可以重写onDraw()方法。
但是如何覆盖在布局XML中定义的SurfaceView中的onDraw()方法?是否有任何方法可以访问draw()方法?
1个回答

30

如果您像这样声明并将SurfaceView实例添加到布局中,那么您无法访问onDraw方法:

<SurfaceView
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" />

上述声明创建了一个android.view.SurfaceView实例并将其添加到您的布局中。您不能改变该实例的onDraw方法的行为,就像您不能更改任何其他已编译类中的代码/行为一样。

要实现您所要求的功能,您可以创建自己的SurfaceView子类:

package myapp.views;

import android.view.SurfaceView;

public MySurfaceView extends SurfaceView implements Callback {
   ...
}

然后,要将其添加到您的布局中,而不是原始的vanilla SurfaceView,您只需在布局中引用您的类的完全限定名称作为XML元素:

<myapp.views.MySurfaceView
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" />

你的SurfaceView子类必须声明一个构造函数,该构造函数以ContextAttributeSet作为参数。同时不要忘记你的SurfaceView应该实现SurfaceHolder.Callback并将其注册到其SurfaceHolder中:

public MySurfaceView(Context context, AttributeSet attributeSet) {
    super(context, attributeSet);
    getHolder().addCallback(this);
}

draw方法不会自动调用,但你可以确保当SurfaceView初始化时,你的视图的初始状态被绘制。一个回调将在surfaceCreated中被调用,在那里你可以调用draw方法:

public void surfaceCreated(SurfaceHolder holder) {
    Canvas c = getHolder().lockCanvas();
    draw(c);
    getHolder().unlockCanvasAndPost(c);
}

看这里!


如何在XML中引用我的类?我找不到方法怎么做? - Fugogugo
1
再次查看上面的XML片段。实际的XML元素是您的类名。这并不是非常直观或符合XML的风格,那是肯定的。 - svjson
我不明白?这是不是意味着我需要“导入”我的包名称或者其他什么? - Fugogugo
2
你不需要“导入”你的包名,只需指出你自己实现的SurfaceView,它将被实例化并添加到你的布局中,而不是普通的SurfaceView。我已经编辑了上面的答案以澄清这一点。希望能有所帮助。 - svjson

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接