2011-04-14 15 views
32

मेरे पास एक सिंगल-पसंद सूची और दो बटन के साथ एक चेतावनी संवाद है: OK बटन और cancel बटन। नीचे दिया गया कोड दिखाता है कि मैंने इसे कैसे कार्यान्वित किया।एकल विकल्प चेकबॉक्स एंड्रॉइड के साथ AlertDialog में एक प्रविष्टि का चयन कैसे करें?

private final Dialog createListFile(final String[] fileList) { 
    AlertDialog.Builder builder = new AlertDialog.Builder(this); 
    builder.setTitle("Compare with:"); 

    builder.setSingleChoiceItems(fileList, -1, new DialogInterface.OnClickListener() { 
    public void onClick(DialogInterface dialog, int whichButton) { 
     Log.d(TAG,"The wrong button was tapped: " + fileList[whichButton]); 
    } 
    }); 

    builder.setPositiveButton("OK", new DialogInterface.OnClickListener() { 
    public void onClick(DialogInterface dialog, int whichButton) {} 
    }); 

    builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() { 
    public void onClick(DialogInterface dialog, int whichButton) {} 
    }); 

    return builder.create(); 
} 

मेरा लक्ष्य चयनित रेडियो बटन का नाम प्राप्त करने के लिए जब OK बटन उपयोग किया जाता है। मैंने एक चर में स्ट्रिंग को सहेजने की कोशिश की, लेकिन एक आंतरिक कक्षा के अंदर केवल अंतिम चर का उपयोग करना संभव है। चयनित रेडियो बटन को स्टोर करने के लिए अंतिम चर का उपयोग करने से बचने का कोई तरीका है?

उत्तर

119

का उपयोग करते हुए एक अंतिम चर स्पष्ट रूप से काम नहीं करेगा (क्योंकि यह केवल घोषणा समय में एक बार सौंपा जा सकता है,)। तथाकथित "वैश्विक" चर आमतौर पर एक कोड गंध होते हैं (विशेष रूप से जब वे एक गतिविधि वर्ग का हिस्सा बन जाते हैं, जो आम तौर पर अलर्टडियलोग बनते हैं)। क्लीनर समाधान डायलॉग इंटरफेस ऑब्जेक्ट को AlertDialog पर डालना है और फिर getListView() को कॉल करना है। GetcheckedItemPosition() प्राप्त करें। इस तरह:

new AlertDialog.Builder(this) 
     .setSingleChoiceItems(items, 0, null) 
     .setPositiveButton(R.string.ok_button_label, new DialogInterface.OnClickListener() { 
      public void onClick(DialogInterface dialog, int whichButton) { 
       dialog.dismiss(); 
       int selectedPosition = ((AlertDialog)dialog).getListView().getCheckedItemPosition(); 
       // Do something useful withe the position of the selected radio button 
      } 
     }) 
     .show(); 
+1

कम से कम सबसे उपयोगी और googleable एक;) – Snicolas

+1

क्या होगा यदि मैं याद रखना चाहता था कि क्या चुना गया था और अगली बार संवाद खोला गया था तो पसंद पहले से चुना गया है? – Si8

+0

@ SiKni8 आप चयनित स्थिति (शायद गतिविधि के एक उदाहरण चर के रूप में) को स्टोर कर सकते हैं और फिर getListView() को कॉल कर सकते हैं। अगली बार संवाद खोला जाता है। –

8
final CharSequence[] choice = {"Choose from Gallery","Capture a photo"}; 

int from; //This must be declared as global ! 

AlertDialog.Builder alert = new AlertDialog.Builder(activity); 
alert.setTitle("Upload Photo"); 
alert.setSingleChoiceItems(choice, -1, new DialogInterface.OnClickListener() { 
    @Override 
    public void onClick(DialogInterface dialog, int which) { 
     if (choice[which] == "Choose from Gallery") { 
      from = 1; 
     } else if (choice[which] == "Capture a photo") { 
      from = 2; 
     } 
    } 
}); 
alert.setPositiveButton("OK", new DialogInterface.OnClickListener() { 
    @Override 
    public void onClick(DialogInterface dialog, int which) { 
     if (from == 0) { 
      Toast.makeText(activity, "Select One Choice", 
         Toast.LENGTH_SHORT).show(); 
     } else if (from == 1) { 
      // Your Code 
     } else if (from == 2) { 
      // Your Code 
     } 
    } 
}); 
alert.show(); 
+2

