Search code examples
androiddialogviewgroup

Dismissing a dialog from its non-xml content view


I have a custom dialog (extends Dialog) whose contentview is a custom viewgroup. The viewgroup has a few edittext children, but I am handling the drawing and clicking of buttons myself in the viewgroup's dispatchDraw and onTouch methods (I'm trying to avoid inflating as many views as possible). Specifically: this view has no button children that I could set to be the dismiss button for the dialog. I want to dismiss the dialog from within the onTouch method of the viewgroup, but beyond simulating a press of the back key, I cannot figure out how to do this.

activity code:

public class My_Activity extends Activity {
    ...
    public void onCreate(Bundle savedInstanceState) {
        ...
        //if there's no Class_That_Im_Editing in the database, prompt the user to make a new one by adding information to the editviews in this custom dialog and clicking the area where I draw the ok button
        my_dialog = new Custom_Dialog(this, R.style.CustomDlg, new Class_That_Im_Editing());
    }
}

dialog code:

public class Custom_Dialog extends Dialog {
    ...
        public void onCreate(Bundle savedInstanceState) {
            ...
            setContentView(new Custom_ViewGroup(context, Class_That_Im_Editing));
        }
}

viewgroup code:

public class Custom_ViewGroup extends ViewGroup implements OnTouchListener {
    //this class has some edittext children but _no_ buttons
    ...
    public boolean onTouch(View view, MotionEvent event) {
        if ( logic checking if the user has clicked the button area ) {
            //??? what do I put here to dismiss the dialog
        }
    }
}

The only other approach I can think of is using the dismissDialog(int) method, which means overriding the onCreateDialog and onPrepareDialog event handlers. But how can I call dismissDialog from within a view's onTouch method?

Maybe I need to set up a listener of some kind? If so, what would be the skeleton code to do this?


Solution

  • So the problem was telling a dialog to dismiss() when I wasn't in the scope where the dialog existed. Here's my solution:

    Create the OnTouchListener in the same scope as the dialog - in this case, inside my main activity. Then pass it when you initialize the dialog, which in turn needs to pass it to the viewgroup.

    It will look something like this:

    activity code:

    public class My_Activity extends Activity {
        public Custom_Dialog my_dialog;
        ...
        public void onCreate(Bundle savedInstanceState) {
            OnTouchListener otl_custom_dialog = new OnTouchListener() {
                public boolean onTouch(View view, MotionEvent event) {
                    if ( logic checking if the user has clicked the button area ) {
                        //notice I can still access any _public_ variable within the viewgroup class
                        //by using my_dialog.my_custom_viewgroup.public_variable
                        ...
                        //I can now call dismiss() from within this scope
                        my_dialog.dismiss();
                    }
                    ...
                }
            }
            ...
            //if there's no Class_That_Im_Editing in the database, prompt the user to make a new one by adding information to the editviews in this custom dialog and clicking the area where I draw the ok button
            my_dialog = new Custom_Dialog(this, R.style.CustomDlg, new Class_That_Im_Editing(), otl_custom_dialog);
            my_dialog.show();
        }
    }
    

    dialog code:

    public class Custom_Dialog extends Dialog {
        Custom_ViewGroup my_custom_viewgroup;
        OnTouchListener otl_custom_dialog;
        ...
            public void onCreate(Bundle savedInstanceState) {
                ...
                setContentView(new Custom_ViewGroup(context, class_that_im_editing, otl_custom_dialog));
            }
    }
    

    viewgroup code:

    public class Custom_ViewGroup extends ViewGroup implements OnTouchListener {
        public Custom_ViewGroup(Context context, Class_That_Im_Editing class_that_im_editing, OnTouchListener otl_custom_dialog) {
            ...
            this.setOnTouchListener(otl_custom_dialog);
        }
    }
    

    I have tested this method and it works fine. Hope this helps someone else out there!