Як передавати значення між фрагментами


109

Я досить новачок у використанні фрагментів.

Я просто намагаюся створити просту програму для зразків, яка використовує фрагменти. Мій сценарій: у мене є дві дії з одним фрагментом всередині кожної діяльності. Перший фрагмент має редакційний текст та кнопку. Другий фрагмент має перегляд тексту. Коли я ввожу ім’я в редакційному тексті і натискаю кнопку, перегляд тексту у другому фрагменті повинен відображати ім’я, введене у редакційному тексті першого фрагмента.

Я зміг надіслати значення від першого фрагмента до його активності, а потім від цієї діяльності до другої діяльності. Тепер як я використовую це значення всередині другого фрагмента.

Ось код 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);
    }
}

Фрагмент_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);
    }

}

Я отримую таке виняток :::

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 до Fragment_2.Java?


Виділіть, будь ласка, ту частину, де у вас
виникають

робоче рішення з легким способом: stackoverflow.com/a/59332751/10201722
Аділ Сиддікі

Відповіді:


203

крок 1. для надсилання даних від фрагмента до активності

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

крок 2.до отримання цих даних у розділі Діяльність:

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

крок 3 . для передачі даних від діяльності до іншої діяльності дотримуйтесь звичайного підходу

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

крок 4 для отримання цих даних у дії

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

Крок 5. З Діяльності ви можете надсилати дані до Фрагменту з наміром як:

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

і отримувати фрагмент у методі Fragment onCreateView:

@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, що я викликаю списності з фрагмента і після вибору елемента з цієї діяльності, я хочу повернутися у фрагмент із вибраним ім'ям файлу. Але він не працює, він дає мені виняток Nullpointer в onCreateView. Будь-яке рішення з цього питання, будь ласка? Це моє запитання stackoverflow.com/questions/18208771 / ...
OnkarDhane

як тут поставити POJO? bundle.putString("message", "From Activity");
jeet.chanchawat

31
Хтось огидує, наскільки змушений робити щось подібне
Ед Лі

1
Точно Едді, це не правильний шлях. Вони повинні використовувати інтерфейси для зв'язку між фрагментами через активність контейнера.
Kaveesh Kanwal

Що стосується використання інтерфейсів для спілкування між фрагментами: developer.android.com/training/basics/fragments/…
Andre L Torres,

49

Як зазначається на сайті розробника

Часто вам потрібно, щоб один фрагмент спілкувався з іншим, наприклад, щоб змінити вміст на основі події користувача. Весь зв'язок між фрагментами здійснюється через пов'язану діяльність. Два фрагменти ніколи не повинні спілкуватися безпосередньо.

зв’язок між фрагментами повинен здійснюватися через пов’язану діяльність.

Будемо мати такі компоненти:

Активність розміщує фрагменти та дозволяє комунікації

FragmentПерший фрагмент, який буде надсилати дані

FragmentB другий фрагмент, який буде отримувати дані від FragmentA

Реалізація FragmentA:

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:

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:

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

Я сподіваюся, що це допоможе ..


4
Що тут OnImageClickListener? і як це передано змінній DataPassListener?
Харша

Я виявив, що це "DataPassListener". Я змусив його працювати, але лише знаходити завдяки кожному натисканню кнопки дані надсилаються. Коли він надсилається, він замінює фрагмент. Що означає, що список щоразу поновлюється. Тому не зберігаючи перелік елементів у пам’яті.
Wesley франки

44

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

// У Fragment_2.java

Bundle bundle = this.getArguments();

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

Сподіваюся, це допоможе тобі.


1
Чиста відповідь, щоб показати основний пункт. використання putString(або putInt) - це відповідь!
Мехді Дехгані

22

З веб-сайту розробників :

Часто вам потрібно, щоб один фрагмент спілкувався з іншим, наприклад, щоб змінити вміст на основі події користувача. Весь зв'язок між фрагментами здійснюється через пов'язану діяльність. Два фрагменти ніколи не повинні спілкуватися безпосередньо.

Ви можете спілкуватися між фрагментами за допомогою його діяльності. Ви можете спілкуватися між активністю та фрагментом, використовуючи такий підхід.

Перевірте також це посилання.


Друге посилання, яке ви надали, показує, як спілкуватися між фрагментами, коли вони перебувають в одній діяльності. Як я можу спілкуватися, коли обидва займаються різними видами діяльності?
Vamsi Challa

5

По-перше, всі відповіді вірні, ви можете передавати дані, крім спеціальних об'єктів, використовуючи Intent. Якщо ви хочете передати користувацькі об’єкти, вам доведеться реалізувати SerialazableабоParcelable до власного класу об'єктів. Я думав, що це занадто складно ...

Тож якщо ваш проект простий, спробуйте використовувати DataCache. Це забезпечує надзвичайно простий спосіб передачі даних. Ref: проект Github CachePot

1- Встановіть це на Перегляд або Діяльність або Фрагмент, який надсилатиме дані

DataCache.getInstance().push(obj);

2- Отримуйте дані де завгодно, як нижче

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

Чи не було б простіше використовувати додатковий клас зі статичними значеннями всередині? Потім ці значення можуть бути доступні обома фрагментами, тому не потрібно використовувати додаткову бібліотеку для кешування спеціальних об'єктів.
Неф

4

