Bir etkinlik yöntemini bir parçadan çağırma


318

Etkinliğimdeki bir yöntemi bir parçadan çağırmaya çalışıyorum. Ben parçası yöntemi veri vermek ve yöntem döndüğünde veri almak istiyorum. Statik bir yöntem çağrısındakine benzer bir şekilde elde etmek istiyorum, ancak statikte kullanmadan aktivitede problem yaratıyor.

Parçalar için yeni, bu yüzden kolay ve pedagojik bir açıklamaya ihtiyacım var!

Teşekkürler!

Yanıtlar:


820

Parçadan etkinliğe:

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

Etkinlikten parçaya:

FragmentManager fm = getSupportFragmentManager();

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

Kodu kodla eklediyseniz ve parçanızı eklerken bir tagdize kullandıysanız findFragmentByTagbunun yerine şunu kullanın:

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

5
Dikkatli olun çünkü oyuncular işe yaramazsa beklenmedik şeyler olur ..: S
Ewoks

48
Döküm probleminden kaçınmak için şunu kullanın: Activity act = getActivity (); if (ActActivityClassName öğesinin örneğini gerçekleştir) ((YourActivityClassName) işlemi) .yourPublicMethod (); }
ericharlow

@Richard: Faaliyet içinde bir parçanın yöntemini gerçekleştirmemiz gerekiyorsa, nasıl zıt eylem gerçekleştirebiliriz?
Himanshu

5
Kötü tasarım ve bir Etkinlik yapmak güvenli değil. Bir Parça belirli bir Faaliyetle sınırlı değildir.
Aviv Ben Shabat

3
@Kay Mutlaka değil. Fragmanlar, parçalanmış daha büyük aktivitelerin "fragmanları" olarak kullanılabilir. Örneğin duyarlı kullanıcı arayüzleri oluşturmak için. Nadiren aynı parçayı kullanıyorum ve farklı aktivite ana bilgisayarlarına ekliyorum.
Richard

201

Muhtemelen başka bir yerde kullanmak istemeniz durumunda parçayı etkinlikten ayırmaya çalışmalısınız. Bunu, etkinliğinizin uyguladığı bir arayüz oluşturarak yapabilirsiniz.

Yani aşağıdaki gibi bir arayüz tanımlarsınız:

Örneğin, etkinliğe bir Dize vermek ve bir Tamsayı döndürmesini istediğinizi varsayalım:

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

Bu, parçada veya ayrı bir dosyada tanımlanabilir.

Daha sonra etkinliğinizin arayüzü uygulamasını sağlarsınız.

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;
  }

}

Sonra parçanızda bir MyStringListener değişkeni olur ve dinleyiciyi parçalı onAttach (Activity activity) yöntemine ayarlarsınız.

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. */
            }
        }

    }

düzenlemek (2015/12/17):onAttach(Activity activity) is deprecated, use onAttach(Context context) instead, it works as intended

İlk cevap kesinlikle işe yarıyor ancak mevcut parçanızı ana bilgisayar etkinliği ile birleştiriyor. Başka bir etkinlikte kullanmak istemeniz durumunda parçayı ana bilgisayar etkinliğinden ayırmak için iyi bir uygulamadır.


58
Buna bakan herkes için, kabul edilen cevap açık bir şekilde iş görürken, bu tasarım perspektifinden daha iyi ve daha güvenli bir yaklaşımdır.
Paul Richter

7
bu cevap kod tasarımı açısından çok daha iyi. Ayrıca etkinlik yanlış yayınlanırsa çökmelere neden olmaz
David T.

3
+1 ama onAttach'ta bir try-catch kullanmazdım. Başarısız olsun. Dinleyici isteğe bağlıysa (başarısızlık uygun değilse), parçaya bir set / addListener yöntemi ekleyin.
ataulm

