Parçalar arasında değerler nasıl geçirilir


109

Fragments'ı kullanmakta oldukça yeniyim.

Fragments kullanan basit bir örnek uygulama oluşturmaya çalışıyorum. Benim senaryom, her faaliyetin içinde bir parça bulunan iki faaliyetim var. İlk parçanın bir edittext ve bir düğmesi vardır. İkinci parçanın bir metin görünümü vardır. Edittext'e bir isim girdiğimde ve butona tıkladığımda, ikinci parçadaki metin görünümünde ilk parçanın edittext'de girilen adı göstermesi gerekir.

Değeri ilk parçadan etkinliğine ve sonra o etkinlikten ikinci etkinliğe gönderebildim. Şimdi bu değeri ikinci parçanın içinde nasıl kullanacağım.

İşte Java kodu :::

package com.example.fragmentexample;

import android.app.Activity;
import android.app.Fragment;
import android.app.FragmentManager;
import android.content.Intent;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

public class Fragment_1 extends Fragment{

    OnFragmentChangedListener mCallback;

    // Container Activity must implement this interface
    public interface OnFragmentChangedListener {
        public void onButtonClicked(String name);
    }

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

        // This makes sure that the container activity has implemented
        // the callback interface. If not, it throws an exception
        try {
            mCallback = (OnFragmentChangedListener) activity;
        } catch (ClassCastException e) {
            throw new ClassCastException(activity.toString()
                    + " must implement OnHeadlineSelectedListener");
        }
    }


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        // TODO Auto-generated method stub      

        View view = inflater.inflate(R.layout.fragment_fragment_1, container, false);

        final EditText edtxtPersonName_Fragment = (EditText) view.findViewById(R.id.edtxtPersonName);
        Button btnSayHi_Fragment = (Button) view.findViewById(R.id.btnSayHi);

        btnSayHi_Fragment.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub

                String name = edtxtPersonName_Fragment.getText().toString();

                FragmentManager fm = getFragmentManager();
                Fragment_2 f2 = (Fragment_2) fm.findFragmentById(R.id.fragment_content_2);

                Activity activity = getActivity();

                if(activity != null)
                {
                    Toast.makeText(activity, "Say&ing Hi in Progress...", Toast.LENGTH_LONG).show();
                }


                if(f2 != null && f2.isInLayout())
                {
                    f2.setName(name);
                }
                else
                {
                    mCallback.onButtonClicked(name);
                }
            }
        });

        return view;


    }

}

MainActivity.Java

package com.example.fragmentexample;

import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;

import android.view.Choreographer.FrameCallback;
import android.view.Menu;

public class MainActivity extends Activity implements Fragment_1.OnFragmentChangedListener {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);     
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.activity_main, menu);
        return true;
    }

    @Override
    public void onButtonClicked(String name) {
        // TODO Auto-generated method stub

        Intent i = new Intent(this, SecondActivity.class);
        i.putExtra("", name);
        startActivity(i);
    }

}

SecondActivity.Java

package com.example.fragmentexample;

import android.app.Activity;
import android.os.Bundle;

public class SecondActivity extends Activity{

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_second);

        Bundle b = getIntent().getExtras();

        Fragment_2 f2 = new Fragment_2();
        f2.setArguments(b);
    }
}

Fragment_2.Java

package com.example.fragmentexample;

import android.app.Activity;
import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

public class Fragment_2 extends Fragment{

    View view;
    TextView txtName;


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        // TODO Auto-generated method stub

        view = inflater.inflate(R.layout.fragment_fragment_2, container, false);

            // Exception at this line
        String name = getArguments().getString("message");
        txtName = (TextView) view.findViewById(R.id.txtViewResult);
        txtName.setText(name);

        return view;
    }

    @Override
    public void onAttach(Activity activity) {
        // TODO Auto-generated method stub
        super.onAttach(activity);       
    }

    public void setName(String name)
    {   
        txtName.setText("Hi " + name);
    }

}

Aşağıdaki istisnayı alıyorum :::

