Reputation: 6389
I have my Custom dialog builder in my app that will trigger from many events like: Asynctasks, web service messages, UI input error or from services that don't have activity context. I always used to create a Activity called currentActivity
in my Application class. then on resume of every activities their sit on currentActivity
.
@Override
protected void onResume() {
super.onResume();
MyApplication.currentActivity = MainActivity.this;
then in case of create dialogs I used that context. but I had one problem. for example I opened RegisterActivity and then currentActivity
changed to it. then when app goto background or some case that some other activity opened, my app will crash on creating dialog with that Context. so handling witch Activity is currentActivity
is a headache. I googled and find that some guys embed the CustomDialog in an non-layout activty and then open that activity. but it seems to not good solution.
UPDATED
for example I have a SMSManager class that handle my all sending sms. I wanna open dialog to user chose some custom options before sending sms.
so what is the best practice of Global Dialog in my whole application?
Upvotes: 3
Views: 4916
Reputation: 7257
First of all - it is a very bad practice to save references to activities (or Context
in general). Android always provides you a reference to a Context
object you can use for creating your dialog. In an Activity
it is the object itself (this
), in a Fragment
you can access the Context
by getActivity()
or getContext()
, in a View
- getContext()
.
If you need to display a dialog from your custom class and don't have the reference to the Context
make sure, that you provide the Context
reference to your class by using the methods described above.
Don't try displaying any dialogs from a Service
- make sure your app is in foreground and visible, before showing any dialogs. You can use an event bus (or LocalBroadcastManager) for sending the state (error, message or whatever) to your currently visible Activity
or Fragment
. The "current visible Activity or fragment" in this case is just the Activity
or Fragment
which is listening for such kind of events. Start listening in onStart()
and stop listening in onStop()
methods of your Activity
or Fragment
. If you don't want to rely on any running Activities for displaying a dialog and don't want to wait for the next time the user starts your app, I would suggest using notifications instead of dialogs.
Given a Context
you can create your custom dialog whereever you want by using a helper dialog builder class like this:
public class DialogBuilder {
private String title;
private String message;
private String primaryButtonTitle;
private String secondaryButtonTitle;
private Dialog.OnClickListener primaryButtonListener;
private Dialog.OnClickListener secondaryButtonListener;
private Activity context;
private boolean showIcon;
private boolean cancellable;
public DialogBuilder(Activity context) {
this.context = context;
}
public DialogBuilder setTitle(@StringRes int title) {
this.title = context.getString(title);
return this;
}
public DialogBuilder setTitle(String title) {
this.title = title;
return this;
}
public DialogBuilder setMessage(@StringRes int message) {
this.message = context.getString(message);
return this;
}
public DialogBuilder setMessage(String message) {
this.message = message;
return this;
}
public DialogBuilder setShowIcon() {
showIcon = true;
return this;
}
public DialogBuilder setPrimaryButton(@StringRes int title, Dialog.OnClickListener listener) {
primaryButtonTitle = context.getString(title);
primaryButtonListener = listener;
return this;
}
public DialogBuilder setSecondaryButton(@StringRes int title, Dialog.OnClickListener listener) {
secondaryButtonTitle = context.getString(title);
secondaryButtonListener = listener;
return this;
}
public DialogBuilder setCancellable(boolean cancellable) {
this.cancellable = cancellable;
return this;
}
public AlertDialog create() {
AlertDialog.Builder builder = new AlertDialog.Builder(context);
View dialogView = LayoutInflater.from(context).inflate(R.layout.my_custom_dialog, null);
builder.setView(dialogView);
// get your custom views here and configure them based on given settings (field values of this class)
final AlertDialog dialog = builder.create();
return dialog;
}
}
example usage (in a Fragment
):
new DialogBuilder(getActivity())
.setTitle(R.string.title)
.setMessage(R.string.message)
.setPrimaryButton(R.string.ok, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
// do something
dialog.dismiss();
}
})
.setSecondaryButton(R.string.settings_cancel, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
// do something
dialog.dismiss();
}
}).create().show();
Upvotes: 5
Reputation: 816
Create a custom dialog class like this :
public class DialogBoardOut extends Dialog {
private TextView txtBoardOut;
private RelativeLayout rel_close_boardout;
public DialogBoardOut(Context mContext) {
super(mContext);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.dialog_boardout);
} }
call like :
DialogBoardOut dialogQrCode = new DialogBoardOut(HomeBaseActivity.this);
dialogQrCode.requestWindowFeature(Window.FEATURE_NO_TITLE);
// dialogQrCode.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
dialogQrCode.show();
dialogQrCode.getWindow().setLayout(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.WRAP_CONTENT);
Upvotes: -1