I am creating views programmatically. every time i run the program, the debug is pointing me at
OperationView operationView = (OperationView) getChildAt(i);
here’s my code:
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;
}
}
What am I doing wrong? How should I go about it?
EDIT: this is the logcat
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);
}
}
}
If the ViewGroup’s children can either be an OperationView or TitleView, you can use
instanceofto test which class it is and repeat the same code but cast the child to the appropriate type:But a more robust solution is to declare an interface that has the methods
getCol()andgetRow()then have OperationView and TitleView implement this interface. Now your code looks like:(But please use a better name than “MyInterface”.)