-1

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

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;
    }           
}   

我究竟做错了什么?我应该怎么做?

编辑:这是日志猫

01-12 04:55:05.339: E/AndroidRuntime(29253): FATAL EXCEPTION: main 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): at android.view.View.layout(View.java:7175) 01-12 04:55:05.339: E/AndroidRuntime(29253): at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1254) 01-12 04:55:05.339: E/AndroidRuntime(29253): at android.widget.LinearLayout.layoutHorizontal(LinearLayout.java:1243) 01-12 04:55:05.339: E/AndroidRuntime(29253): at android.widget.LinearLayout.onLayout(LinearLayout.java:1049) 01-12 04:55:05.339: E/AndroidRuntime(29253): at android.view.View.layout(View.java:7175) 01-12 04:55:05.339: E/AndroidRuntime(29253): at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1254) 01-12 04:55:05.339: E/AndroidRuntime(29253): at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1130) 01-12 04:55:05.339: E/AndroidRuntime(29253): at android.widget.LinearLayout.onLayout(LinearLayout.java:1047) 01-12 04:55:05.339: E/AndroidRuntime(29253): at android.view.View.layout(View.java:7175) 01-12 04:55:05.339: E/AndroidRuntime(29253): at android.widget.FrameLayout.onLayout(FrameLayout.java:338) 01-12 04:55:05.339: E/AndroidRuntime(29253): at android.view.View.layout(View.java:7175) 01-12 04:55:05.339: E/AndroidRuntime(29253): at android.widget.FrameLayout.onLayout(FrameLayout.java:338) 01-12 04:55:05.339: E/AndroidRuntime(29253): at android.view.View.layout(View.java:7175) 01-12 04:55:05.339: E/AndroidRuntime(29253): at android.view.ViewRoot.performTraversals(ViewRoot.java:1142) 01-12 04:55:05.339: E/AndroidRuntime(29253): at android.view.ViewRoot.handleMessage(ViewRoot.java:1861) 01-12 04:55:05.339: E/AndroidRuntime(29253): at android.os.Handler.dispatchMessage(Handler.java:99) 01-12 04:55:05.339: E/AndroidRuntime(29253): at android.os.Looper.loop(Looper.java:123) 01-12 04:55:05.339: E/AndroidRuntime(29253): at 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)

EDIT: this is how i put the views

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);
                }
            }
        }
4

2 回答 2

1

as your logcat says:

java.lang.ArrayIndexOutOfBoundsException

You are accessing a index that is not in the array.

Are you sure you have initialised your arrays. and to the right size.

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

Make sure your for loops are logical, in that they dont cause a read from the wrong index.

于 2013-01-11T20:53:39.240 回答
1
OperationView operationView = (OperationView) getChildAt(i);
// etc

If the ViewGroup's children can either be an OperationView or TitleView, you can use instanceof to test which class it is and repeat the same code but cast the child to the appropriate type:

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

But a more robust solution is to declare an interface that has the methods getCol() and getRow() then have OperationView and TitleView implement this interface. Now your code looks like:

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

(But please use a better name than "MyInterface".)

于 2013-01-11T21:20:56.087 回答