Reputation: 61
I am developing an app with a few functionalities and whenever there is some error happens in a functionality, an DialogFragment with two buttons will be shown:
And if an error happens and we have a ErrorManager class to show the error:
public class ErrorManager {
public static showError(int errorType, FragmentManager fragmentManager) {
switch(errorType) {
case 0:
new ErrorDialog().setTitle()
.setMessage()
.setPositveButton(()->{
// dosomething when the positive button is clicked
Toast.makeText(getActivity(),.....);
}.show(fragmentManager)
...
default:
break;
}
}
The ErrorManager can be called not only inside the FragmentActivity but anywhere where the FragmentManager
can be passed.
and the ErrorDialog is something like:
private ButtonFunction F;
public ErrorDialog extends DialogFragment {
public interface ButtonFunction {
void doSomething();
}
public ErrorDialog() {
}
public void setTitle(String title) {
// set the title in the bundle
}
public void setPositveButton(Function f) {
this.f = f
}
@Override
public View onCreateView(LayoutInflater inflater,
ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(getLayoutId(), container, false);
Button positiveButton = view.findViewById(R.id.postive);
positiveButton.setOnClickListener(v->{
if (f != null) {
f.doSomething()
}
dismiss();
});
}
}
By doing this, we can just show the error dialog from ErrorManager class and provide different implementation when the positive button is clicked. Until we turn on the Don't keep Activities from Develop option where the Activity/Fragment view have been destroyed so the "ButtonFunction" is lost.
I have tried the setretaininstance(true)
but it works for the orientation change.
I am not sure if set static ButtonFunction f
will work or cause any memory leak if the f implementation contains some ParentActivity reference.
Any suggestions? Thanks!
Upvotes: 2
Views: 1121
Reputation: 2004
Here is one way to implement it:
public class AlertDialogFragment extends DialogFragment {
Context context;
String title, msg, positiveBtnText, negativeBtnText;
DialogInterface.OnClickListener positiveClickListner, negativeClickListner, itemClickListner;
DialogInterface.OnKeyListener keyListener;
String[] items;
public static boolean mIsDisplayed = false;
AlertDialog alertDialog;
private TextView selectedText;
boolean isPrivacyPopUp = false;
Date final_firebase_date = null;
private boolean alertSizeFlag, alertDueDate;
private int viewAlert;
private Button postiveButton, negativeButton;
public AlertDialogFragment() {
}
public static AlertDialogFragment getInstance(Context context, String title, String msg, String positiveBtnText, DialogInterface.OnClickListener positiveClickListner, String negativeBtnText, DialogInterface.OnClickListener negativeClickListner, DialogInterface.OnKeyListener keyListener, Date final_firebase_date, boolean isPrivacyPopUP) {
AlertDialogFragment alertDialogFragment = new AlertDialogFragment();
alertDialogFragment.context = context;
alertDialogFragment.title = title;
alertDialogFragment.msg = msg;
alertDialogFragment.positiveBtnText = positiveBtnText;
alertDialogFragment.negativeBtnText = negativeBtnText;
alertDialogFragment.positiveClickListner = positiveClickListner;
alertDialogFragment.negativeClickListner = negativeClickListner;
alertDialogFragment.keyListener = keyListener;
alertDialogFragment.isPrivacyPopUp = isPrivacyPopUP;
alertDialogFragment.final_firebase_date = final_firebase_date;
return alertDialogFragment;
}
public static AlertDialogFragment getInstance(Context context, String title, String msg, String positiveBtnText, DialogInterface.OnClickListener positiveClickListner, String negativeBtnText, DialogInterface.OnClickListener negativeClickListner, DialogInterface.OnKeyListener keyListener) {
AlertDialogFragment alertDialogFragment = new AlertDialogFragment();
alertDialogFragment.context = context;
alertDialogFragment.title = title;
alertDialogFragment.msg = msg;
alertDialogFragment.positiveBtnText = positiveBtnText;
alertDialogFragment.negativeBtnText = negativeBtnText;
alertDialogFragment.positiveClickListner = positiveClickListner;
alertDialogFragment.negativeClickListner = negativeClickListner;
alertDialogFragment.keyListener = keyListener;
alertDialogFragment.isPrivacyPopUp = false;
return alertDialogFragment;
}
//Create custom Constructor with parameter
@Override
public void onStart() {
super.onStart();
if (isPrivacyPopUp) {
TextView textPrivacyMsg = ((TextView) alertDialog.findViewById(android.R.id.message));
if (textPrivacyMsg != null) {
textPrivacyMsg.setMovementMethod(LinkMovementMethod.getInstance());
textPrivacyMsg.setText(xxxxxxxx.addClickablePartForPrivacy1(context,
getResources().getString(R.string.privacy_popup_note),
R.string.privacy,
R.string.privacy_link, R.color.blue, final_firebase_date, alertDialog), TextView.BufferType.SPANNABLE);
}
}
if (alertSizeFlag == true) {
if (getDialog().getWindow() != null) {
if(LandingScreenPhoneActivity.isTablet(getActivity())){
getDialog().getWindow().setLayout(CommonBindingUtils.getRelativeWidthInPX(150), WindowManager.LayoutParams.WRAP_CONTENT);
PreferencesManager.getInstance().putBoolean(ALERT_FLAG, false);
}
else{
getDialog().getWindow().setLayout(CommonBindingUtils.getRelativeWidthInPX(280),WindowManager.LayoutParams.WRAP_CONTENT);
PreferencesManager.getInstance().putBoolean(ALERT_FLAG, false);
}
}
}
if (alertDueDate == true) {
if (getDialog().getWindow() != null ) {
if(LandingScreenPhoneActivity.isTablet(getActivity())){
getDialog().getWindow().setLayout(CommonBindingUtils.getRelativeWidthInPX(150), WindowManager.LayoutParams.WRAP_CONTENT);
// getDialog().getWindow().setLayout(CommonBindingUtils.getRelativeWidthInPX(150), CommonBindingUtils.getRelativeHeightInPX(150));
}
else{
getDialog().getWindow().setLayout(CommonBindingUtils.getRelativeWidthInPX(280),WindowManager.LayoutParams.WRAP_CONTENT);
}
}
}
//Crash fix #178
if (alertDialog!=null){
negativeButton = alertDialog.getButton(DialogInterface.BUTTON_NEGATIVE);
postiveButton = alertDialog.getButton(DialogInterface.BUTTON_POSITIVE);
}
if (postiveButton != null) {
postiveButton.setTextColor(getResources().getColor(R.color.new_colorPrimary));
}
if (negativeButton != null) {
negativeButton.setTextColor(getResources().getColor(R.color.new_colorPrimary));
}
// getDialog().getWindow().setLayout(200,200);
}
@NonNull
@Override
public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
int checkedItem = -1;
alertSizeFlag = PreferencesManager.getInstance().getBoolean(ALERT_FLAG);
alertDueDate = PreferencesManager.getInstance().getBoolean(DUE_DATE_ALERT);
if (items != null && selectedText != null) {
checkedItem = Arrays.asList(items).indexOf(selectedText.getText().toString());
}
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity(), R.style.customalertstyle)
// set dialog icon
// set Dialog Title
.setTitle(title)
// Set Dialog Message
.setItems(items, itemClickListner)
.setMessage(msg)
// positive button
.setCancelable(false)
.setPositiveButton(positiveBtnText, positiveClickListner)
.setOnKeyListener(keyListener)
.setNegativeButton(negativeBtnText, negativeClickListner);
if (viewAlert != 0 && alertDueDate == true) {
builder.setView(viewAlert);
}
if (selectedText != null) {
builder.setSingleChoiceItems(items, checkedItem, itemClickListner);
}
alertDialog = builder.create();
alertDialog.setCanceledOnTouchOutside(false);
if (isPrivacyPopUp) {
Window window = alertDialog.getWindow();
window.setGravity(Gravity.BOTTOM);
window.setLayout(WindowManager.LayoutParams.FILL_PARENT, WindowManager.LayoutParams.FILL_PARENT);
}
return alertDialog;
}
@Override
public void show(FragmentManager manager, String tag) {
//to catch the exception while app is in background and dialog
try {
super.show(manager, tag);
} catch (IllegalStateException e) {
e.printStackTrace();
}
}
@Override
public void dismiss() {
super.dismiss();
xxxxxxxx.resetBellyCount();
mIsDisplayed = false;
clearReferences();
}
@Override
public void onCancel(DialogInterface dialog) {
super.onCancel(dialog);
xxxxxxxx.resetBellyCount();
mIsDisplayed = false;
xxxxxxxx.resetBellyCount();
mIsDisplayed = false;
clearReferences();
}
@Override
public void onDestroy() {
super.onDestroy();
clearReferences();
}
private void clearReferences() {
context = null;
title = null;
msg = null;
positiveBtnText = null;
negativeBtnText = null;
positiveClickListner = negativeClickListner = itemClickListner = null;
keyListener = null;
items = null;
alertDialog = null;
selectedText = null;
final_firebase_date = null;
}
}
Upvotes: 0
Reputation: 550
Xml for custom dialog
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/genericDialog"
android:layout_width="280dp"
android:layout_height="180dp"
android:layout_gravity="center"
android:layout_margin="8dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<TextView
android:id="@+id/dialogMessage"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:gravity="center"
android:padding="10dp"
android:text="Your Custom Message"
android:textAlignment="center"
android:textAllCaps="false"
android:textSize="14sp"
app:layout_constraintBottom_toTopOf="@+id/negativeCLick"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.502"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="@+id/positiveClick"
android:layout_width="100dp"
android:layout_height="wrap_content"
android:layout_marginStart="24dp"
android:layout_marginBottom="16dp"
android:gravity="center"
android:padding="10dp"
android:text="Yes"
android:textAlignment="center"
android:textAllCaps="false"
android:textSize="14sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent" />
<Button
android:id="@+id/negativeCLick"
android:layout_width="100dp"
android:layout_height="wrap_content"
android:layout_marginEnd="24dp"
android:layout_marginBottom="16dp"
android:gravity="center"
android:padding="10dp"
android:text="No"
android:textAlignment="center"
android:textAllCaps="false"
android:textSize="14sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
Java code custom Dialog
// 3 Params: 1st- Activity, 2nd- Dialog Message, 3-New Activity of action you want to do.
public static void showDialogWithYesNo(Activity activity, String msg, Class gotoActivity) {
final Dialog dialog = new Dialog(activity, android.R.style.Theme_Dialog);
int layout_parms;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
layout_parms = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
} else {
layout_parms = WindowManager.LayoutParams.TYPE_PHONE;
}
new WindowManager.LayoutParams(
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.WRAP_CONTENT,
layout_parms,
WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
PixelFormat.TRANSPARENT);
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
dialog.setCancelable(false);
dialog.setContentView(R.layout.generic_dialog);
dialog.getWindow().setBackgroundDrawable(new ColorDrawable(activity.getResources().getColor(R.color.colorPrimary)));
dialog.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);
TextView text = (TextView) dialog.findViewById(R.id.dialogMessage);
text.setText(msg);
TextView dialogBtn_cancel = (TextView) dialog.findViewById(R.id.negativeCLick);
dialogBtn_cancel.setText("No");
dialogBtn_cancel.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
dialog.cancel();
}
});
TextView dialogBtn_okay = (TextView) dialog.findViewById(R.id.positiveClick);
dialogBtn_okay.setText("Yes");
dialogBtn_okay.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// Add actions as per your need here for positive response
Intent intent = new Intent(activity, gotoActivity);
activity.startActivity(intent);
dialog.cancel();
}
});
dialog.show();
}
How to use the above dialog
//1: Activity.this will your Activity Name.this
//2: Your Message you want to display in your dialog
//3: The Activity you want to open when a user press yes. eg: NewAcitivity.class
showDialogWithYesNo(Activity.this, "Do you want to exit ?", Activity.class);
Upvotes: 1