Karşı taraf iletişimi için lütfen bkz . Developer.android.com/training/basics/fragments/… . Parçanın arayüzünü kullanarak (ayrıca yukarıda açıklandığı gibi fragman-> etkinlik iletişimini yapmanın güvenli bir yoludur), parçanız-> etkinliğinize dayalı bir işlem yapmak istiyorsanız, parçanızda bulunan bir yöntemi aktivitenizden de çağırabilirsiniz. comm.
Kerem

Parçalar yeniden kullanılmalı ve herhangi bir Faaliyette ayarlanmalıdır. Aynı Parçayı kullanan 5 etkinliğim olursa ne olur? Marco'nun cevabı doğru olan ve parçalararası ve Etkinlik-Parça iletişimi için iyi bir uygulamadır
blockwala

51

İçin Kotlin geliştiricileri

(activity as YourActivityClassName).methodName()

için Java geliştiricileri

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

Bu kodu çalıştırırsak kotlin'de hata veriyor .. başka bir yolu var mı?
Jake Garbo

1
Ben koştuğumda. ActivityClass'ın null değerini alıyorum, bunun kotlin'de bile hata yapmanın doğru yolu olmadığını düşünüyorum. ya da belki bir hata?
Jake Garbo

@JakeGarbo Aksi takdirde 12 kişi oy kullanmadı. ikinci şey bir süre getActivity () null döndürür SO üzerinde bu soruyu kontrol edin.
Wasim K. Memon

Sana söylediler. Eğer sizin için işe yaradıysa, takdir edin veya başka bir yol bulun veya önce nasıl kod yazacağınızı öğrenin.
Wasim K. Memon

13

Parçaların nasıl çalıştığını daha fazla anladıktan sonra güncelleyin. Her parça bir ana aktiviteye aittir. Sadece şunu kullanın:

getActivity().whatever

Parçanın içinden. Daha iyi bir cevaptır çünkü gereksiz dökümlerden kaçınırsınız. Bu çözümle dökümlerden kaçınamıyorsanız, aşağıdakini kullanın.

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

Yapmanız gereken dış aktiviteye atmak

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

yeni bir örnek oluşturmak android çerçevesini karıştırıyor olacak ve bunu tanıyamayacak. Ayrıca bakınız :

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

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


9

Marco'nun Yanıtını tamamen sevmeme rağmen, aynı sonucu elde etmek için yayınlama / abone olma tabanlı bir çerçeve de kullanabileceğinizi belirtmek adil olur, örneğin olay otobüsüyle giderseniz aşağıdakileri yapabilirsiniz

fragman:

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

Aktivite:

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

}

5

Kotlin'de aktivite yöntemini aşağıdaki gibi parçadan çağırabilirsiniz:

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

2

Faaliyetinizde beyan edilen bir fonksiyona parçanız aracılığıyla erişmek için lütfen marco'nun cevabında gösterildiği gibi bir arayüz kullanın.

Parçanızda bildirilen bir işleve etkinliğiniz aracılığıyla erişmek için bunu bir etiketiniz veya kimliğiniz yoksa kullanabilirsiniz

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


}

Bu 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);
    }
}

Bu cevap benim gibi asiller için. İyi günler.


1

Bu Fragment sınıfından ...

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

Etkinlik Sınıfından Bu Kod ...

 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

Bu konuda gösterilen tüm yöntemleri denedim ve hiçbiri benim için çalıştı, bunu deneyin. Benim için çalıştı.

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

0

Aramak istediğimiz her yöntemin aynı Etkinlik Üst Kısmına sahip Fragment'te bulunmaması nedeniyle bunu yapmanın en iyi yolunu arıyordum.

Parçanızda

public void methodExemple(View view){

        // your code here

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

Faaliyetinizde

new ExempleFragment().methodExemple(context); 

0

((YourActivityName)getActivity()).functionName();

Misal : ((SessionActivity)getActivity()).changeFragment();

Not: sınıf adı herkese açık olmalıdır


0
((your_activity) getActivity).method_name()

Nerede your_activityetkinlik adıdır ve method_name()aramak istediğiniz yöntemin adıdır.


0

Kotlin için deneyin

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)
    }
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.