2013-09-02 8 views
23

मेरे पास एक टुकड़ा है जो उपयोगकर्ता इनपुट (एक स्ट्रिंग और एक पूर्णांक) प्राप्त करने के लिए Dialogfragment खोलता है। मैं इन दो चीजों को वापस टुकड़े में कैसे भेजूं? मैं बटन क्लिक करने के बाद डेटा भेजने के लिए की जरूरत है और getDialog().dismiss()डायलॉग फ्रैगमेंट से डेटा को फ्रैगमेंट में कैसे भेजा जाए?

यहाँ से पहले टुकड़ा है कि डेटा के लिए भेजा जाना चाहिए

public class DatePickerFragment extends DialogFragment { 
    String Month; 
    int Year; 

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
     getDialog().setTitle(getString(R.string.Date_Picker)); 
     View v = inflater.inflate(R.layout.date_picker_dialog, container, false); 

     Spinner months = (Spinner) v.findViewById(R.id.months_spinner); 
     ArrayAdapter<CharSequence> monthadapter = ArrayAdapter.createFromResource(getActivity(), 
       R.array.Months, R.layout.picker_row); 
       months.setAdapter(monthadapter); 
       months.setOnItemSelectedListener(new OnItemSelectedListener(){ 
        @Override 
        public void onItemSelected(AdapterView<?> parentView, View selectedItemView, int monthplace, long id) { 
         Month = Integer.toString(monthplace); 
        } 
        public void onNothingSelected(AdapterView<?> parent) { 
        } 
       }); 

     Spinner years = (Spinner) v.findViewById(R.id.years_spinner); 
     ArrayAdapter<CharSequence> yearadapter = ArrayAdapter.createFromResource(getActivity(), 
      R.array.Years, R.layout.picker_row); 
     years.setAdapter(yearadapter); 
     years.setOnItemSelectedListener(new OnItemSelectedListener(){ 
      @Override 
      public void onItemSelected(AdapterView<?> parentView, View selectedItemView, int yearplace, long id) { 
       if (yearplace == 0){ 
        Year = 2012; 
       }if (yearplace == 1){ 
        Year = 2013; 
       }if (yearplace == 2){ 
        Year = 2014; 
       } 
      } 
      public void onNothingSelected(AdapterView<?> parent) {} 
     }); 

     Button button = (Button) v.findViewById(R.id.button); 
     button.setOnClickListener(new View.OnClickListener() { 
      public void onClick(View v) { 
       getDialog().dismiss(); 
      } 
     }); 

     return v; 
    } 
} 

:

public class CalendarFragment extends Fragment { 
int Year; 
String Month; 

@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, 
     Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 

    int position = getArguments().getInt("position"); 
    String[] categories = getResources().getStringArray(R.array.categories); 
    getActivity().getActionBar().setTitle(categories[position]); 
    View v = inflater.inflate(R.layout.calendar_fragment_layout, container, false);  

    final Calendar c = Calendar.getInstance(); 
    SimpleDateFormat month_date = new SimpleDateFormat("MMMMMMMMM"); 
    Month = month_date.format(c.getTime()); 
    Year = c.get(Calendar.YEAR); 

    Button button = (Button) v.findViewById(R.id.button); 
    button.setText(Month + " "+ Year); 
    button.setOnClickListener(new View.OnClickListener() { 
     public void onClick(View v) { 
      new DatePickerFragment().show(getFragmentManager(), "MyProgressDialog"); 
     } 
    }); 
    return v; 
    } 
} 

यहाँ मेरी DialogFragment है

इसलिए जब उपयोगकर्ता Dialogfragment में कोई दिनांक चुनता है, तो उसे महीने और वर्ष वापस करना होगा।

फिर, बटन पर टेक्स्ट उपयोगकर्ता द्वारा निर्दिष्ट महीने और वर्ष में बदलना चाहिए।

उत्तर

63

नोट: एक या दो टुकड़े विशिष्ट कॉल से अलग, यह कमजोर युग्मित घटकों के बीच डेटा एक्सचेंज के कार्यान्वयन के लिए एक सामान्य दृष्टिकोण नुस्खा है। आप सचमुच कुछ भी के बीच डेटा का आदान-प्रदान करने के लिए इस दृष्टिकोण का सुरक्षित रूप से उपयोग कर सकते हैं, चाहे वह टुकड़े, गतिविधियां, संवाद या आपके आवेदन के किसी भी अन्य घटक हों।


