我们如何从xml布局文件中访问表面视图类?

时间:2013-09-26 17:27:41

标签: java android xml surfaceview

基本上,我正在实现一个系统,其中视图由按钮和表面视图组成。此表面视图以编程方式在主活动的类中定义。现在我需要将它添加为xml文件的一部分,因为它是自己的标记。

当前的xml代码是:

<RelativeLayout 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:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity" >

   <Button
        android:id="@+id/downbutton"
        android:layout_width="100dip"
        android:layout_height="75dip"
        android:layout_alignLeft="@+id/upbutton"
        android:layout_centerVertical="true"
        android:text="Down" />

    <Button
        android:id="@+id/rightbutton"
        android:layout_width="100dip"
        android:layout_height="75dip"
        android:layout_alignBottom="@+id/leftbutton"
        android:layout_marginLeft="80dp"
        android:layout_toRightOf="@+id/upbutton"
        android:text="Right" />

    <Button
        android:id="@+id/leftbutton"
        android:layout_width="100dip"
        android:layout_height="75dip"
        android:layout_above="@+id/downbutton"
        android:layout_marginRight="80dp"
        android:layout_toLeftOf="@+id/upbutton"
        android:text="Left" />

    <Button
        android:id="@+id/upbutton"
        android:layout_width="100dip"
        android:layout_height="75dip"
        android:layout_above="@+id/rightbutton"
        android:layout_centerHorizontal="true"
        android:text="Up" />

    <com.example.gui.GridSurfaceView
        android:id="@+id/gridsurfaceview"
        android:layout_width="fill_parent"
        android:layout_height="300dp"
        android:layout_alignParentBottom="true"
        android:layout_centerHorizontal="true"
        android:background="#cbfff4" />

</RelativeLayout>

这里,“com.example.gui.GridSurfaceView”指的是表面视图类。但是,我的表面视图类现在已放置在主活动的类中,并且无法删除(因为表面视图类需要访问该活动的某些变量)。当表面视图拥有它自己的类时,视图看起来很好但是现在,这个xml导致了一些问题。如何更改xml以再次包含曲面视图?

编辑 - 好吧,既然被问到,这里也是活动代码。由于代码太大,我已经包含了包含表面视图的活动部分。注意,主要活动的名称是“Robotremote”,而surfaceview是“GridSurfaceView”

public class GridSurfaceView extends SurfaceView implements Runnable {

SurfaceHolder GridSurfaceHolder;
Thread gridThread = null;
boolean isRunning = false;
Paint paint;
Typeface mFont = Typeface.create(Typeface.SANS_SERIF, Typeface.BOLD);
Paint red;

public GridSurfaceView(Context context) {
    // TODO Auto-generated constructor stub
    super(context);
    paint = new Paint();
    paint.setTextSize(14);
    paint.setTypeface(mFont);
    paint.setAntiAlias(true);
    red = new Paint();
    red.setColor(getResources().getColor(R.color.position));
    GridSurfaceHolder = getHolder();
    gridThread = new Thread(this); //allows for the usage of the run method of     this class. 
    gridThread.start();
}

public void pause(){
    isRunning = false;
    while(true){
        try {
            gridThread.join();
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        break;
        }
        gridThread = null; 
}

public void resume(){
    isRunning = true;
    gridThread = new Thread(this);
    gridThread.start();
}

@Override
public void run() {
    // TODO Auto-generated method stub
    while(isRunning){
        if(!GridSurfaceHolder.getSurface().isValid())
            continue;

        Canvas gridcanvas = GridSurfaceHolder.lockCanvas();
        gridtobedrawn = com.example.gui.Robotremote.getGrid();
        paint.setColor(Color.BLACK);
        paint.setStrokeWidth(3);
        gridcanvas.drawRect(130, 130, 180, 180, paint);
        gridtobedrawn.draw(gridcanvas, paint);
        gridcanvas.drawCircle(xCoord, yCoord, (30*0.45f), red);

    }

}

}

2 个答案:

答案 0 :(得分:1)

以下是解决此问题的方法:

在自定义视图中定义侦听器接口,并定义侦听器设置器。 并在你的活动的onCreate方法拉取视图,将其转换为GridSurfaceView并添加一个实现你的接口监听器的匿名类(如按钮的setOnCLickListener)

并且在界面的实现中,您可以使用活动的任何字段

--------------------------------------------------------------------

编辑

使用侦听器解耦GridSurfaceView以将xCoord和yCoord注入到视图中,从而允许GridSurfaceView与您分离活动:

  1. 在GridSurfaceView中定义一个接口来处理xCoord,yCoord注入:

    public interface CoordsProvider {
        public double getXCoord();
        public double getYCoord(); // am assuming your xCoord and yCoord are doubles
    }
    
  2. 在GridSurfaceView中定义字段提供程序

    CoordsProvider provider;
    
  3. 在GridSurfaceView

    中为您的提供者定义一个setter
     public void setCoordsProvider(CoordsProvider p){
          provider = p;
     }
    
  4. 在你的run方法中,不是直接使用xCoords和yCoords,而是像这样调用你的coords提供者:

    gridcanvas.drawCircle(provider.getXCoord(), provider.getYCoord(), (30*0.45f), red);
    
  5. 修改GridSurfaceView构造函数,使其可以从xml中膨胀。您所要做的就是向构造函数添加一个参数:

     public GridSurfaceView(Context context, AttributeSet attrs) {
        super(context, attrs);
    ...//same code
    
  6. 将您的GridSurfaceView放在xml布局文件中,就像在帖子中一样

  7. 使用findViewById在setContentView之后将其拉入Activity的onCreate方法:

     @Override
    protected void onCreate(Bundle savedInstanceState)  {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.your_layout_id);
        gridSurfaceView = (GridSurfaceView) findViewById(R.id.gridsurfaceview);
    
        gridSurfaceView.setCoordsProvider(new CoordsProvider(){
            @Override
            public double getXCoord(){return xCoord;}
    
            @Override
            public double getYCoord(){return yCoord;}
        });
    

答案 1 :(得分:0)

当将自定义视图作为内部类放置时,您无法定义它。可以认为它必须是独立的,并且为了实例化自定义视图,它必须实例化整个Activity。

我建议在XML中使用FrameLayout或ViewStub占位符,并以编程方式对自定义视图进行膨胀。