04-16 18:10:24.573: E/AndroidRuntime(713): FATAL EXCEPTION: main
04-16 18:10:24.573: E/AndroidRuntime(713): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.fragmentexample/com.example.fragmentexample.SecondActivity}: android.view.InflateException: Binary XML file line #8: Error inflating class fragment
04-16 18:10:24.573: E/AndroidRuntime(713):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1815)
04-16 18:10:24.573: E/AndroidRuntime(713):  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1831)
04-16 18:10:24.573: E/AndroidRuntime(713):  at android.app.ActivityThread.access$500(ActivityThread.java:122)
04-16 18:10:24.573: E/AndroidRuntime(713):  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1024)
04-16 18:10:24.573: E/AndroidRuntime(713):  at android.os.Handler.dispatchMessage(Handler.java:99)
04-16 18:10:24.573: E/AndroidRuntime(713):  at android.os.Looper.loop(Looper.java:132)
04-16 18:10:24.573: E/AndroidRuntime(713):  at android.app.ActivityThread.main(ActivityThread.java:4123)
04-16 18:10:24.573: E/AndroidRuntime(713):  at java.lang.reflect.Method.invokeNative(Native Method)
04-16 18:10:24.573: E/AndroidRuntime(713):  at java.lang.reflect.Method.invoke(Method.java:491)
04-16 18:10:24.573: E/AndroidRuntime(713):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:841)
04-16 18:10:24.573: E/AndroidRuntime(713):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:599)
04-16 18:10:24.573: E/AndroidRuntime(713):  at dalvik.system.NativeStart.main(Native Method)
04-16 18:10:24.573: E/AndroidRuntime(713): Caused by: android.view.InflateException: Binary XML file line #8: Error inflating class fragment
04-16 18:10:24.573: E/AndroidRuntime(713):  at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:688)
04-16 18:10:24.573: E/AndroidRuntime(713):  at android.view.LayoutInflater.rInflate(LayoutInflater.java:724)
04-16 18:10:24.573: E/AndroidRuntime(713):  at android.view.LayoutInflater.inflate(LayoutInflater.java:479)
04-16 18:10:24.573: E/AndroidRuntime(713):  at android.view.LayoutInflater.inflate(LayoutInflater.java:391)
04-16 18:10:24.573: E/AndroidRuntime(713):  at android.view.LayoutInflater.inflate(LayoutInflater.java:347)
04-16 18:10:24.573: E/AndroidRuntime(713):  at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:223)
04-16 18:10:24.573: E/AndroidRuntime(713):  at android.app.Activity.setContentView(Activity.java:1786)
04-16 18:10:24.573: E/AndroidRuntime(713):  at com.example.fragmentexample.SecondActivity.onCreate(SecondActivity.java:13)
04-16 18:10:24.573: E/AndroidRuntime(713):  at android.app.Activity.performCreate(Activity.java:4397)
04-16 18:10:24.573: E/AndroidRuntime(713):  at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1048)
04-16 18:10:24.573: E/AndroidRuntime(713):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1779)
04-16 18:10:24.573: E/AndroidRuntime(713):  ... 11 more
04-16 18:10:24.573: E/AndroidRuntime(713): Caused by: java.lang.NullPointerException
04-16 18:10:24.573: E/AndroidRuntime(713):  at com.example.fragmentexample.Fragment_2.onCreateView(Fragment_2.java:24)
04-16 18:10:24.573: E/AndroidRuntime(713):  at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:754)
04-16 18:10:24.573: E/AndroidRuntime(713):  at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:956)
04-16 18:10:24.573: E/AndroidRuntime(713):  at android.app.FragmentManagerImpl.addFragment(FragmentManager.java:1035)
04-16 18:10:24.573: E/AndroidRuntime(713):  at android.app.Activity.onCreateView(Activity.java:4177)
04-16 18:10:24.573: E/AndroidRuntime(713):  at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:664)
04-16 18:10:24.573: E/AndroidRuntime(713):  ... 21 more

SecondActivity.java'daki paketten Fragment_2.Java'ya nasıl değer alabilirim?


Lütfen sorunun
çözüldüğü

kolay yoldan çalışma çözümü: stackoverflow.com/a/59332751/10201722
Adil Siddiqui

Yanıtlar:


203

Adım 1. verileri parçadan aktiviteye göndermek için

Intent intent = new Intent(getActivity().getBaseContext(),
                        TargetActivity.class);
                intent.putExtra("message", message);
                getActivity().startActivity(intent);

Adım 2. Bu verileri Faaliyette almak için:

Intent intent = getIntent();
String message = intent.getStringExtra("message");

3. adım . aktiviteden başka bir aktiviteye veri göndermek için normal yaklaşımı izleyin