यहाँ नुस्खा है:

  1. बनाएं interface (अर्थात MyContract नाम) विधि का एक हस्ताक्षर युक्त, डेटा पास करने के लिए इस्तेमाल किया जा अर्थात methodToPassData(... data);
  2. सुनिश्चित करें कि आपका DialogFragment अपने अनुबंध लागू करता है: class MyFragment extends Fragment implements MyContract {....}
  3. DialogFragment के निर्माण पर सेट अपने लागू Fragment DialogFragment के target fragment रूप myDialogFragment.setTargetFragment(this, 0); फोन करके। यह आपकी वस्तु है जिसे आप बाद में बात करेंगे।
  4. अपने DialogFragment में, getTargetFragment(); पर कॉल करके उस खंड को आविष्कार करें और चरण 1 में बनाए गए अनुबंध इंटरफ़ेस पर ऑब्जेक्ट लौटाएं, MyContract mHost = (MyContract)getTargetFragment();। यह चरण सुनिश्चित करता है कि आपका लक्ष्य आपके डेटा को संभालने के तरीकों के लिए आवश्यक अनुबंध को लागू करता है। ध्यान दें कि यदि आपका लक्ष्य खंड MyContract इंटरफ़ेस लागू नहीं कर रहा है तो आपको ClassCastException मिलेगा। यह आमतौर पर तब तक नहीं होना चाहिए जब तक कि आप बहुत अधिक प्रतिलिपि और पेस्ट-कोडिंग नहीं कर रहे हैं :), या शायद, आपकी परियोजना बाहरी कोड, पुस्तकालयों या प्लगइन्स इत्यादि का उपयोग करती है और ऐसे मामले में आपको अपवाद को पकड़ना चाहिए और उपयोगकर्ता को यानी प्लगइन इसके बजाय संगत नहीं है।
  5. जब डेटा वापस भेजने के लिए समय आता है, तो आपको प्राप्त ऑब्जेक्ट पर methodToPassData() पर कॉल करें, यानी यह ((MyContract)getTargetFragment()).methodToPassData(data); पसंद है। यदि आपका onAttach() पहले से ही एक चर (यानी mHost) पर लक्षित खंड को रोकता है और निर्दिष्ट करता है, तो यह कोड केवल mHost.methodToPassData(data); होगा।
  6. वोला।

आपने सफलतापूर्वक अपने डेटा को खंड से वापस सफलतापूर्वक पास कर दिया है।

+1

तुम सिर्फ बजाय इंटरफेस के माध्यम से गुजर का टुकड़ा अंदर विधि को परिभाषित कर सकता है? – splinter123

+2

आप कर सकते थे, लेकिन फिर संवाद को उस खंड के प्रकार को जानना होगा जिसने इसे बुलाया था। इससे संवाद केवल एक विशिष्ट टुकड़े से उपयोग योग्य होगा। इंटरफ़ेस के माध्यम से वापस कॉल करना एक बहुत अधिक लचीला दृष्टिकोण है। –

+3

मुझे यह जवाब पसंद आया। न केवल यह स्पष्ट रूप से मेरी मदद करता है, लेकिन आपने कोड के ब्लॉक को लिखने और चरणों को समझाए बिना किया। +1 – AdamMc331

27

किसी भी इंटरफ़ेस का उपयोग किये बिना यहां एक और नुस्खा है। डायलॉग फ्रैगमेंट और फ्रैगमेंट के बीच डेटा पास करने के लिए बस setTargetFragment और Bundle का उपयोग करना।

public static final int DATEPICKER_FRAGMENT = 1; // class variable 

1. कॉल के रूप में DialogFragment नीचे दिखाया गया है:

DialogFragment में एक Intent में
// create dialog fragment 
DatePickerFragment dialog = new DatePickerFragment(); 

// optionally pass arguments to the dialog fragment 
Bundle args = new Bundle(); 
args.putString("pickerStyle", "fancy"); 
dialog.setArguments(args); 

// setup link back to use and display 
dialog.setTargetFragment(this, DATEPICKER_FRAGMENT); 
dialog.show(getFragmentManager().beginTransaction(), "MyProgressDialog") 

2. उपयोग अतिरिक्त Bundle वापस जो कुछ भी जानकारी लक्ष्य टुकड़ा करने के लिए पारित करने के लिए। Button#onClick()DatePickerFragment की घटना में निम्न कोड एक स्ट्रिंग और इंटीजर पास करता है।

Intent i = new Intent() 
     .putExtra("month", getMonthString()) 
     .putExtra("year", getYearInt()); 
getTargetFragment().onActivityResult(getTargetRequestCode(), Activity.RESULT_OK, i); 
dismiss(); 

3. उपयोग CalendarFragment के onActivityResult() विधि मूल्यों को पढ़ने के लिए:

@Override 
public void onActivityResult(int requestCode, int resultCode, Intent data) { 
    switch (requestCode) { 
     case DATEPICKER_FRAGMENT: 
      if (resultCode == Activity.RESULT_OK) { 
       Bundle bundle = data.getExtras(); 
       String mMonth = bundle.getString("month", Month); 
       int mYear = bundle.getInt("year"); 
       Log.i("PICKER", "Got year=" + year + " and month=" + month + ", yay!"); 
      } else if (resultCode == Activity.RESULT_CANCELED) { 
       ... 
      } 
      break; 
    } 
} 
+0

क्या आपको एक्टिविटी रिसेट पर उपयोग करना है? आप खंड से संवाद तक डेटा कैसे पारित करेंगे - ऐसा लगता है कि यह केवल खंड के लिए संवाद है? –

+0

@ xphill64x: हां, 'onActivityResult' खंड में विधि है जो डायलॉग फ्रैगमेंट से प्रतिक्रिया प्राप्त करती है। आप 'फ्रैगमेंट टू डायलॉग फ्रैगमेंट' से डेटा पास करने के लिए 'बंडल' का उपयोग कर सकते हैं। – blizzard

+1

यह सबसे अच्छा तरीका नहीं है क्योंकि आप अपने लक्ष्य को छोड़कर डेटा w/o पास करने में असमर्थ हैं, जबकि इंटरफ़ेस का उपयोग करने में यह कमी नहीं होती है। –

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