चर से अंतिम नहीं है, तो आप इसे आंतरिक कक्षा में उपयोग नहीं कर सकते हैं। – LuckyStarr

+0

बस अंतिम या स्थानीय (वैश्विक) को परिभाषित करें .. –

14

यह ठीक है, लेकिन मुझे यह जवाब Google से मिल रहा है और मैं एक गैर-अज्ञात वर्ग समाधान साझा करना चाहता था। मैं खुद को पुन: प्रयोज्य वर्ग पसंद करता हूं और दूसरों के लिए सहायक हो सकता हूं।

इस उदाहरण में, मैं DialogFragment कार्यान्वयन का उपयोग कर रहा हूं और कॉलबैक विधि के माध्यम से एक मान पुनर्प्राप्त कर रहा हूं।

कॉलबैक एक संवाद से मूल्यों को प्राप्त करने के लिए विधि

public interface OnDialogSelectorListener { 
    public void onSelectedOption(int selectedIndex); 
} 

इसके अलावा DialogFragment औजार DialogInterface.OnClickListener आप वर्ग आप को क्रियान्वित किया है रजिस्टर कर सकते हैं जिसका मतलब है कि एक सार्वजनिक इंटरफेस बनाने के द्वारा किया जा सकता है ऑनक्लिक लिस्टनरDialogFragment के लिए बनाया जा रहा है।

उदाहरण

public Dialog onCreateDialog(Bundle savedInstanceState) { 
    final AlertDialog.Builder builder = new AlertDialog.Builder(this.getActivity()); 

    builder.setTitle(R.string.select); 
    builder.setSingleChoiceItems(mResourceArray, mSelectedIndex, this); 
    builder.setPositiveButton(R.string.ok, this); 
    builder.setNegativeButton(R.string.cancel, this); 
    return builder.create(); 
} 

लाइन

builder.setSingleChoiceItems(mResourceArray, mSelectedIndex, this);

के लिए एक संसाधन सरणीmResourceArray में संग्रहीत से विकल्पों के साथ एक विकल्प संवाद बनाता है। यह mSelectedIndex में संग्रहीत एक विकल्प इंडेक्स को भी पूर्व निर्धारित करता है और अंततः यह this को ऑनक्लिक लिस्टनर के रूप में सेट करता है। (अंत में पूरा कोड देखें तो निम्न अनुच्छेद एक बालक भ्रामक है)

अब, OnClick विधि है जहां मूल्य है कि संवाद

@Override 
public void onClick(DialogInterface dialog, int which) { 

    switch (which) { 
     case Dialog.BUTTON_NEGATIVE: // Cancel button selected, do nothing 
      dialog.cancel(); 
      break; 

     case Dialog.BUTTON_POSITIVE: // OK button selected, send the data back 
      dialog.dismiss(); 
      // message selected value to registered callbacks with the 
        // selected value. 
      mDialogSelectorCallback.onSelectedOption(mSelectedIndex); 
      break; 

     default: // choice item selected 
        // store the new selected value in the static variable 
      mSelectedIndex = which; 
      break; 
    } 
} 

से आता है हड़पने यहाँ क्या होता है जब एक है आइटम चुना जाता है, यह एक चर में संग्रहीत है। यदि उपयोगकर्ता बटन को रद्द करता है, तो कोई अपडेट वापस नहीं भेजा जाता है और कुछ भी नहीं बदलता है।यदि उपयोगकर्ता ओके बटन पर क्लिक करता है, तो यह मान Activity पर देता है जो इसे कॉलबैक के माध्यम से बनाया गया है।

उदाहरण के तौर पर, आप FragmentActivity से संवाद कैसे बनाएंगे।

final SelectorDialog sd = SelectorDialog.newInstance(R.array.selector_array, preSelectedValue); 
sd.show(getSupportFragmentManager(), TAG); 

यहाँ, संसाधन सरणी _R.array.selector_array_ संवाद और preSelectedValue में दिखाने के लिए तार की एक सरणी सूचकांक खुला पर चयन करने के लिए किया जाता है।