Intent intent = new Intent(MainActivity.this,
                        TargetActivity.class);
                intent.putExtra("message", message);
                startActivity(intent);

bu verileri aktivitede almak için 4. adım

     Intent intent = getIntent();
  String message = intent.getStringExtra("message");

Adım 5. Etkinlikten, aşağıdaki amaçlarla Parçaya veri gönderebilirsiniz:

Bundle bundle=new Bundle();
bundle.putString("message", "From Activity");
  //set Fragmentclass Arguments
Fragmentclass fragobj=new Fragmentclass();
fragobj.setArguments(bundle);

ve Fragment onCreateView yönteminde parça halinde almak için:

@Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
    Bundle savedInstanceState) {
          String strtext=getArguments().getString("message");

    return inflater.inflate(R.layout.fragment, container, false);
    }

2
5. adımı denedim, listaktiviteyi parçadan çağırıyorum ve bu etkinlikten öğeyi seçtikten sonra, seçilen dosya adıyla parça halinde geri gelmek istiyorum. Ama çalışmıyor, bana onCreateView'da Nullpointer İstisnası veriyor. Bununla ilgili bir çözüm var mı lütfen? Bu benim sorum stackoverflow.com/questions/18208771/…
OnkarDhane

buraya nasıl POJO koyarım? bundle.putString("message", "From Activity");
jeet.chanchawat

31
Böyle bir şey yapmanın ne kadar karmaşık olduğundan tiksinen var mı
Ed Lee

1
Kesinlikle Eddie, bu doğru yol değil. Konteyner etkinliği aracılığıyla parçalar arasında iletişim kurmak için arayüzler kullanmalıdırlar.
Kaveesh Kanwal

Parçalar arasında iletişim kurmak için arayüzlerin kullanılmasıyla ilgili olarak: developer.android.com/training/basics/fragments/…
Andre L Torres

49

Geliştirici sitesinde belirtildiği gibi

Genellikle bir Parçanın diğeriyle iletişim kurmasını istersiniz, örneğin içeriği bir kullanıcı olayına göre değiştirmek için. Tüm Parçadan Parçaya iletişim, ilgili Etkinlik aracılığıyla yapılır. İki Fragman asla doğrudan iletişim kurmamalıdır.

parçalar arasındaki iletişim, ilgili Faaliyet aracılığıyla yapılmalıdır.

Aşağıdaki bileşenlere sahip olalım:

Bir etkinlik parçaları barındırır ve parçaların iletişimine izin verir

Fragment: Veri gönderecek ilk fragman

FragmentB dataları alacak ikinci bir parça Fragmenta

FragmentA'nın uygulaması:

public class FragmentA extends Fragment 
{
    DataPassListener mCallback;
    
    public interface DataPassListener{
        public void passData(String data);
    }

    @Override
    public void onAttach(Context context) 
    {
        super.onAttach(context);
        // This makes sure that the host activity has implemented the callback interface
        // If not, it throws an exception
        try 
        {
            mCallback = (OnImageClickListener) context;
        }
        catch (ClassCastException e) 
        {
            throw new ClassCastException(context.toString()+ " must implement OnImageClickListener");
        }
    }
    
    public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) 
    {
        // Suppose that when a button clicked second FragmentB will be inflated
        // some data on FragmentA will pass FragmentB
        // Button passDataButton = (Button).........
        
        passDataButton.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                if (view.getId() == R.id.passDataButton) {
                    mCallback.passData("Text to pass FragmentB");
                }
            }
        });
    }
}

MainActivity uygulaması:

public class MainActivity extends ActionBarActivity implements DataPassListener{
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        if (findViewById(R.id.container) != null) {
            if (savedInstanceState != null) {
                return;
            }
            getFragmentManager().beginTransaction()
                    .add(R.id.container, new FragmentA()).commit();
        }
    }
    
    @Override
    public void passData(String data) {
        FragmentB fragmentB = new FragmentB ();
        Bundle args = new Bundle();
        args.putString(FragmentB.DATA_RECEIVE, data);
        fragmentB .setArguments(args);
        getFragmentManager().beginTransaction()
            .replace(R.id.container, fragmentB )
            .commit();
    }
}

FragmentB uygulaması:

public class FragmentB extends Fragment{
    final static String DATA_RECEIVE = "data_receive";
    TextView showReceivedData;
    
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_B, container, false);
        showReceivedData = (TextView) view.findViewById(R.id.showReceivedData);
    }
    
    @Override
    public void onStart() {
        super.onStart();
        Bundle args = getArguments();
        if (args != null) {
            showReceivedData.setText(args.getString(DATA_RECEIVE));
        }
    }
}

Umarım bu yardımcı olacak..


4
Buradaki OnImageClickListener nedir? ve bir DataPassListener değişkenine nasıl dönüştürülür?
Harsha

"DataPassListener" olduğunu buldum. Çalışmasını sağladım, ancak yalnızca düğmeye her tıklandığında veriler gönderildiği için bulmak için. Gönderildiğinde parçanın yerini alır. Bu, listenin her seferinde yenileneceği anlamına gelir. Bu nedenle, öğelerin listesini bellekte tutmamak.
wesley franks

44

// Fragment_1.java'da

Bundle bundle = new Bundle();
bundle.putString("key","abc"); // Put anything what you want

Fragment_2 fragment2 = new Fragment_2();
fragment2.setArguments(bundle);

getFragmentManager()
      .beginTransaction()
      .replace(R.id.content, fragment2)
      .commit();

// Fragment_2.java'da

Bundle bundle = this.getArguments();

if(bundle != null){
     // handle your code here.
}

Umarım bu size yardımcı olur.


1
Ana noktayı göstermek için net cevap. putString(veya putInt) kullanmak cevaptır!
Mehdi Dehghani

22

Gönderen Geliştiriciler web:

Genellikle bir Parçanın diğeriyle iletişim kurmasını istersiniz, örneğin içeriği bir kullanıcı olayına göre değiştirmek için. Tüm Parçadan Parçaya iletişim, ilgili Etkinlik aracılığıyla yapılır. İki Fragman asla doğrudan iletişim kurmamalıdır.

Faaliyetinin yardımıyla parçalar arasında iletişim kurabilirsiniz. Bu yaklaşımı kullanarak faaliyet ve parça arasında iletişim kurabilirsiniz .

Lütfen bu bağlantıyı da kontrol edin .


Verdiğiniz ikinci bağlantı, aynı aktivitede olduklarında parçalar arasında nasıl iletişim kurulacağını gösterir. Her ikisi de farklı aktivitelerdeyken nasıl iletişim kurarım?
Vamsi Challa

5

Öncelikle tüm cevaplar doğrudur, kullanarak özel nesneler dışındaki verileri aktarabilirsiniz Intent. Eğer özel nesneleri geçmek istiyorsanız, uygulamak zorunda Serialazableya Parcelableda özel nesne sınıfına. Bunun çok karmaşık olduğunu düşündüm ...

Yani projeniz basitse kullanmayı deneyin DataCache. Bu, veri aktarımı için süper basit bir yol sağlar. Ref: Github projesi CachePot

1- Bunu, veri gönderecek Görünüm veya Etkinlik veya Parça olarak ayarlayın

DataCache.getInstance().push(obj);

2- Aşağıdaki gibi her yerde veri alın

public class MainFragment extends Fragment
{
    private YourObject obj;

    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);

        obj = DataCache.getInstance().pop(YourObject.class);

    }//end onCreate()
}//end class MainFragment

İçinde statik değerler olan ekstra bir sınıf kullanmak daha kolay olmaz mıydı? Bu değerlere daha sonra her iki parça tarafından da erişilebilir, bu nedenle özel nesneleri önbelleğe almak için fazladan bir kitaplık kullanmaya gerek yoktur.
nef

4

Parçalar arasında veri aktarımı için en son çözüm, ViewModel ve LiveData gibi android mimari bileşenler kullanılarak uygulanabilir. Bu çözümle, iletişim için arayüz tanımlamanıza gerek kalmaz ve konfigürasyon değişiklikleri nedeniyle veri sağkalımı gibi viewmodel kullanmanın avantajlarını elde edebilirsiniz.

Bu çözümde, iletişimde yer alan parçalar, etkinlik yaşam döngülerine bağlı olan aynı görünüm modeli nesnesini paylaşır. Görünüm modeli nesnesi, yaşam verileri nesnesi içerir. Bir parça, canlı veri nesnesine aktarılacak verileri ayarlar ve ikinci parça gözlemcileri veri değişikliklerini yaşadı ve verileri aldı.

Tam örnek http://www.zoftino.com/passing-data-between-android-fragments-using-viewmodel


