Как передавать значения между фрагментами

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

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

}

Я получаю следующее исключение :::

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?

Вамси Чалла
источник
Пожалуйста, выделите ту часть, где возникла проблема с ru
Нихил Агравал
рабочее решение простым способом: stackoverflow.com/a/59332751/10201722
Адиль Сиддики

Ответы:

203

Шаг 1. отправить данные из фрагмента в действие

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

шаг 2. чтобы получить эти данные в Activity:

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. Из Activity вы можете отправлять данные в Fragment с целью:

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: я вызываю listactivity из фрагмента, и после выбора элемента из этого действия я хочу вернуться во фрагменте с выбранным именем файла. Но он не работает, он дает мне исключение Nullpointer в onCreateView. Любое решение по этому поводу, пожалуйста? Это мой вопрос stackoverflow.com/questions/18208771/…
OnkarDhane
как мне разместить здесь POJO? bundle.putString("message", "From Activity");
jeet.chanchawat
31
Кому-нибудь противно, насколько запутанно делать что-то подобное,
Эд Ли
1
Совершенно верно, Эдди, это неправильный путь. Они должны использовать интерфейсы для связи между фрагментами посредством активности контейнера.
Кавиш Канвал 08
Относительно использования интерфейсов для связи между фрагментами: developer.android.com/training/basics/fragments/…
Андре Торрес
49

Как отмечено на сайте разработчика

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

связь между фрагментами должна осуществляться через связанное действие.

У нас есть следующие компоненты:

Действие содержит фрагменты и позволяет фрагментам общаться

Фрагмент - первый фрагмент, который отправит данные.

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?
Harsha
Я обнаружил, что это "DataPassListener". Я заставил его работать, но только чтобы найти, потому что каждый раз, когда нажимается кнопка, данные отправляются. При отправке заменяет фрагмент. Это означает, что список обновляется каждый раз. Поэтому не хранить список предметов в памяти.
Уэсли Фрэнкс
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.
}

Надеюсь, это поможет вам.

Nguyencse
источник
1
Четкий ответ, чтобы показать основную мысль. использование putString(или putInt) - это ответ!
Мехди Дехгани
22

С веб-сайта разработчиков :

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

Вы можете общаться между фрагментами с помощью его Activity. Используя этот подход, вы можете общаться между активностью и фрагментом .

Пожалуйста, проверьте также эту ссылку.

Джайнендра
источник
Вторая ссылка, которую вы указали, показывает, как взаимодействовать между фрагментами, когда они находятся в одном действии. Как мне общаться, когда оба занимаются разными делами?
Вамси Чалла
5

Во-первых, все ответы верны, вы можете передавать данные, кроме настраиваемых объектов, используя Intent. Если вы хотите передать настраиваемые объекты, вам необходимо реализовать Serialazableили Parcelableв свой класс настраиваемых объектов. Я думал, что это слишком сложно ...

Так что если ваш проект простой, попробуйте использовать DataCache. Это обеспечивает очень простой способ передачи данных. Ссылка: проект Github CachePot

1- Установите для этого параметра View или Activity или Fragment, который будет отправлять данные

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
kimkevin
источник
Не было бы проще использовать дополнительный класс со статическими значениями внутри? Затем эти значения могут быть доступны для обоих фрагментов, поэтому нет необходимости использовать дополнительную библиотеку для кэширования настраиваемых объектов.
Неф
4

Последнее решение для передачи данных между фрагментами может быть реализовано с использованием архитектурных компонентов Android, таких как ViewModel и LiveData. С помощью этого решения вам не нужно определять интерфейс для связи и вы можете получить преимущества использования модели просмотра, такие как сохранение данных, из-за изменений конфигурации.

В этом решении участвующие в коммуникации фрагменты используют один и тот же объект модели представления, который привязан к их жизненному циклу активности. Объект модели представления содержит объект Liveata. Один фрагмент устанавливает данные, которые должны быть переданы объекту liveata, а второй фрагмент обозреватель изменяет данные, и получает данные.

Вот полный пример 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"

Во фрагменте1 (установить данные для отправки)

 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
Janaka
источник
В моем приложении я пытаюсь заставить это работать, но каким-то образом, хотя значение передается, оно не отображается на фрагменте 2, я думаю, что делаю ошибку при установке R.id.content_drawer. Может ли кто-нибудь подсказать мне, какой может быть правильный идентификатор для R.id.content_drawer с примером .xml.
сокол
1

Котлин путь

Используйте SharedViewModelпредложенный в официальной документации ViewModel

Очень часто два или более фрагмента в действии должны взаимодействовать друг с другом. Представьте себе типичный случай фрагментов «мастер-деталь», когда у вас есть фрагмент, в котором пользователь выбирает элемент из списка, и другой фрагмент, отображающий содержимое выбранного элемента. Этот случай никогда не бывает тривиальным, поскольку оба фрагмента должны определять некоторое описание интерфейса, а действие владельца должно связывать их вместе. Кроме того, оба фрагмента должны обрабатывать сценарий, в котором другой фрагмент еще не создан или не виден.

Эту распространенную проблему можно решить с помощью объектов ViewModel. Эти фрагменты могут совместно использовать ViewModel, используя свою область действия для обработки этого взаимодействия.

Сначала реализуйте фрагмент-ktx, чтобы упростить создание вашей модели просмотра.

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

Затем вам просто нужно поместить в модель представления данные, которыми вы будете делиться с другим фрагментом.

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

    }
}

А затем просто слушайте это значение в месте назначения фрагмента

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

Вы также можете сделать это наоборот

Gastón Saillén
источник
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

Хорошо, после стольких копаний здесь я нашел простое решение, на самом деле вы никогда не должны передавать данные из фрагмента в фрагмент, это всегда плохая идея, вы можете передавать данные из фрагмента A в действие и получать данные из активности во фрагменте 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();
        }
    });

// в основной деятельности

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

я сделал кое-что действительно легкое для новичков вроде меня ... я сделал текстовое представление в моем activity_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();

Надеюсь, поможет!

user7933515
источник
Ответ не имеет отношения к
заданному