Cara meneruskan nilai di antara Fragmen

109

Saya cukup baru menggunakan Fragmen.

Saya hanya mencoba membuat aplikasi sampel sederhana yang menggunakan Fragmen. Skenario saya adalah, saya memiliki dua aktivitas dengan satu fragmen di dalam setiap aktivitas. Fragmen pertama memiliki teks edit dan tombol. Fragmen kedua memiliki textview. Ketika saya memasukkan nama di edittext dan mengklik tombolnya, textview di fragmen kedua harus menampilkan nama yang dimasukkan di edittext dari fragmen pertama.

Saya bisa mengirim nilai dari fragmen pertama ke aktivitasnya dan kemudian dari aktivitas itu ke aktivitas kedua. Sekarang bagaimana cara menggunakan nilai ini di dalam fragmen kedua.

Berikut adalah kode Java :::

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

}

Saya mendapatkan pengecualian berikut :::

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

Bagaimana cara mendapatkan nilai dari bundel di SecondActivity.java ke Fragment_2.Java?

Vamsi Challa
sumber
Harap soroti bagian di mana Anda mendapatkan masalah
Nikhil Agrawal
solusi bekerja dengan cara mudah: stackoverflow.com/a/59332751/10201722
Adil Siddiqui

Jawaban:

203

langkah 1. untuk mengirim data dari fragmen ke aktivitas

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

langkah 2. untuk menerima data ini dalam Aktivitas:

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

langkah 3 . untuk mengirim data dari aktivitas ke aktivitas lain ikuti pendekatan normal

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

langkah 4 untuk menerima data ini dalam aktivitas

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

Langkah 5. Dari Aktivitas Anda bisa mengirim data ke Fragment dengan maksud sebagai:

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

dan untuk menerima dalam fragmen dalam metode onCreateView Fragment:

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

    return inflater.inflate(R.layout.fragment, container, false);
    }
Pisau
sumber
2
Saya mencoba langkah 5, Bahwa saya memanggil listactivity dari fragmen dan setelah memilih item dari aktivitas itu, saya ingin kembali dalam fragmen dengan nama file yang dipilih. Tetapi tidak berfungsi, ini memberi saya Pengecualian Nullpointer di onCreateView. Ada solusi tentang ini, tolong? Ini adalah pertanyaan saya stackoverflow.com/questions/18208771/…
OnkarDhane
bagaimana cara meletakkan POJO di sini? bundle.putString("message", "From Activity");
jeet.chanchawat
31
Adakah yang muak dengan betapa berbelit-belitnya melakukan sesuatu seperti ini
Ed Lee
1
Tepatnya Eddie, ini bukanlah cara yang benar. Mereka harus menggunakan antarmuka untuk berkomunikasi antar fragmen melalui aktivitas penampung.
Kaveesh Kanwal
Mengenai penggunaan antarmuka untuk berkomunikasi antar fragmen: developer.android.com/training/basics/fragments/…
Andre L Torres
49

Sebagaimana dicatat di situs pengembang

Seringkali Anda ingin satu Fragmen berkomunikasi dengan yang lain, misalnya untuk mengubah konten berdasarkan peristiwa pengguna. Semua komunikasi Fragmen ke Fragmen dilakukan melalui Aktivitas terkait. Dua Fragmen tidak boleh berkomunikasi secara langsung.

komunikasi antar fragmen harus dilakukan melalui Aktivitas terkait.

Mari kita memiliki komponen berikut:

Suatu aktivitas menghosting fragmen dan memungkinkan komunikasi fragmen

Fragment: Fragmen pertama yang akan mengirimkan data

FragmentB kedua fragment yang akan menerima data dari FragmentA

Implementasi FragmentA adalah:

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

Implementasi MainActivity adalah:

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

Implementasi FragmentB adalah:

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

Saya harap ini akan membantu ..

ozhanli.dll
sumber
4
Apa OnImageClickListener di sini? dan bagaimana cara mentransmisikannya ke variabel DataPassListener?
Harsha
Saya menemukan itu adalah "DataPassListener". Saya membuatnya berfungsi, tetapi hanya untuk menemukan karena setiap kali tombol diklik data dikirim. Ketika dikirim, itu menggantikan fragmen. Artinya daftar tersebut diperbarui setiap saat. Oleh karena itu, tidak menyimpan daftar item dalam memori.
wesley franks
44

// Dalam Fragment_1.java

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();

// Dalam Fragment_2.java

