java - 结合 Canvas 和布局?

标签 java android

想必想要一个屏幕是很普遍的 在同一屏幕上有图形元素(您可能喜欢使用 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小部件(例如,TextViewButton)。我会尝试将 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/

相关文章:

android - 从对话框中删除边框,填充

java - 创建用于内部应用程序的 Web 服务并将其公开给其他人

java - Drawable 不显示在 ImageView 中

android - (intent.getStringExtra ("PaymentDetails") 为空

java - Android在代码中访问XML常量实际值

android - 布局 XML 中定义的谷歌地图标记

java - java 帮助中的命令行参数

java - 如何让代码比较数组中的 2 个值?

java - 我尝试编写我的第一个 Bukkit 插件,但无法安装它

java - 执行 LEFT_RIGHT 滑动菜单时的奇怪行为