3

Parçalar arasında argümanlar iletmek. Bu soruyu cevaplamak için oldukça geç ancak birine yardımcı olabilir! Fragment_1.java

Bundle i = new Bundle(); 
            i.putString("name", "Emmanuel");

            Fragment_1 frag = new Fragment_1();
            frag.setArguments(i);
            FragmentManager fragmentManager = getFragmentManager();
            fragmentManager.beginTransaction()
                    .replace(R.id.content_frame
                            , new Fragment_2())
                    .commit();

Daha sonra Fragment_2.java, parametrelerinizi normal olarak onActivityCreated örneğin

 Intent intent = getActivity().getIntent();
    if (intent.getExtras() != null) {
        String name =intent.getStringExtra("name");
    }

3

Bence bu sorunu çözmenin iyi bir yolu özel bir arayüz kullanmaktır.

Diyelim ki aynı aktivitenin içinde olan iki parçanız (A ve B) var ve A'dan B'ye veri göndermek istiyorsunuz.

Arayüz :

public interface OnDataSentListener{
    void onDataSent(Object data);
}

Aktivite:

    public class MyActivity extends AppCompatActivity{

            private OnDataSentListener onDataSentListener;

            @Override
            protected void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
                setContentView(R.layout.activity_activity);

                FragmentTransaction trans = getFragmentManager().beginTransaction();

                FragmentA fa = new FragmentA();
                FragmentB fb = new FragmentB();

               fa.setOnDataSentListener(new Listeners.OnDataSentListener() {
                    @Override
                    public void onDataSent(Object data) {
                         if(onDataSentListener != null)  onDataSentListener.onDataSent(data);
                    }
               });

                transaction.add(R.id.frame_a, fa);
                transaction.add(R.id.frame_b, fb);

                transaction.commit();
            }

            public void setOnDataSentListener(OnDataSentListener listener){
                this.onDataSentListener = listener;
            }
        }

A Parçası:

public class FragmentA extends Fragment{

    private OnDataSentListener onDataSentListener;

    private void sendDataToFragmentB(Object data){
        if(onDataSentListener != null) onDataSentListener.onDataSent(data);
    }

    public void setOnDataSentListener(OnDataSentListener listener){
        this.onDataSentListener = listener;
    }
}

Parça B:

public class FragmentB extends Fragment{

    private void initReceiver(){
        ((MyActivity) getActivity()).setOnDataSentListener(new OnDataSentListener() {
            @Override
            public void onDataSent(Object data) {
                //Here you receive the data from fragment A
            }
        });
    }
}

2

Parçalar arasında iletişim kurmak oldukça karmaşık (dinleyici kavramını uygulamak için biraz zor buluyorum).

Bu iletişimleri soyutlamak için bir "Olay Veriyolu" kullanmak yaygındır. Bu, bu iletişimi sizin için halleden bir 3. taraf kitaplığıdır.

"Otto" bunu yapmak için sıklıkla kullanılan bir yöntemdir ve araştırmaya değer olabilir: http://square.github.io/otto/


2

Parçadan başka bir Parçaya veri aktarımı

  • İlk Fragman'dan

    // Set data to pass
    MyFragment fragment = new MyFragment(); //Your Fragment
    Bundle bundle = new Bundle();
    bundle.putInt("year", 2017)  // Key, value
    fragment.setArguments(bundle); 
    // Pass data to other Fragment
    getFragmentManager()
     .beginTransaction()
     .replace(R.id.content, fragment)
     .commit(); 
  • İkinci Fragmanda

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
    
         Bundle bundle = this.getArguments();
         if (bundle != null) {
             Int receivedYear = bundle.getInt("year", ""); // Key, default value
         } 
    }

1

Bu basit uygulama, verilerin fragmanlar arasında basit bir şekilde aktarılmasına yardımcı olur. Verileri 'Frgment1'den' Fragment2'ye geçirmek istediğinizi düşünün

Fragment1'de (Gönderilecek verileri ayarlayın)

 Bundle bundle = new Bundle();
 bundle.putString("key","Jhon Doe"); // set your parameteres

 Fragment2 nextFragment = new Fragment2();
 nextFragment.setArguments(bundle);

 FragmentManager fragmentManager = getActivity().getSupportFragmentManager();
 fragmentManager.beginTransaction().replace(R.id.content_drawer, nextFragment).commit();

