Android:查看嵌入在布局中。触发了onDraw()方法,但屏幕没有立即更新

时间:2014-11-27 06:08:45

标签: android user-interface android-view invalidation

我是Android新手。我正在研究简单的数独求解器,我的观点有问题。 我的SolverView包含嵌入到包含2个按钮的布局中的自定义视图。 当我点击数独网格的单元格时,会出现一个键盘对话框,允许我选择该单元格的编号。但是,单击键盘上的数字后,虽然调用了onDraw()方法,但我的数独网格不会立即显示它。相反,它只会在我下次触摸屏时更新。 以下是代码

public class SolverView extends View{

private String TAG = "Solver View";
private int size;
private Solver solver; 
private static int selU, selV;

public SolverView(Context context) {
    super(context);
    this.solver = (Solver) context;
    setFocusable(true);
    setFocusableInTouchMode(true);
    setLayerType(View.LAYER_TYPE_SOFTWARE, null);
}

public SolverView(Context context, AttributeSet attrs) {
    super(context, attrs);
    this.solver = (Solver) context;
    setFocusable(true);
    setFocusableInTouchMode(true);
    setLayerType(View.LAYER_TYPE_SOFTWARE, null);
}
public SolverView(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
    this.solver = (Solver) context;
    setFocusable(true);
    setFocusableInTouchMode(true);
    setLayerType(View.LAYER_TYPE_SOFTWARE, null);
}   

public int getBoardSize() {
    int height = getHeight();
    int width = getWidth();
    return Math.min(height, width);
}

@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    size = getBoardSize();
    int cellSize = size / 9;

    Paint light = new Paint();
    light.setColor(getResources().getColor(R.color.puzzle_light));

    Paint dark = new Paint();
    dark.setColor(getResources().getColor(R.color.puzzle_dark));
    dark.setTypeface(Typeface.DEFAULT_BOLD);

    for (int i = 0; i <= 9; i++) {
        canvas.drawLine(i * cellSize, 0, i * cellSize, size, light);
        if (i % 3 == 0) 
            canvas.drawLine(i * cellSize, 0, i * cellSize, size, dark);
    }


    for (int i = 0; i <= 9; i++) {
        canvas.drawLine(0, i * cellSize, size, i * cellSize, light);
        if (i % 3 == 0)
            canvas.drawLine(0, i * cellSize, size, i * cellSize, dark);
    }
    Paint foreground = new Paint(Paint.ANTI_ALIAS_FLAG);
    foreground.setColor(getResources().getColor(R.color.puzzle_dark));
    foreground.setStyle(Style.FILL);
    foreground.setTextSize(cellSize * 0.75f);
    foreground.setTextAlign(Paint.Align.CENTER);
    FontMetrics fm = foreground.getFontMetrics();
    float x = cellSize / 2 - (fm.ascent + fm.descent) / 2;
    float y = cellSize / 2 ;
    for (int i = 0; i < 9; i++) {
        for (int j = 0; j < 9; j++) {
            canvas.drawText(this.solver.getCellString(i, j), j * cellSize + y, i * cellSize + x, foreground);
        }
    }

}

@Override
public boolean onTouchEvent(MotionEvent event) {
    if (event.getAction() != MotionEvent.ACTION_DOWN)
        return super.onTouchEvent(event);
    int cellSize = size / 9;
    int i = (int)event.getY() / cellSize;
    int j = (int)event.getX() / cellSize;
    if (i < 0 || i > 8 || j < 0 || j > 8) 
        return false;
    this.selU = i;
    this.selV = j;
    Log.d(TAG, "onTouchEvent: " + selU + " , " + selV);
    this.solver.showKeypad(i, j);
    invalidate();
    return true;
}

public void setCell(int t) {
    Log.d(TAG, "in setCell: t = " + t);
    Log.d(TAG, "in setCell: selU = " + selU);
    Log.d(TAG, "in setCell: selV = " + selV);
    if (solver.setCellIfValid(selU, selV, t)) {
        Log.d(TAG, "setCell: going to invalidate()");
        Log.d(TAG, "setCell: value change: " + solver.a[selU][selV]);
        invalidate();
    }

}

}

这是布局的结构:

<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:paddingBottom="@dimen/zero"
android:paddingLeft="@dimen/zero"
android:paddingRight="@dimen/zero"
android:paddingTop="@dimen/zero"
tools:context="com.trungkienioicamp.helloworld.Solver" >

<com.trungkienioicamp.helloworld.SolverView
    android:id="@+id/board"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:layout_alignParentLeft="true"
    android:layout_alignParentRight="true"
    android:layout_alignParentTop="true" />

<Button
    android:id="@+id/clear"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentBottom="true"
    android:layout_alignParentLeft="true"
    android:layout_marginBottom="74dp"
    android:layout_marginLeft="29dp"
    android:text="Clear" />

<Button
    android:id="@+id/solve"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignBaseline="@+id/clear"
    android:layout_alignBottom="@+id/clear"
    android:layout_alignParentRight="true"
    android:layout_marginRight="61dp"
    android:text="Solve" />

有人能建议我解决这个问题吗?感谢阅读

更新:当我将主要活动的内容视图设置为solverView实例

时,问题就消失了
setContentView(solverView);

但是当我将内容视图设置为布局

时,它将无效
setContentView(R.layout.activity_solver);

1 个答案:

答案 0 :(得分:1)

  

相反,它只会在下次触摸屏时更新

点击键盘上的数字后,尝试拨打invalidate SolverView个实例。