Android Activity and Dialog communication

Dialogs are used a lot in user-friendly mobile apps. You may want to display to user some message, or want to provide users some options. When we use dialog in android app, we often need to communicate between pop-up dialog and the underlying activity, we want to get users’ choice or want to react when user selects an option. If you are using an inner class dialog in the Activity, the communication is simple, because inner class (The dialog) can access members of main class(The activity). In this post, I am talking about communication between custom dialog and the activity, dialog defined in its own .java file.

I will give two methods for passing value back from dialog to activity.

###Use Handler and Message mechanism
Handler and Message is easy to use if there’s not much data to pass. The mechanism is easy, we pass a handler in the activity to the dialog, when we create the dialog, when user interact with the dialog, for example, if user clicks OK button, then we can use the handler to send a message, and process this message in the handleMessage function, which is defined in the activity class. Below is the code:

First is a custom dialog class:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
public class PauseDialog extends Dialog {
Button resumeBtn = null;
Button mainMenuBtn = null;
Handler mhandler;

public PauseDialog(Context context) {
super(context);
}

public PauseDialog(Context context, int theme) {
super(context, R.style.pause_game_dialog_style);
}

public void setHandler(Handler handler) {
this.mhandler = handler;
}

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.pause_game_dialog);
resumeBtn = (Button) findViewById(R.id.resume_button);
mainMenuBtn = (Button) findViewById(R.id.mainmenu_button);
resumeBtn.setOnClickListener(onClickListener);
mainMenuBtn.setOnClickListener(onClickListener);
}

View.OnClickListener onClickListener = new View.OnClickListener() {
@Override
public void onClick(View view) {
if (view.equals(resumeBtn)) {
//TODO: Resume game
Message msg = new Message();
msg.what = MainActivity.HANDLER_RESUME;
PauseDialog.this.mhandler.sendMessage(msg);
PauseDialog.this.dismiss();

} else if (view.equals(mainMenuBtn)) {
//TODO return to main menu
Message msg = new Message();
msg.what = MainActivity.HANDLER_MAINMENU;
PauseDialog.this.mhandler.sendMessage(msg);
PauseDialog.this.dismiss();
}
}
};
}

You can see there are two buttons in the dialog, and we add clickListener for buttons, and in the onClick method, we just send an message ,and then dismiss the dialog. Then handleMessage defined in the activity will process the click event. We can see the code below:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public android.os.Handler mHandler = new android.os.Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case HANDLER_MAINMENU:
System.out.println("Available Memory size:" + Memory.AvailableMemorySize(MainActivity.this));
Log.i("in Handler", "before remove mpView");
fLayout.removeView(MainActivity.this.mpView);
Log.i("in Handler", "after remove mpView");
MainActivity.this.addMainMenuView();
break;
case HANDLER_RESUME:
if (MainActivity.this.mpView != null)
MainActivity.this.mpView.resume();
break;
}
}
};

Of course in this case, we don’t pass much data from the dialog to the activity, just want activity to do something according to user’s choice. If you want to pass data, you can put data in the Message, you can refer to document how to do this.

###Use delegate (call back function)
When use call back function, we need to define a delegate for the dialog, we user interact with the dialog, we can use delegate to react.

For example, if we want user provide us a name and password, then we have one dialog which contains two textview Name and Password, and one button OK, when user click ok, we will pass name and password to the activity.

1
2
3
4
public interface DialogClickListener
{

public void onClick(String name, String passw);
}

This is the dialog click listener interface.

We need our activity to implement this interface and override onClickmethod.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public class MainActivity extends Activity implements DialogClickListener{

private string name = null;
private string passw = null;
void onCreate()
{

......
}

public void onClick(String name, String passw)//override method from DialogClickListener
{

this.name = name;
this.passw = passw;
......
}

//here is how we show dialog
public void showDialog()
{

NameAndPassDialog dialog = new NameAndPassDialog(this);
dialog.setListener(this);
dialog.show();
}

}

Our custom dialog class will look like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
public class NameAndPassDialog extends Dialog {
TextView nameText = null;
TextView passwText = null;
DialogClickLIstener mListener = null;

public PauseDialog(Context context) {
super(context);
}

public PauseDialog(Context context, int theme) {
super(context, R.style.pause_game_dialog_style);
}

public void setHandler(Handler handler) {
this.mhandler = handler;
}

public void setClickListener(DialogClickListener lis)
{

this.mListener = lis;//register delegate here
}

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
...
}

View.OnClickListener onClickListener = new View.OnClickListener() {
@Override
public void onClick(View view) {
if (view.equals(OkButton)) {
//TODO: Resume game
this.mListener.onClick(nameText.getText(), passwText.getText());//use delegate here
this.dismiss();
}
}
};
}

You can see in the handle event method of the OK button in the dialog, we call the delegate’s onClick method, and pass the data to it, so the Activity can get the data.

Wish this will help others, if there are any problems, feel free to leave comments :)