以编程方式创建视图

时间:2013-01-11 20:37:20

标签: android android-view textview

我正在以编程方式创建视图。每次我运行程序时,调试都指向我

OperationView operationView =(OperationView)getChildAt(i);

这是我的代码:

protected void onLayout(boolean changed, int l, int t, int r, int b) {
    int size = getWidth();
    int oneTenth = size / 10;

    int count = getChildCount();

        for (int i = 0; i < count; i++) {
            if (i%2==1){
                Log.d(null,"tile");
                TileView tileView = (TileView) getChildAt(i);
                int tleft = oneTenth * tileView.getCol();
                int ttop = oneTenth * tileView.getRow();
                int tright = oneTenth * tileView.getCol() + oneTenth;
                int tbottom = oneTenth * tileView.getRow() + oneTenth;
                tileView.layout(tleft, ttop, tright, tbottom);
                tileView.setGravity(Gravity.CENTER);
            }

            else {
                Log.d(null,"operation");
                OperationView operationView = (OperationView) getChildAt(i);
                int oleft = oneTenth * operationView.getCol();
                int otop = oneTenth * operationView.getRow();
                int oright = oneTenth * operationView.getCol() + oneTenth;
                int obottom = oneTenth * operationView.getRow() + oneTenth;
                operationView.layout(oleft, otop, oright, obottom);
                operationView.setGravity(Gravity.CENTER);
            }           
         }                      
}


@SuppressLint("NewApi")
protected class TileView extends TextView{
    private int tileType;
    private int col;
    private int row;

    protected TileView(Context context, int row, int col, int tileType) {
        super(context);
        this.col = col;
        this.row = row;
        this.tileType = tileType;

        String result = Integer.toString(RandomNumber(1,20));

        Drawable image = getResources().getDrawable(tileType);
        setBackgroundDrawable(image);
        setClickable(true);
        setText(result);
        setOnClickListener(GameView.this);          
    }

    public int getTileType(){
        return tileType;
    }


    public int RandomNumber(int min, int max){
        int Result;
        Result = (int) (Math.floor(Math.random() * (max - min + 1)) + min);
        return Result;
    }

    public void setRandomType() {
        tileType = random.nextInt(3);
        //tileType = PickRandomByChance(tileType);
        Drawable image = getResources().getDrawable(tileType);
        setBackgroundDrawable(image);
    }

    public int getCol() {
        return col;
    }

    public int getRow() {
        return row;
    }

    public void setCol(int col) {
        this.col = col;
    }

    public void setRow(int row) {
        this.row = row;
    }           
}


@SuppressLint("NewApi")
protected class OperationView extends TextView{
    private int col;
    private int row;

    @SuppressWarnings("deprecation")
    protected OperationView(Context context, int row, int col) {
        super(context);
        this.col = col;
        this.row = row;

        String result = Character.toString(randomOper());
        //String result = Integer.toString(RandomNumber(1,20));

        Drawable image = getResources().getDrawable(R.drawable.normal);
        setBackgroundDrawable(image);
        setClickable(true);
        setText(result);
        setOnClickListener(GameView.this);          
    }       

    public char randomOper() {    
          oper[0] = '+';
          oper[1] = '-';
          oper[2] = 'x';
          oper[3] = '/';

          if (rounds==3){
              weight1[0] = 60;
              weight1[1] = 20;
              weight1[2] = 20;
              weight1[3] = 0;
          }           
          else{
              weight1[0] = 50;
              weight1[1] = 30;
              weight1[2] = 10;
              weight1[3] = 10;
          }

          weightSum[0] = weight1[0];

          for (z = 1; z < 4; z++) {
              weightSum[z] = weightSum[z-1] + weight1[z];
          }

          for (j = 0; j < 1; j++) {
              k = rand.nextInt(weightSum[3]);
              for (z = 0; k > weightSum[z]; z++);
              //Log.d(null, "operation: " + oper[z]);                             
          } 
          return oper[z];
      }

    public int getCol() {
        return col;
    }

    public int getRow() {
        return row;
    }

    public void setCol(int col) {
        this.col = col;
    }

    public void setRow(int row) {
        this.row = row;
    }           
}   

我做错了什么?我应该怎么做呢?

编辑:这是logcat

