想必想要一个屏幕是很普遍的 在同一屏幕上有图形元素(您可能喜欢使用 Canvas )和小部件/按钮。但到目前为止,我所看到的所有内容都提供了充满小部件的屏幕或 整个屏幕 Canvas 的示例。有人可以指点我同时使用两者的一些示例代码吗。
...或者这不是完成的事情?
编辑:根据史蒂夫的建议,我的代码现在看起来像这样:
public class CanLay extends Activity
{
Bitmap bm;
@Override
protected void onCreate(Bundle savedInstanceState)
{
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.canlay);
InputStream is = getResources().openRawResource(R.drawable.ella);
bm = BitmapFactory.decodeStream(is);
SurfaceView sv;
SurfaceHolder sh;
Canvas can = null;
sv = (SurfaceView)findViewById(R.id.surview);
sh = sv.getHolder();
try
{
can = sh.lockCanvas(null);
synchronized(sh)
{
can.drawBitmap(bm, 0, 0, null);
}
}
finally
{
if (can != null)
{
sh.unlockCanvasAndPost(can);
}
}
}
}
现在唯一的问题是 sh.lockCanvas(null);总是返回 null。
最佳答案
我不知道有任何示例代码,但您通常会从 SurfaceView
获得一个 Canvas
,这是一个像其他 View 一样的 View
小部件(例如,TextView
和 Button
)。我会尝试将 SurfaceView
与布局的其他元素一起布置。您的基本 XML 结构可能类似于
<LinearLayout >
<TextView />
<Button />
<SurfaceView />
</LinearLayout>
编辑:
要从 SurfaceView
获取 Canvas
,首先获取 SurfaceHolder
,然后锁定 Canvas ,绘制您的东西,然后解锁 Canvas 以显示它。在通常看起来像的代码中:
SurfaceHolder holder = surfaceView.getHolder();
Canvas c = null;
try {
c = holder.lockCanvas(null);
synchronized(holder) {
// draw here
// c.drawBitmap() or whatever
}
} finally {
if(c != null)
holder.unlockCanvasAndPost(c);
}
双重编辑:
根据docs , lockCanvas
在表面未准备好时返回 null。当您仍在 onCreate()
中时,表面肯定还没有准备好。您知道表面已准备就绪的方法是处理对 SurfaceHolder.Callback.surfaceCreated()
的回调。 . (游戏通常使用 surfaceCreated()
来了解何时开始运行它们的非事件线程。)
我知道这听起来像是您要做的事情越来越多,但实际上并没有那么糟糕。你甚至可以像这样内联:
void onCreate(Bundle savedInstanceState) {
// inflate the XML with setContentView(), create your Bitmap, etc
sv = (SurfaceView)findViewById(R.id.surview);
sv.addCallback(new SurfaceHolder.Callback() {
@Override
void surfaceCreated(SurfaceHolder holder) {
Canvas can;
try {
can = holder.lockCanvas(null);
synchronized(holder) {
can.drawBitmap(bm, 0, 0, null);
}
} finally {
if(can != null) {
holder.unlockCanvasAndPost(can);
}
}});
// the rest of onCreate()
}
我可能搞砸了一些牙套,但你明白了。总的来说,将您的 SurfaceHolder.Callback
实现放在它自己的非匿名类中可能更容易,因为对匿名有限制,但这就是您了解您的 SurfaceView
的方式已准备好营业。当然,最好实现 SurfaceHolder.Callback.surfaceDestroyed()
,这样您就可以知道 SurfaceView
何时停止运行。 (游戏经常使用 surfaceDestroyed()
来知道何时停止运行它们的非事件线程!)
关于java - 结合 Canvas 和布局?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8434308/