एक खंड से एक गतिविधि विधि को बुलाओ


318

एक टुकड़े से मेरी गतिविधि में एक विधि को कॉल करने की कोशिश कर रहा है। मैं चाहता हूं कि खंड विधि को डेटा दे और विधि वापस आने पर डेटा प्राप्त करे। मैं एक स्थिर विधि पर कॉल करने के लिए समान प्राप्त करना चाहता हूं, लेकिन स्थिर के उपयोग के बिना क्योंकि यह गतिविधि में समस्याएं पैदा करता है।

टुकड़े करने के लिए नया तो मैं एक आसान और शैक्षणिक स्पष्टीकरण की जरूरत है!

धन्यवाद!

जवाबों:


820

टुकड़े से लेकर सक्रियता:

((YourActivityClassName)getActivity()).yourPublicMethod();

गतिविधि से लेकर टुकड़े तक:

FragmentManager fm = getSupportFragmentManager();

//if you added fragment via layout xml
YourFragmentClass fragment = (YourFragmentClass)fm.findFragmentById(R.id.your_fragment_id);
fragment.yourPublicMethod();

यदि आपने कोड के माध्यम से टुकड़ा जोड़ा और tagजब आपने अपना टुकड़ा जोड़ा, तो findFragmentByTagइसके बजाय एक स्ट्रिंग का उपयोग किया:

YourFragmentClass fragment = (YourFragmentClass)fm.findFragmentByTag("yourTag");

5
अगर कोई काम नहीं करता है, तो सावधान रहें क्योंकि अप्रत्याशित चीजें होती हैं ..: S
Ewoks

48
कास्ट समस्या के उपयोग से बचने के लिए: गतिविधि अधिनियम = getActivity (); if (act instof YourActivityClassName) ((YourActivityClassName) अधिनियम) .yourPublicMethod (); }
ericharlow

@ रीचर्ड: हम विपरीत क्रिया कैसे कर सकते हैं, जैसे, अगर हमें गतिविधि के अंदर एक खंडन विधि करनी है?
हिमांशु

5
किसी गतिविधि को करने के लिए यह खराब डिज़ाइन और असुरक्षित है। एक टुकड़ा एक विशिष्ट गतिविधि तक सीमित नहीं है।
अवीव बेन शाबात

3
@ जरूरी नहीं। टुकड़े टुकड़े का उपयोग किसी भी बड़ी गतिविधियों के टूटने के "टुकड़े" के रूप में किया जा सकता है। उदाहरण के लिए उत्तरदायी UI बनाने के लिए। मैं शायद ही कभी एक ही टुकड़े का उपयोग करता हूं और इसे विभिन्न गतिविधि मेजबानों के साथ संलग्न करता हूं।
रिचर्ड

201

यदि आप इसे कहीं और उपयोग करना चाहते हैं, तो आपको संभवतः गतिविधि से टुकड़े को हटाने का प्रयास करना चाहिए। आप ऐसा इंटरफ़ेस बनाकर कर सकते हैं जिसे आपकी गतिविधि लागू करती है।

तो आप निम्नलिखित की तरह एक इंटरफ़ेस परिभाषित करेंगे:

उदाहरण के लिए मान लीजिए कि आप गतिविधि को एक स्ट्रिंग देना चाहते हैं और क्या यह एक पूर्णांक लौटाता है:

public interface MyStringListener{
    public Integer computeSomething(String myString);
}

इसे खंड या एक अलग फ़ाइल में परिभाषित किया जा सकता है।

फिर आप अपनी गतिविधि को इंटरफ़ेस लागू करेंगे।

public class MyActivity extends FragmentActivity implements MyStringListener{

  @Override
  public Integer computeSomething(String myString){
   /** Do something with the string and return your Integer instead of 0 **/ 
   return 0;
  }

}

तब आपके टुकड़े में आपके पास एक MyStringListener चर होगा और आप श्रोता को onAttach (गतिविधि गतिविधि) विधि में सेट करेंगे।

public class MyFragment {

        private MyStringListener listener;

        @Override
        public void onAttach(Context context) {
            super.onAttach(context);
            try {
                listener = (MyStringListener) context;
            } catch (ClassCastException castException) {
                /** The activity does not implement the listener. */
            }
        }

    }

संपादित करें (2015/12/17):onAttach(Activity activity) is deprecated, use onAttach(Context context) instead, it works as intended

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


58
इसे देखने वाले किसी अन्य व्यक्ति के लिए, जबकि स्वीकृत उत्तर स्पष्ट रूप से काम करता है, यह एक डिजाइन परिप्रेक्ष्य से बेहतर, और सुरक्षित है।
पॉल रिक्टर