01-12 04:55:05.339:E / AndroidRuntime(29253):致命异常:主要 01-12 04:55:05.339:E / AndroidRuntime(29253):java.lang.ClassCastException:com.jrs.math.GameView $ OperationView 01-12 04:55:05.339:E / AndroidRuntime(29253):at com.jrs.math.GameView.onLayout(GameView.java:238) 01-12 04:55:05.339:E / AndroidRuntime(29253):在android.view.View.layout(View.java:7175) 01-12 04:55:05.339:E / AndroidRuntime(29253):在android.widget.LinearLayout.setChildFrame(LinearLayout.java:1254) 01-12 04:55:05.339:E / AndroidRuntime(29253):在android.widget.LinearLayout.layoutHorizo​​ntal(LinearLayout.java:1243) 01-12 04:55:05.339:E / AndroidRuntime(29253):在android.widget.LinearLayout.onLayout(LinearLayout.java:1049) 01-12 04:55:05.339:E / AndroidRuntime(29253):在android.view.View.layout(View.java:7175) 01-12 04:55:05.339:E / AndroidRuntime(29253):在android.widget.LinearLayout.setChildFrame(LinearLayout.java:1254) 01-12 04:55:05.339:E / AndroidRuntime(29253):在android.widget.LinearLayout.layoutVertical(LinearLayout.java:1130) 01-12 04:55:05.339:E / AndroidRuntime(29253):在android.widget.LinearLayout.onLayout(LinearLayout.java:1047) 01-12 04:55:05.339:E / AndroidRuntime(29253):在android.view.View.layout(View.java:7175) 01-12 04:55:05.339:E / AndroidRuntime(29253):在android.widget.FrameLayout.onLayout(FrameLayout.java:338) 01-12 04:55:05.339:E / AndroidRuntime(29253):在android.view.View.layout(View.java:7175) 01-12 04:55:05.339:E / AndroidRuntime(29253):在android.widget.FrameLayout.onLayout(FrameLayout.java:338) 01-12 04:55:05.339:E / AndroidRuntime(29253):在android.view.View.layout(View.java:7175) 01-12 04:55:05.339:E / AndroidRuntime(29253):在android.view.ViewRoot.performTraversals(ViewRoot.java:1142) 01-12 04:55:05.339:E / AndroidRuntime(29253):在android.view.ViewRoot.handleMessage(ViewRoot.java:1861) 01-12 04:55:05.339:E / AndroidRuntime(29253):在android.os.Handler.dispatchMessage(Handler.java:99) 01-12 04:55:05.339:E / AndroidRuntime(29253):在android.os.Looper.loop(Looper.java:123) 01-12 04:55:05.339:E / AndroidRuntime(29253):在android.app.ActivityThread.main(ActivityThread.java:3729) 01-12 04:55:05.339:E / AndroidRuntime(29253):at java.lang.reflect.Method.invokeNative(Native Method) 01-12 04:55:05.339:E / AndroidRuntime(29253):at java.lang.reflect.Method.invoke(Method.java:507) 01-12 04:55:05.339:E / AndroidRuntime(29253):at com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java:874) 01-12 04:55:05.339:E / AndroidRuntime(29253):at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:632) 01-12 04:55:05.339:E / AndroidRuntime(29253):at dalvik.system.NativeStart.main(Native Method)

编辑:这就是我把观点放在

的方式
for (int r = 0; r < 10; r++) {
            for (int c = 0; c < 10; c++) {
                if ((r % 2) == (c % 2)) {
                    TileView tileView = new TileView(getContext(), c, r,
                            PickRandomByChance());
                    addView(tileView);
                }
                else {
                    OperationView operationView = new OperationView(getContext(), c, r);
                    addView(operationView);
                }
            }
        }

2 个答案:

答案 0 :(得分:1)

正如您的logcat所说:

java.lang.ArrayIndexOutOfBoundsException

您正在访问不在数组中的索引。

您确定已初始化阵列吗?并且尺寸合适。

oper = new char[4];
weight1 = new int[4];
weightSum = new int[4];

确保你的for循环是合乎逻辑的,因为它们不会导致从错误的索引读取。

答案 1 :(得分:1)

OperationView operationView = (OperationView) getChildAt(i);
// etc

如果ViewGroup的子节点可以是OperationView或TitleView,则可以使用instanceof来测试它是哪个类并重复相同的代码,但将子节点转换为适当的类型:

View view = getChildAt(i);
if(view instanceof OperationView) {
    OperationView operationView = (OperationView) view;
    // etc using operationView
}
else {
    TitleView titleView = (TitleView) view;
    // etc using titleView
}

但更强大的解决方案是声明一个具有方法getCol()getRow()的接口,然后让OperationView和TitleView实现此接口。现在您的代码如下:

MyInterface view = (MyInterface) getChildAt(i);
// etc using view

(但请使用比“MyInterface”更好的名称。)