यहां सभी प्रकार के संवादों के लिए कुछ समाधान दिए गए हैं जिनमें AlertDialog.Builder का समाधान भी शामिल है जो सभी एपीआई स्तरों (एपीआई 8 के नीचे काम करता है, जो अन्य उत्तर यहां नहीं है) पर काम करेगा। AlertDialog.Builder, DialogFragment और DialogPference का उपयोग करके AlertDialogs के लिए समाधान मौजूद हैं।
नीचे दिए गए कोड उदाहरण दिखा रहे हैं कि कैसे डिफॉल्ट कॉमन बटन हैंडलर को ओवरराइड किया जाए और डायलॉग के इन विभिन्न रूपों के लिए संवाद को बंद करने से रोका जाए। सभी उदाहरण बताते हैं कि सकारात्मक बटन को संवाद को बंद करने से कैसे रोका जाए।
नोट: आधार एंड्रॉइड कक्षाओं के लिए हुड के तहत संवाद समापन कैसे काम करता है और निम्न दृष्टिकोण क्यों चुना जाता है, इसका विवरण उदाहरण के बाद, उन लोगों के लिए है जो अधिक विवरण चाहते हैं
AlertDialog.Builder - शो के तुरंत बाद डिफ़ॉल्ट बटन हैंडलर बदलें ()
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setMessage("Test for preventing dialog close");
builder.setPositiveButton("Test",
new DialogInterface.OnClickListener()
{
@Override
public void onClick(DialogInterface dialog, int which)
{
//Do nothing here because we override this button later to change the close behaviour.
//However, we still need this because on older versions of Android unless we
//pass a handler the button doesn't get instantiated
}
});
final AlertDialog dialog = builder.create();
dialog.show();
//Overriding the handler immediately after show is probably a better approach than OnShowListener as described below
dialog.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v)
{
Boolean wantToCloseDialog = false;
//Do stuff, possibly set wantToCloseDialog to true then...
if(wantToCloseDialog)
dialog.dismiss();
//else dialog stays open. Make sure you have an obvious way to close the dialog especially if you set cancellable to false.
}
});
DialogFragment - ओवरराइड onResume ()
@Override
public Dialog onCreateDialog(Bundle savedInstanceState)
{
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setMessage("Test for preventing dialog close");
builder.setPositiveButton("Test",
new DialogInterface.OnClickListener()
{
@Override
public void onClick(DialogInterface dialog, int which)
{
//Do nothing here because we override this button later to change the close behaviour.
//However, we still need this because on older versions of Android unless we
//pass a handler the button doesn't get instantiated
}
});
return builder.create();
}
//onStart() is where dialog.show() is actually called on
//the underlying dialog, so we have to do it there or
//later in the lifecycle.
//Doing it in onResume() makes sure that even if there is a config change
//environment that skips onStart then the dialog will still be functioning
//properly after a rotation.
@Override
public void onResume()
{
super.onResume();
final AlertDialog d = (AlertDialog)getDialog();
if(d != null)
{
Button positiveButton = (Button) d.getButton(Dialog.BUTTON_POSITIVE);
positiveButton.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v)
{
Boolean wantToCloseDialog = false;
//Do stuff, possibly set wantToCloseDialog to true then...
if(wantToCloseDialog)
d.dismiss();
//else dialog stays open. Make sure you have an obvious way to close the dialog especially if you set cancellable to false.
}
});
}
}
DialogPreference - ओवरराइड शोडायॉगॉग ()
@Override
protected void onPrepareDialogBuilder(Builder builder)
{
super.onPrepareDialogBuilder(builder);
builder.setPositiveButton("Test", this); //Set the button here so it gets created
}
@Override
protected void showDialog(Bundle state)
{
super.showDialog(state); //Call show on default first so we can override the handlers
final AlertDialog d = (AlertDialog) getDialog();
d.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v)
{
Boolean wantToCloseDialog = false;
//Do stuff, possibly set wantToCloseDialog to true then...
if(wantToCloseDialog)
d.dismiss();
//else dialog stays open. Make sure you have an obvious way to close the dialog especially if you set cancellable to false.
}
});
}
दृष्टिकोण की व्याख्या:
एंड्रॉइड सोर्स कोड के माध्यम से देखते हुए ऑन्टरडायलॉग डिफॉल्ट इम्प्लीमेंटेशन ऑनक्रिएट () में सभी वास्तविक बटन के लिए एक कॉमन बटन हैंडलर रजिस्टर करके काम करता है। जब एक बटन को सामान्य बटन हैंडलर पर क्लिक किया जाता है, तो आप जिस भी हैंडलर को सेटबटन () में पास करते हैं उस पर क्लिक करें।
यदि आप इनमें से किसी एक बटन को दबाने पर डायलॉग बॉक्स को बंद होने से रोकना चाहते हैं तो आपको बटन के वास्तविक दृश्य के लिए सामान्य बटन हैंडलर को बदलना होगा। क्योंकि यह OnCreate () में असाइन किया गया है, आपको डिफ़ॉल्ट OnCreate () कार्यान्वयन कहा जाता है के बाद इसे प्रतिस्थापित करना होगा। OnCreate को शो () विधि की प्रक्रिया में कहा जाता है। आप एक कस्टम डायलॉग क्लास बना सकते हैं और ऑनक्रिएट () को ओवरऑल कर सकते हैं। सुपर क्रिएट () को कॉल करने के लिए फिर बटन हैंडलर्स को ओवरराइड करें, लेकिन यदि आप कस्टम डायलॉग बनाते हैं तो आपको बिल्डर फ्री में नहीं मिलता है, जिस स्थिति में बिंदु क्या है ?
इसलिए, एक डायलॉग का उपयोग करने के तरीके से इसे डिज़ाइन किया गया है लेकिन जब इसे खारिज किया जाता है तो इसे नियंत्रित करने के लिए, एक दृष्टिकोण डायलॉग को कॉल करना होता है। किसी तरह (पहले), फिर क्लिक हैंडलर को ओवरराइड करने के लिए Dial.getButton () का उपयोग करके बटन का संदर्भ प्राप्त करें। एक अन्य दृष्टिकोण सेटऑनशोलिस्टनर () का उपयोग करना है और बटन दृश्य को ढूंढना और ऑनस्लोविस्टनर में हैंडलर को बदलना है। दोनों के बीच कार्यात्मक अंतर 'लगभग' शून्य है, जो इस बात पर निर्भर करता है कि मूल रूप से संवाद उदाहरण क्या है। स्रोत कोड के माध्यम से देखते हुए, onShowListener उस डायलॉग को बनाने वाले थ्रेड पर चलने वाले हैंडलर को पोस्ट किए गए संदेश द्वारा कॉल करता है। इसलिए, जब से आपके OnShowListener को संदेश कतार पर पोस्ट किए गए संदेश द्वारा कॉल किया जाता है, यह तकनीकी रूप से संभव है कि शो पूरा होने के कुछ समय बाद आपके श्रोता को कॉल करने में देरी हो।
इसलिए, मेरा मानना है कि सबसे सुरक्षित तरीका पहला है: शो को कॉल करना। डायलॉग (), फिर तुरंत एक ही निष्पादन पथ में बटन के बटन को बदल दें। चूँकि आपका कोड जो शो दिखाता है () मुख्य GUI थ्रेड पर काम कर रहा है, इसका मतलब है कि आप जो भी कोड शो () का उपयोग करेंगे, उस थ्रेड पर किसी भी अन्य कोड से पहले निष्पादित किया जाएगा, जबकि OnShowListener विधि का समय दया पर है संदेश कतार।