Останнє рішення для передачі даних між фрагментами може бути реалізовано за допомогою андроїдних архітектурних компонентів, таких як ViewModel та LiveData. За допомогою цього рішення вам не потрібно визначати інтерфейс для спілкування і ви можете отримати переваги використання перегляду даних, подібних до перегляду даних, через зміни конфігурації.

У цьому рішенні фрагменти, що беруть участь у спілкуванні, поділяють той самий об'єкт перегляду, який пов'язаний із життєвим циклом їх діяльності. Об'єкт моделі перегляду містить об'єкт живих даних. Один фрагмент встановлює дані, що передаються на об’єкт livedata, а другий фрагмент даних про зміни спостерігачів спостерігачів спостерігачів.

Ось повний приклад http://www.zoftino.com/passing-data-between-android-fragments-using-viewmodel


3

Передача аргументів між фрагментами. Відповісти на це питання досить пізно, але це могло б допомогти комусь! 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();

Тоді у вашому випадку Fragment_2.javaви можете отримати параметри, як правило, у межах свого onActivityCreated напр

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

3

Я думаю, що хороший спосіб вирішити цю проблему - використовувати користувальницький інтерфейс.

Скажімо, у вас є два фрагменти (A і B), які знаходяться в одній і тій же діяльності, і ви хочете надсилати дані від A до B.

Інтерфейс:

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

Діяльність:

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

Фрагмент А:

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

Фрагмент 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

Спілкування між фрагментами є досить складним (мені здається, що концепція слухачів є дещо складною для реалізації).

Для абстрагування цих повідомлень звичайно використовувати "Шину подій". Це третя сторона бібліотека, яка бере на себе цю комунікацію.

"Отто" - це те, що часто використовується для цього, і, можливо, варто переглянути: http://square.github.io/otto/


2

Передача даних з фрагмента в інший фрагмент

  • З першого фрагменту

    // 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(); 
  • На другому фрагменті

    @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

Ця проста реалізація допомагає простим способом передавати дані між фрагментами. Подумайте, що ви хочете передати дані з "Frgment1" до "Fragment2"

У Fragment1 (Встановлення даних для надсилання)

 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 (Отримати параметри)

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

У своєму додатку я намагаюся зробити це робочим, але якимось чином, хоча значення передається, воно не відображається на fragment2, я думаю, що я помиляюсь у налаштуванні R.id.content_drawer. Хтось може мені керувати, що може бути правильним ідентифікатором для R.id.content_drawer з прикладом .xml.
сокіл

1

Котлін шлях

Використовуйте SharedViewModelзапропоновану в офіційній документації ViewModel

Дуже часто зустрічається, що два чи більше фрагментів у діяльності потребують спілкування один з одним. Уявіть звичайний випадок фрагментів основної деталізації, де у вас є фрагмент, у якому користувач вибирає елемент зі списку та інший фрагмент, який відображає вміст обраного елемента. Цей випадок ніколи не є тривіальним, оскільки обом фрагментам потрібно визначити деякий опис інтерфейсу, а діяльність власника повинна зв’язати їх два разом. Крім того, обидва фрагменти повинні обробляти сценарій, коли інший фрагмент ще не створений або видимий.

Цю загальну больову точку можна усунути за допомогою об’єктів ViewModel. Ці фрагменти можуть спільно використовувати ViewModel, використовуючи сферу їх діяльності для обробки цього спілкування

Спочатку застосуйте fragment-ktx, щоб інстанціювати свій модельний вигляд простіше

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

Потім вам просто потрібно помістити всередину viewmodel ті дані, якими ви будете ділитися з іншим фрагментом

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

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

Потім, щоб закінчити, просто інстанціюйте viewModel у кожному фрагменті та встановіть значення selected фрагмента, для якого потрібно встановити дані

Фрагмент А

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

    }
}

А потім просто прослухайте це значення у пункті призначення "Фрагмент"

Фрагмент В

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

Ви також можете зробити це протилежно


0

100% робоче рішення: (якщо вам допоможуть, то не забудьте звернутись до нагороди)

У свій перший фрагмент покладіть цей фрагмент коду:

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

                }
            });

У другому фрагменті зробіть метод, як показано нижче:

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;

    }

потім визначте змінну на рівні класу:

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

потім зробіть інший метод у другому фрагменті, щоб встановити значення:

  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

Ви можете досягти своєї мети за допомогою ViewModel та Live Data, які очищаються Арнавом Рао . Тепер я ставлю приклад, щоб це акуратніше очистити.

По-перше, припущена ViewModelназвана 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;
    }
}

Тоді фрагмент джерела - це місце, MasterFragment.javaзвідки ми хочемо надіслати дані.

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

І нарешті фрагмент пункту призначення - це те, DetailFragment.javaкуди ми хочемо отримати дані.

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

Гаразд після стількох копань тут я знайшов просте рішення, насправді ніколи не слід передавати дані з фрагмента в фрагмент, його завжди погана ідея, ви можете передавати дані з фрагмента А в активність і отримувати дані від активності на фрагменті В.

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

// в Основній діяльності

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
}

// тепер у 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;

}

-2

Я зробив щось дуже легко для початківців, як я .. Я зробив перегляд тексту в своїй діяльності_main.xml і поставив

id=index
visibility=invisible

то я отримую це перегляд тексту з першого фрагмента

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

а потім у другому фрагменті я отримую значення

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

сподіваюся, що це допоможе!


Відповідь не пов’язана з поставленим запитанням
Kanagalingam
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.