Bundle bundle = this.getArguments();

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

Semoga ini membantu Anda.

nguyencse
sumber
1
Jawaban bersih untuk menunjukkan poin utama. menggunakan putString(atau putInt) adalah jawabannya!
Mehdi Dehghani
22

Dari situs web Pengembang :

Seringkali Anda ingin satu Fragmen berkomunikasi dengan yang lain, misalnya untuk mengubah konten berdasarkan peristiwa pengguna. Semua komunikasi Fragmen ke Fragmen dilakukan melalui Aktivitas terkait. Dua Fragmen tidak boleh berkomunikasi secara langsung.

Anda dapat berkomunikasi di antara fragmen dengan bantuan Activity-nya. Anda dapat berkomunikasi di antara aktivitas dan fragmen menggunakan pendekatan ini .

Silakan periksa juga tautan ini .

Jainendra
sumber
Tautan kedua yang telah Anda berikan, menunjukkan cara berkomunikasi antar fragmen ketika mereka berada dalam aktivitas yang sama. Bagaimana cara saya berkomunikasi saat keduanya berada dalam aktivitas yang berbeda?
Vamsi Challa
5

Pertama semua jawaban benar, Anda dapat mengirimkan data kecuali objek kustom dengan menggunakan Intent. Jika Anda ingin meneruskan objek kustom, Anda harus mengimplementasikan Serialazableatau Parcelableke kelas objek kustom Anda. Saya pikir itu terlalu rumit ...

Jadi jika proyek Anda sederhana, coba gunakan DataCache. Itu memberikan cara yang sangat sederhana untuk meneruskan data. Ref: proyek Github CachePot

1- Setel ini ke View atau Activity atau Fragment yang akan mengirim data

DataCache.getInstance().push(obj);

2- Dapatkan data di mana saja seperti di bawah ini

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
kimkevin
sumber
Bukankah lebih mudah menggunakan kelas ekstra dengan nilai statis di dalamnya? Nilai ini kemudian dapat diakses oleh kedua fragmen, jadi tidak perlu menggunakan pustaka tambahan untuk menyimpan objek khusus ke dalam cache.
Nef
4

Solusi terbaru untuk meneruskan data antar fragmen dapat diimplementasikan dengan menggunakan komponen arsitektur android seperti ViewModel dan LiveData. Dengan solusi ini, Anda tidak perlu menentukan antarmuka untuk komunikasi dan bisa mendapatkan keuntungan menggunakan viewmodel seperti kelangsungan data karena perubahan konfigurasi.

Dalam solusi ini, fragmen yang terlibat dalam komunikasi berbagi objek viewmodel yang sama yang terkait dengan daur hidup aktivitasnya. Objek model tampilan berisi objek Liveata. Satu fragmen menyetel data untuk diteruskan pada objek Liveata dan fragmen kedua, pengamat, liveata, mengubah dan menerima data.

Berikut adalah contoh lengkapnya http://www.zoftino.com/passing-data-between-android-fragments-using-viewmodel

Arnav Rao
sumber
3

Meneruskan argumen antar fragmen. Ini agak terlambat untuk menjawab pertanyaan ini tetapi ini bisa membantu seseorang! 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();

Kemudian di Anda, Fragment_2.javaAnda bisa mendapatkan paramaters secara normal dalam onActivityCreated misalnya Anda

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

Saya pikir cara yang baik untuk mengatasi masalah ini adalah dengan menggunakan antarmuka khusus.

Katakanlah Anda memiliki dua fragmen (A dan B) yang berada di dalam aktivitas yang sama dan Anda ingin mengirim data dari A ke B.

Antarmuka:

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

Aktivitas:

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

Fragmen A:

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

Fragmen 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
            }
        });
    }
}
simpleApps
sumber
2

Berkomunikasi antar fragmen cukup rumit (menurut saya konsep pendengar agak menantang untuk diterapkan).

Biasanya menggunakan 'Bus Acara "untuk mengabstraksi komunikasi ini. Ini adalah perpustakaan pihak ketiga yang menangani komunikasi ini untuk Anda.

'Otto' adalah salah satu yang sering digunakan untuk melakukan ini, dan mungkin layak untuk dilihat: http://square.github.io/otto/

Booger
sumber
2

Meneruskan data dari Fragmen ke Fragmen lain

  • Dari Fragmen pertama

    // 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(); 
  • Pada Fragmen Kedua

    @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
         } 
    }
Spirit Solusi
sumber
1