Fragment2 onCreateView yönteminde (Parametreleri alın)

String value = this.getArguments().getString("key");//get your parameters
Toast.makeText(getActivity(), value+" ", Toast.LENGTH_LONG).show();//show data in tost

Uygulamamda bunu çalıştırmaya çalışıyorum ama bir şekilde değer geçiliyor olsa da fragment2'de görüntülenmiyor, sanırım R.id.content_drawer'ı ayarlamada hata yapıyorum. Biri bana R.id.content_drawer için doğru tanımlayıcının .xml örneğiyle rehberlik edebilir mi?
şahin

1

Kotlin yolu

SharedViewModelResmi ViewModel belgelerinde önerileni kullanın

Bir faaliyetteki iki veya daha fazla parçanın birbiriyle iletişim kurması çok yaygındır. Kullanıcının listeden bir öğe seçtiği bir parçaya ve seçilen öğenin içeriğini görüntüleyen başka bir parçaya sahip olduğunuz yaygın bir ana ayrıntı parçaları durumunu hayal edin. Bu durum hiçbir zaman önemsiz değildir çünkü her iki parçanın da bazı arayüz açıklamaları tanımlaması gerekir ve sahip etkinliği ikisini birbirine bağlamalıdır. Ek olarak, her iki parça da, diğer parçanın henüz yaratılmadığı veya görünmediği senaryoyu işlemelidir.

Bu yaygın sorun noktası, ViewModel nesneleri kullanılarak ele alınabilir. Bu parçalar, bu iletişimi yönetmek için etkinlik kapsamlarını kullanarak bir ViewModel paylaşabilir.

Görünüm modelinizi daha kolay örneklemek için ilk parça-ktx uygulayın

dependencies {
    implementation "androidx.fragment:fragment-ktx:1.2.2"
} 

Ardından, diğer parça ile paylaşacağınız verileri görünüm modelinin içine koymanız yeterlidir.

class SharedViewModel : ViewModel() {
    val selected = MutableLiveData<Item>()

    fun select(item: Item) {
        selected.value = item
    }
}

Ardından, bitirmek için, her bir parçada viewModel'inizi somutlaştırın selectedve verileri ayarlamak istediğiniz parçanın değerini ayarlayın.

Bölüm A

class MasterFragment : Fragment() {

    private val model: SharedViewModel by activityViewModels()

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        itemSelector.setOnClickListener { item ->
        model.select(item)
      }

    }
}

Sonra Fragment hedefinizde bu değeri dinleyin

Parça B

 class DetailFragment : Fragment() {

        private val model: SharedViewModel by activityViewModels()

        override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
            super.onViewCreated(view, savedInstanceState)
            model.selected.observe(viewLifecycleOwner, Observer<Item> { item ->
                // Update the UI
            })
        }
    }

Bunu tam tersi şekilde de yapabilirsiniz


0

% 100 Çalışma Çözümü: (eğer yardım edersen, oy vermeyi unutma)

İlk Parçanıza şu kod parçasını koyun:

    editprofile.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {

                    Fragment_editprofile Fragment = new Fragment_editprofile();
.
.
.
.
.


                Fragment.getintentdetails(tv_name.getText().toString(),
                            tv_mob.getText().toString(), tv_email.getText().toString(), tv_dob.getText().toString(),
                            tv_gender.getText().toString(), photointent);

                }
            });

İkinci Fragmanda aşağıdaki gibi bir yöntem yapın:

public void getintentdetails(String name, String mobile, String email, String dob, String gender,
                                 String photointent) {

        this.name_str= name;
        this.mob_str= mobile;
        this.email_str= email;
        this.dob_str= dob;
        this.gender_str= gender;
        this.photo_str= photointent;

    }

sonra sınıf düzeyinde bir değişken tanımlayın:

String name_str, mob_str, dob_str, photo_str, email_str, gender_str;

daha sonra değeri ayarlamak için ikinci parçada başka bir yöntem yapın:

  setexistingdetails();