अंत में, आपके FragmentActivityOnDialogSelectorListener लागू करेंगे और कॉलबैक संदेश प्राप्त करेंगे।

public class MyActivity extends FragmentActivity implements OnDialogSelectorListener { 
// .... 

    public void onSelectedOption(int selectedIndex) { 
     // do something with the newly selected index 
    } 
} 

मुझे आशा है कि यह किसी के लिए उपयोगी है, के रूप में यह मुझे इसे समझने के लिए कई प्रयास ले लिया। इस प्रकार के DialogFragment के कॉलबैक के साथ इस प्रकार का पूर्ण कार्यान्वयन यहां है। एक टिप्पणी से

public class SelectorDialog extends DialogFragment implements OnClickListener { 
    static final String TAG = "SelectorDialog"; 

    static int mResourceArray; 
    static int mSelectedIndex; 
    static OnDialogSelectorListener mDialogSelectorCallback; 

    public interface OnDialogSelectorListener { 
     public void onSelectedOption(int dialogId); 
    } 

    public static DialogSelectorDialog newInstance(int res, int selected) { 
     final DialogSelectorDialog dialog = new DialogSelectorDialog(); 
     mResourceArray = res; 
     mSelectedIndex = selected; 

     return dialog; 
    } 

    @Override 
    public void onAttach(Activity activity) { 
     super.onAttach(activity); 

     try { 
      mDialogSelectorCallback = (OnDialogSelectorListener)activity; 
     } catch (final ClassCastException e) { 
      throw new ClassCastException(activity.toString() + " must implement OnDialogSelectorListener"); 
     } 
    } 

    public Dialog onCreateDialog(Bundle savedInstanceState) { 
     final AlertDialog.Builder builder = new AlertDialog.Builder(this.getActivity()); 

     builder.setTitle(R.string.select); 
     builder.setSingleChoiceItems(mResourceArray, mSelectedIndex, this); 
     builder.setPositiveButton(R.string.ok, this); 
     builder.setNegativeButton(R.string.cancel, this); 
     return builder.create(); 
    } 

    @Override 
    public void onClick(DialogInterface dialog, int which) { 

     switch (which) { 
      case Dialog.BUTTON_NEGATIVE: 
       dialog.cancel(); 
       break; 

      case Dialog.BUTTON_POSITIVE: 
       dialog.dismiss(); 
       // message selected value to registered calbacks 
       mDialogSelectorCallback.onSelectedOption(mSelectedIndex); 
       break; 

      default: // choice selected click 
       mSelectedIndex = which; 
       break; 
     } 

    } 
} 

प्रश्न कैसे एक Fragment के बजाय एक Activity से कॉल करने के लिए।

पहले DialogFragment में कुछ बदलाव करें।

onAttach ईवेंट हटाएं क्योंकि यह इस परिदृश्य में सबसे आसान तरीका नहीं है।

कॉलबैक के लिए एक संदर्भ जोड़ने के लिए एक नई विधि जोड़ें

public void setDialogSelectorListener (OnDialogSelectorListener listener) { 
    this.mListener = listener; 
} 

अपने Fragment

public class MyFragment extends Fragment implements SelectorDialog.OnDialogSelectorListener { 
// .... 

    public void onSelectedOption(int selectedIndex) { 
     // do something with the newly selected index 
    } 
} 

में श्रोता को लागू करें अब एक नया उदाहरण बना सकते हैं और उपयोग करने के लिए Fragment के लिए एक संदर्भ में पारित यह।

final SelectorDialog sd = SelectorDialog.newInstance(R.array.selector_array, preSelectedValue); 
// this is a reference to MyFragment 
sd.setDialogSelectorListener(this); 
// mActivity is just a reference to the activity attached to MyFragment 
sd.show(this.mActivity.getSupportFragmentManager(), TAG); 
+0

आपकी स्पष्टीकरण के लिए धन्यवाद। कॉलबैक को कैसे कार्यान्वित किया जाएगा ताकि श्रोता को आग लगने पर 'गतिविधि' के बजाय 'फ्रैगमेंट' सूचित किया जा सके? – JJD

+2

मैंने एक स्पष्टीकरण जोड़ा है कि मैं इसे 'फ्रैगमेंट' में कैसे उपयोग करता हूं – Kirk

संबंधित मुद्दे