7
कोड डिज़ाइन के मामले में यह उत्तर बहुत बेहतर है। यह भी दुर्घटना का कारण नहीं होगा अगर गतिविधि गलत डाली गई है
डेविड टी।

3
+1 लेकिन मैं onAttach में ट्राइ-कैच का उपयोग नहीं करूंगा। इसे विफल होने दो। यदि श्रोता वैकल्पिक है (जो कि, असफल होना उचित नहीं है), टुकड़े में एक सेट / ऐड लिस्टनर विधि जोड़ें।
ataulm

विपरीत दिशा के संचार के लिए कृपया देखें: developer.android.com/training/basics/fragments/… । टुकड़े के इंटरफ़ेस का उपयोग करना (जो कि टुकड़े करने के लिए सुरक्षित तरीका भी है-> गतिविधि कॉम जैसा कि ऊपर बताया गया है) आप एक विधि को अपनी गतिविधि से खंडित कर सकते हैं और साथ ही यदि आप अपने टुकड़े के आधार पर कोई कार्रवाई करना चाहते हैं-> गतिविधि कॉम।
केरम

किसी भी गतिविधि में खंडों का पुन: उपयोग और सेट किया जाना है। क्या होगा यदि मेरे पास एक ही फ्रैगमेंट का उपयोग करने वाली 5 गतिविधियां हैं? मार्को का जवाब सही है और अंतर-टुकड़े और गतिविधि-फ्रैगमेंट संचार के लिए एक अच्छा अभ्यास
ब्लॉकवला

51

के लिए Kotlin डेवलपर्स

(activity as YourActivityClassName).methodName()

के लिए जावा डेवलपर्स

((YourActivityClassName) getActivity()).methodName();

यदि हम इस कोड को चलाते हैं तो यह कोटलिन में त्रुटि देता है .. क्या कोई और तरीका है?
जेक गरबो

1
जब मैं इसे चलाता हूं। मुझे एक्टिविटीक्लास का शून्य मान मिलता है, मुझे लगता है कि यह कोटलिन में ऐसा करने का उचित तरीका नहीं है यहां तक ​​कि कोई त्रुटि भी नहीं है। या शायद एक बग?
जेक गरबो

@JakeGarbo इसका उचित तरीका अन्यथा 12 लोगों ने इसके लिए मतदान नहीं किया है। दूसरी बात कुछ समय getActivity () रिटर्न अशक्त एसओ पर उन सवालों की जाँच करें।
वसीम के। मेमन

@JakeGarbo हां उन्होंने आपको बताया। यदि यह आपके लिए काम करता है, तो इसकी सराहना करें या अन्य तरीका खोजें या पहले कोड करना सीखें।
वसीम के। मेमन

13

अपडेट के बाद मैं समझता हूं कि टुकड़े कैसे काम करते हैं। प्रत्येक टुकड़ा एक मूल गतिविधि से संबंधित है। तो बस उपयोग करें:

getActivity().whatever

टुकड़े के भीतर से। यह एक बेहतर जवाब है क्योंकि आप सतही जातियों से बचते हैं। यदि आप इस समाधान के साथ जातियों से बच नहीं सकते हैं तो नीचे दिए गए एक का उपयोग करें।

============

बाहरी गतिविधि के लिए आपको क्या करना है

((MainActivity) getActivity()).Method();

एक नया उदाहरण बनाने से एंड्रॉइड फ़्रेम भ्रमित हो जाएगा और यह इसे पहचान नहीं पाएगा। यह सभी देखें :

https://stackoverflow.com/a/12014834/1984636

https://stackoverflow.com/a/2042829/1984636


9

हालांकि मुझे पूरी तरह से मार्को का उत्तर पसंद है, मुझे लगता है कि यह कहना उचित है कि आप उदाहरण के लिए एक ही परिणाम प्राप्त करने के लिए एक प्रकाशन / सदस्यता आधारित रूपरेखा का उपयोग कर सकते हैं यदि आप इवेंट बस के साथ जाते हैं तो आप निम्नलिखित कर सकते हैं

टुकड़ा:

EventBus.getDefault().post(new DoSomeActionEvent()); 

गतिविधि:

 @Subscribe
onSomeActionEventRecieved(DoSomeActionEvent doSomeActionEvent){
//Do something

}

5

कोटलिन में आप नीचे की तरह खंड से गतिविधि विधि कह सकते हैं:

var mainActivity: MainActivity = activity as MainActivity
        mainActivity.showToast() //Calling show toast method of activity

2

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

अपनी गतिविधि के माध्यम से आपके फ्रेगमेंट में घोषित एक फ़ंक्शन तक पहुंचने के लिए आप इसका उपयोग कर सकते हैं यदि आपके पास टैग या आईडी नहीं है

private void setupViewPager(ViewPager viewPager) {
    //fragmentOne,fragmentTwo and fragmentThree are all global variables
    fragmentOne= new FragmentOne();
    fragmentTwo= new FragmentTwo();
    fragmentThree = new FragmentThree();

    viewPagerAdapteradapter = new ViewPagerAdapter(getSupportFragmentManager());
    viewPagerAdapteradapter.addFragment(fragmentOne, "Frag1");
    viewPagerAdapteradapter.addFragment(fragmentTwo, "Frag2");
    viewPagerAdapteradapter.addFragment(fragmentThree, "Frag3");

    //viewPager has to be instantiated when you create the activity:
    //ViewPager viewPager = (ViewPager)findViewById(R.id.pager);
    //setupViewPager(viewPager);
    //Where R.id.pager is the id of the viewPager defined in your activity's xml page.

    viewPager.setAdapter(viewPagerAdapteradapter);


    //frag1 and frag2 are also global variables
    frag1 = (FragmentOne)viewPagerAdapteradapter.mFragmentList.get(0);
    frag2 = (FragmentTwo)viewPagerAdapteradapter.mFragmentList.get(1);;


    //You can use the variable fragmentOne or frag1 to access functions declared in FragmentOne


}

यह ViewpagerAdapterClass है

    class ViewPagerAdapter extends FragmentPagerAdapter {
    public final List<Fragment> mFragmentList = new ArrayList<>();
    private final List<String> mFragmentTitleList = new ArrayList<>();

    public ViewPagerAdapter(FragmentManager manager) {
        super(manager);
    }

    @Override
    public Fragment getItem(int position) {
        return mFragmentList.get(position);
    }

    @Override
    public int getCount() {
        return mFragmentList.size();
    }

    public void addFragment(Fragment fragment, String title) {
        mFragmentList.add(fragment);
        mFragmentTitleList.add(title);
    }

    @Override
    public CharSequence getPageTitle(int position) {
        return mFragmentTitleList.get(position);
    }
}

यह जवाब मेरे जैसे नोब्स के लिए है। आपका दिन शुभ हो।


1

यह फ्रैगमेंट क्लास से है ...

((KidsStoryDashboard)getActivity()).values(title_txt,bannerImgUrl);

गतिविधि वर्ग से यह कोड ...

 public void values(String title_txts, String bannerImgUrl) {
    if (!title_txts.isEmpty()) {

//Do something to set text 
    }
    imageLoader.displayImage(bannerImgUrl, htab_header_image, doption);
}

1

मैंने इस धागे में दिखाए गए सभी तरीकों की कोशिश की है और कोई भी मेरे लिए काम नहीं करता है, इसे आज़माएं। इसने मेरे लिए काम किया।

((MainActivity) getContext().getApplicationContext()).Method();

0

मैं यह करने के लिए सबसे अच्छा तरीका ढूंढ रहा हूं कि हम जिस पद्धति को कॉल करना चाहते हैं, वह उसी गतिविधि जनक के साथ Fragment में स्थित नहीं है।

आपके टुकड़े में

public void methodExemple(View view){

        // your code here

        Toast.makeText(view.getContext(), "Clicked clicked",Toast.LENGTH_LONG).show();
    }

आपकी गतिविधि में

new ExempleFragment().methodExemple(context); 


0
((your_activity) getActivity).method_name()

your_activityआपकी गतिविधि का नाम कहां है और method_name()उस विधि का नाम है जिसे आप कॉल करना चाहते हैं।


0

कोटलिन के लिए इसे आज़माएं

class DataForm : Fragment() {
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        Tasks(this).getData()
    }

    fun getResponse(response: String) {
        // code
    }
}

class Tasks(private val context: Any) {
    fun getData() {

        val getContext = (context as DataForm).activity
        val getFragment = (context as DataForm)

        val responseListener = Response.Listener<String> { response ->
            getFragment.getResponse(response)
        }

        val errorListener = Response.ErrorListener { error ->
            error.printStackTrace();
        }

        val stringRequest = StringRequest(Request.Method.GET, url, responseListener, errorListener)
        Volley.newRequestQueue(getContext).add(stringRequest)
    }
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.