private void setexistingdetails() {

        if(!name_str.equalsIgnoreCase(""))
            (et_name).setText(name_str);
        if(!mob_str.equalsIgnoreCase(""))
            et_mobile.setText(mob_str);
        if(!email_str.equalsIgnoreCase(""))
            email_et.setText(email_str);
        if(!dob_str.equalsIgnoreCase(""))
            dob_et.setText(dob_str);
        if(!gender_str.equalsIgnoreCase("")){
            if (gender_str.equalsIgnoreCase("m")){
                male_radio.setChecked(true);
            }else {
                female_radio.setChecked(true);
            }
        }
        if(!photo_str.equalsIgnoreCase("")){
            try {
                Picasso.get().load(Const.BASE_PATH+"include/sub-domain/GENIUS/"+photo_str).into(adminpropic_edit);
            } catch (Exception e) {            }
        }
    }

0

Arnav Rao tarafından onaylanan ViewModel ve Live Data ile hedefinize ulaşabilirsiniz . Şimdi bunu daha düzgün bir şekilde açıklamak için bir örnek verdim.

İlk olarak, varsayılan ViewModeladlandırılır SharedViewModel.java.

public class SharedViewModel extends ViewModel {
    private final MutableLiveData<Item> selected = new MutableLiveData<Item>();

    public void select(Item item) {
        selected.setValue(item);
    }
    public LiveData<Item> getSelected() {
        return selected;
    }
}

Daha sonra kaynak parçası , MasterFragment.javabir veriyi göndermek istediğimiz yerdir.

public class MasterFragment extends Fragment {
    private SharedViewModel model;

    public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        model = new ViewModelProvider(requireActivity()).get(SharedViewModel.class);
        itemSelector.setOnClickListener(item -> {

            // Data is sent

            model.select(item);
        });
    }
}

Ve son olarak, hedef parçası , DetailFragment.javaverileri almak istediğimiz yerdir.

public class DetailFragment extends Fragment {

    public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        SharedViewModel model = new ViewModelProvider(requireActivity()).get(SharedViewModel.class);
        model.getSelected().observe(getViewLifecycleOwner(), { item ->

           // Data is received 

        });
    }
}

0

Pekala, burada bu kadar kazandıktan sonra basit bir çözüm buldum, aslında verileri hiçbir zaman parçadan bölüme aktarmamalısınız, bu her zaman kötü bir fikirdir, verileri A parçasından etkinliğe aktarabilir ve B parçasındaki etkinlikten verileri alabilirsiniz.

For Example
//fragment A
//your method that will be called in Main Activity for getting data from this fragment
public List<customDataModel> getlist(){
return mlist; //your custom list 
}
buttonopen.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            //before calling  your new fragment, send a Broadcast signal to your main activity
 mContext.sendBroadcast(new Intent("call.myfragment.action"));
//here you are now changing the fragment
Fragment fragment1 = new VolunteerListDetailsFragment();

            FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
            ft.replace(R.id.content_frame, fragment1);
            ft.commit();
        }
    });

// Ana Aktivitede

this.registerReceiver(mBroadcastReceiver, new IntentFilter("call.myfragment.action"));//this line should be in your onCreate method
   BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {

    @Override
    public void onReceive(Context context, Intent intent) {
//init the fragment A
FragmenA fragment =
                (FragmentA) getSupportFragmentManager().findFragmentById(R.id.content_frame);
        mlistdetails = fragment.getlist();//this is my method in fragmentA which is retuning me a custom list, init this list type in top of on create fragment


    }
};
//here you are creating method that is returning the list that you just recieved From fragmentA
public List<customDataModel> getcustomlist(){
return mlistdetails; //you are returning the same list that you recived from fragmentA
}

// şimdi FragmentB'de

 public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

    View rootView = (View) inflater.inflate(R.layout.vol_listdetails, container, false);

    mlistdetails=((MainActivity)getActivity()).getcustomlist();//here you are calling the method that you have created in Main Activity

    Toast.makeText(getActivity().getApplicationContext(), mlistdetails.get(0).getItemqty(), Toast.LENGTH_SHORT).show();
    return rootView;

}

-2

benim gibi yeni başlayanlar için gerçekten kolay bir şey yaptım .. activity_main.xml dosyamda bir metin görünümü yaptım ve

id=index
visibility=invisible

sonra bu metin görünümünü ilk parçadan alıyorum

index= (Textview) getActivity().findviewbyid(R.id.index)
index.setText("fill me with the value")

ve sonra ikinci parçada değeri alıyorum

index= (Textview) getActivity().findviewbyid(R.id.index)
String get_the_value= index.getText().toString();

Umarım yardımcı olur!


Cevap sorulan soruyla ilgili değil
Kanagalingam
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.