Implementasi sederhana ini membantu meneruskan data antar fragmen dengan cara yang sederhana. Pikirkan Anda ingin meneruskan data dari 'Frgment1' ke 'Fragment2'

Di Fragment1 (Setel data untuk dikirim)

 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();

Dalam metode onCreateView Fragment2 (Dapatkan parameter)

String value = this.getArguments().getString("key");//get your parameters
Toast.makeText(getActivity(), value+" ", Toast.LENGTH_LONG).show();//show data in tost
Janaka
sumber
Di aplikasi saya, saya mencoba untuk membuatnya berfungsi tetapi entah bagaimana meskipun nilai yang diteruskan tidak ditampilkan di fragment2, saya pikir saya membuat kesalahan dalam menyetel R.id.content_drawer. Adakah yang bisa memandu saya apa yang bisa menjadi pengenal yang tepat untuk R.id.content_drawer dengan contoh .xml.
elang
1

Cara Kotlin

Gunakan yang SharedViewModeldiusulkan di dokumentasi ViewModel resmi

Sangat umum bahwa dua atau lebih fragmen dalam suatu aktivitas perlu berkomunikasi satu sama lain. Bayangkan kasus umum fragmen detail master, di mana Anda memiliki fragmen di mana pengguna memilih item dari daftar dan fragmen lain yang menampilkan konten item yang dipilih. Kasus ini tidak pernah sepele karena kedua fragmen perlu mendefinisikan beberapa deskripsi antarmuka, dan aktivitas pemilik harus mengikat keduanya. Selain itu, kedua fragmen harus menangani skenario di mana fragmen lain belum dibuat atau terlihat.

Masalah umum ini dapat diatasi dengan menggunakan objek ViewModel. Fragmen ini dapat berbagi ViewModel menggunakan cakupan aktivitasnya untuk menangani komunikasi ini

Pertama-tama terapkan fragment-ktx untuk membuat instance viewmodel Anda dengan lebih mudah

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

Kemudian, Anda hanya perlu memasukkan ke dalam viewmodel data yang akan Anda bagikan dengan fragmen lain

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

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

Kemudian, untuk menyelesaikannya, cukup buat instance viewModel Anda di setiap fragmen, dan setel nilai dari selectedfragmen yang ingin Anda setel datanya

Fragmen 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)
      }

    }
}

Dan kemudian, dengarkan saja nilai ini di tujuan Fragmen Anda

Fragmen 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
            })
        }
    }

Anda juga bisa melakukannya dengan cara yang berlawanan

Gastón Saillén
sumber
0

Solusi Kerja 100%: (jika membantu Anda maka jangan lupa untuk menekan upvote)

Di Fragmen Pertama Anda, masukkan kode ini:

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

                }
            });

Di Second Fragment, buat metode seperti di bawah ini:

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;

    }

lalu tentukan variabel di tingkat kelas:

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

lalu buat metode lain di fragmen kedua untuk menyetel nilai:

  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) {            }
        }
    }
Adil Siddiqui
sumber
0

Anda dapat mencapai tujuan Anda dengan ViewModel dan Live Data yang diselesaikan oleh Arnav Rao . Sekarang saya beri contoh agar lebih rapi.

Pertama, diasumsikan ViewModelbernama 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;
    }
}

Kemudian fragmen sumber adalah MasterFragment.javadari mana kita ingin mengirim data.

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

Dan akhirnya bagian tujuan adalah DetailFragment.javake tempat kami ingin menerima data.

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 

        });
    }
}
Gk Mohammad Emon
sumber
0

Oke setelah begitu banyak penggalian di sini saya menemukan solusi sederhana, sebenarnya Anda tidak boleh meneruskan data dari fragmen ke fragmen itu selalu ide yang buruk, Anda bisa meneruskan data dari fragmen A ke aktivitas dan mendapatkan data dari aktivitas di fragmen B.

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

// di Aktivitas Utama

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
}

// sekarang di FragmentB

 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;

}
Mubashir Murtaza
sumber
-2

Saya telah membuat sesuatu yang sangat mudah untuk pemula seperti saya .. saya membuat tampilan teks di activity_main.xml saya dan meletakkan

id=index
visibility=invisible

lalu saya mendapatkan textview ini dari fragmen pertama

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

dan kemudian di fragmen kedua saya mendapatkan nilainya

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

semoga membantu!

pengguna7933515
sumber
Jawaban tidak terkait dengan pertanyaan yang telah diajukan
Kanagalingam