How to invalidate() on return from a dialog?

折月煮酒 提交于 2019-12-13 03:39:44

问题


I have a drawing canvas with an OnTouchListener from which I call an AlertDialog.

In the dialog I reset the underlying data for the canvas (or not depending on user). On returning to the canvas with dialog.cancel() the canvas does not redraw and I want it to.
This means the user has to click on the canvas to cause it to redraw - not good!

Because the dialog runs asynchronously any call to invalidate() in the canvas is completed before the dialog returns the changed underlying data. Any attempt I make to invalidate or reference the canvas from inside the dialog buttons code results in errors. I seem to be in catch 22!

Can enyone give me advice?

dialog code:

case DIALOG_NEW_ID:
    AlertDialog.Builder builder5 = new AlertDialog.Builder(this);
    builder5.setMessage("     WARNING" +
            "\nYour current game will be lost")
    .setCancelable(false)
    .setPositiveButton("Cancel", new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface dialog, int id) {                   
            dialog.cancel();
        }
    })              
    .setNegativeButton("Continue", new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface dialog, int id) {
            cells.reset();
            gameMode = 0;
            dialog.cancel();
        }
    });
    AlertDialog alert5 = builder5.create();             
    alert5.setOnDismissListener(new DialogInterface.OnDismissListener() { 
        public void onDismiss( DialogInterface dialog) { 
            Log.d(TAG, "Dialog cancelled");// debug log entry 
            //myBoard.invalidate();
        }
    });     
    dialog = alert5;                
    break;

Dialog calling code onTouch in the canvas:

    case MODE_SOLUTION:
        break;
    default:                            
        showDialog(DIALOG_NEW_ID);
        invalidate();
}// end switch  

The Main Class set up:

public class SudokuGame extends Activity {
static final int DIALOG_OPEN_ID = 0;
static final int DIALOG_INFO_ID = 1;
static final int DIALOG_FAIL_ID = 2;
static final int DIALOG_SAVE_ID = 3;
static final int DIALOG_NEW_ID = 4;
static final int MODE_ENTRY = 0;
static final int MODE_PLAY = 1;
static final int MODE_SHOW_ERRORS = 3;
static final int MODE_SOLUTION = 4;
final String TAG = "Game";
int  gameMode;
SKU cells;
View myBoard;


@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    requestWindowFeature(Window.FEATURE_LEFT_ICON);
    View myBoard = new NewBoard(this);        
    setContentView(myBoard);
    setFeatureDrawableResource(Window.FEATURE_LEFT_ICON, R.drawable.ic_launcher);
    showDialog(DIALOG_OPEN_ID);        
}// end onCreate

    protected Dialog onCreateDialog(int id) {

The Class NewBoard which is nested in the main class:

    class NewBoard extends View implements OnTouchListener{
    int cW;  // canvas width
    int cH;  // canvas height
    int cellSize,textSize;
    int boardX,boardY;  
    int runner, tX, tY,pX,pY,selectorX,selectorY;
    int gap ;
    int btn1X,btn1Y, selected;
    int infoButtonX, infoButtonY,quitButtonX,quitButtonY;
    boolean btn1Pressed, btn2Pressed,  btn3Pressed, btn4Pressed, btn5Pressed;
    String btn1,btn2,btn3,btn4,btn5;

    public NewBoard(Context context){ // NewBoard Constructor
        super(context);
        this.setOnTouchListener(this);  
        cells = new SKU();
        readStateStore();
    }// end NewBoard Constructor

    @Override 
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        Paint paint = new Paint();  
        Rect textRect = new Rect();     

回答1:


Two possibilities:

  • make the dialog non-cancelable
  • set an OnCancelListener for the dialog that will then call invalidate().



回答2:


Could you post some code of your situation with the dialog box and invalidate(), and the error message being returned back?

I don't see why you couldn't do the following (dialog box that invalidates a mapView):

    AlertDialog.Builder builderAccountInfo = new AlertDialog.Builder(this);
        builderAccountInfo.setMessage("TEST")
        .setCancelable(false)
        .setTitle("TEST")
        .setPositiveButton("Ok", new DialogInterface.OnClickListener() {
       public void onClick(DialogInterface dialog, int id) {
            changeUserCanvas();
            mapView.invalidate();
            dialog.cancel();
       }
   });
        AlertDialog alertAccountInfo = builderAccountInfo.create();

        alertAccountInfo.show();

The error would probably come from the context you're using to invalidate, but more information on the changes to the canvas you're making and your dialog box code is needed.

////////////////////////////////Edit

it looks like there is a problem between the local and global variable of View myBoard.

public class SudokuGame extends Activity {
static final int DIALOG_OPEN_ID = 0;
static final int DIALOG_INFO_ID = 1;
static final int DIALOG_FAIL_ID = 2;
static final int DIALOG_SAVE_ID = 3;
static final int DIALOG_NEW_ID = 4;
static final int MODE_ENTRY = 0;
static final int MODE_PLAY = 1;
static final int MODE_SHOW_ERRORS = 3;
static final int MODE_SOLUTION = 4;
final String TAG = "Game";
int  gameMode;
SKU cells;
View myBoard;


@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    requestWindowFeature(Window.FEATURE_LEFT_ICON);
    View myBoard = new NewBoard(this);        
    setContentView(myBoard);
    setFeatureDrawableResource(Window.FEATURE_LEFT_ICON, R.drawable.ic_launcher);
    showDialog(DIALOG_OPEN_ID);        
}// end onCreate

View myBoard in onCreate is initialized locally, but the global View myBoard has not been initialized because of the local scope. You have two myBoard variables and only one is initialized. To fix this quickly, I would change:

View myBoard = new NewBoard(this);

to

myBoard = new NewBoard(this); 


来源:https://stackoverflow.com/questions/4888481/how-to-invalidate-on-return-from-a-dialog

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!