如何通过按下按钮启动xml定义的表面视图?

时间:2011-04-07 04:05:39

标签: android xml surfaceholder

我已经从另一个教程中构建了我的初始代码,以创建处理SurfaceView绘图的类。本教程(以及我发现的其他教程)将xml定义的SurfaceView与一个在创建活动时启动的类相关联。我的目标是在按下布局中的按钮并在我再次按下它时终止它时,在xml定义的表面视图中启动动画。

此外,动画必须在我在xml中指定的区域内运行(而不是整个显示)。

为简单起见,我目前只在surfaceview中绘制一个圆圈,直到我弄清楚如何让我的布局工作。

因此,当我单击Go按钮(BattleActivity :: onClick)时,我的表面视图会被创建并绘制,但它会填满整个显示,覆盖我布局中的其他控件,包括按钮。我希望动画仅在作为布局的一部分定义的表面视图中进行(id = battleView)。

这是我的XML布局代码(tabBattle.xml)的一个子部分。

<LinearLayout
    android:orientation="vertical"
    android:gravity="center"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">

    <SurfaceView
        android:id="@+id/battleView"
        android:layout_weight="70"
        android:layout_width="fill_parent" 
        android:layout_height="wrap_content" 
        android:layout_gravity="center_horizontal"/>        

    <Button
        android:onClick="onClick"
        android:text=" Go "
        android:gravity="center"
        android:layout_weight="30"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>

</LinearLayout>

这是我的主要活动课程。这是在我导航到其布局(tabBattle)所在的选项卡视图时创建的。按下Go按钮时会调用onClick。我在onClick中的意图是获取表面视图,创建一个新的BattleView实例,并将表面视图上下文传递给BattleView构造函数。这显然是不正确的,但我不知道如何做到这一点。

公共类BattleActivity扩展Activity实现View.OnClickListener {     @覆盖     public void onCreate(Bundle savedInstanceState)     {         super.onCreate(savedInstanceState);         的setContentView(R.layout.tabbattle);     }

@Override
public void onClick(View v)
{
    SurfaceView battleSurface = (SurfaceView)findViewById(R.id.battleView);
    setContentView(new BattleView( battleSurface.getContext() ));
}

}

SurfaceView子类:

公共类BattleView扩展了SurfaceView实现的SurfaceHolder.Callback {     private int circleRadius;     私人Paint circlePaint;     UpdateThreadBattle updateThread;

private int width;
private int height;
private int xPos;
private int yPos;
private int xVel;
private int yVel;

public BattleView(Context context)
{
    super(context);
    getHolder().addCallback(this);

    circleRadius = 10;
    circlePaint = new Paint();
    circlePaint.setColor(Color.BLUE);

    xVel = 2;
    yVel = 2;       
}

@Override
protected void onDraw(Canvas canvas) {
    canvas.drawColor(Color.WHITE);
    canvas.drawCircle(xPos, yPos, circleRadius, circlePaint);
}


@Override
public void surfaceCreated(SurfaceHolder holder)
{
    Rect surfaceFrame = holder.getSurfaceFrame();
    width = surfaceFrame.width();
    height = surfaceFrame.height();

    xPos = width / 2;
    yPos = circleRadius;

    updateThread = new UpdateThreadBattle(this);
    updateThread.setRunning(true);
    updateThread.start();
}

@Override
public void surfaceDestroyed(SurfaceHolder arg0)
{
    boolean retry = true;

    updateThread.setRunning(false);

    while (retry) {
        try {
            updateThread.join();
            retry = false;
        } catch (InterruptedException e) {

        }
    }
}

@Override
public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {
    // TODO Auto-generated method stub

}

}

正如你可能已经怀疑的那样,我对android和java一般都是新手。非常感谢任何帮助!

格雷格

1 个答案:

答案 0 :(得分:0)

我选择的最终解决方案是利用计时器而不是实现基于线程的表面动画,这对于我在视图中需要的简单动画来说是过度的。当时我写了一个我不知道计时器的问题。它很棒,brw!