Как синхронизировать данные между фрагментами Viewpager - PullRequest
0 голосов
/ 22 февраля 2019

С помощью следующего кода я могу нажать кнопку, чтобы отправить строку из одного фрагмента (Фрагмент A) в MainActivity.Как мне извлечь строку из MainActivity и отобразить ее на фрагменте B за один раз?Я хотел бы, чтобы фрагменты действовали синхронно;чтобы Фрагмент B обновился сам, как только я нажму кнопку во Фрагменте A. Кажется, я ничего не могу найти в SO по этому вопросу.

Интерфейс:

public interface OnDataListener {
    public void onDataReceived(String data);
}

Данные фрагмента Aслушатель:

OnDataListener mOnDataListener;

@Override
public void onAttach(Context context) {
    try{
        mOnDataListener = (OnDataListener) context;
        Log.d(TAG, "onAttach was called" + context);
    }catch (ClassCastException e){
        Log.e(TAG, "onAttach: ClassCastException: " + e.getMessage() );
    }
    super.onAttach(context);
}

Логика кнопок в onCreateView фрагмента A:

button.setOnClickListener(new View.OnClickListener() {
        public void onClick(View v) {

          String newTextString = editTextView.getText().toString();
          mOnDataListener.onDataReceived(newTextString);

        }
      });

Приемник данных MainActivity

public class MainActivity extends AppCompatActivity implements OnDataListener {


@Override
public void onDataReceived(String data) {

    Log.e(TAG, "MainActivity received this string " + data );

            }
}

Ответы [ 2 ]

0 голосов
/ 22 февраля 2019

Решение 1: Использование обратных вызовов

// это будет работать, если ваш экземпляр фрагмента активен, поэтому проверьте ограничение экрана для viewpager

(Выможет также использовать решение 3, упомянутое Фаридом Хаком, которое делает то же самое, выполняя работу самого действия)

Здесь Activity реализует обратный вызов OnDataUpdateListener

interface OnDataUpdateListener{
    void passDataToFragmentB(String data)
}

Код активности:

Fragment instanceFragmentB;
// intialise it somewhere in your activity
// or get from viewpager adapter

@Override
void passDataToFragmentB(String data){
    instanceFragmentB.onDataChange(data)
}

Код фрагмента A:

OnDataUpdateListener mOnDataUpdateListener;
onAttach(Activity activity){
    mOnDataUpdateListener=  (OnDataUpdateListener) activity
}

onViewCreated(){
    somebutton.onClick{
        mOnDataUpdateListener.passDataToFragmentB("someString")
    }
}

Код фрагмента B:

onDataChange(String data){
    //do your work with update data passed from fragment A  
}

Решение 2: Использование EventBus или RxBus

// это будет работать, если ваш экземпляр фрагмента активен, поэтому проверьте ограничение offscreenpage viewpager

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

Фрагмент A:

onViewCreated(){
    somebutton.onClick{
        EventBus.post("your data")
    }
}

Фрагмент B:

@Subsribe
void onDataChange(String data){
    //do your work with update data passed from fragment A  
}

Решение 3: Использование ViewModel.

Взять модель представления с контекстомактивности во всем фрагменте и Wrap String с LiveData.

Всякий раз, когдаданные изменяются, просто публикуйте новые данные в объекте String Livedata.Все фрагменты, которые наблюдают за тем, что liveata получат обновленное значение.

0 голосов
/ 22 февраля 2019

Решение 1

В вашей основной деятельности

@Override
public void onDataReceived(String data) {
   Log.e(TAG, "MainActivity received this string " + data );
   Bundle bundle = new Bundle();
   bundle.putString("edttext", data);
   FragmentB fragment = new FragmentB();
   fragment.setArguments(bundle);
   // Fragment Transaction method goes here
}

В ваших данных FragmentB Retrieve

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
    Bundle savedInstanceState) {
   String strtext = getArguments().getString("edttext");    
   return inflater.inflate(R.layout.fragment, container, false);
}

Решение 2

Вы можете поместить данные обратного вызова в свою глобальную переменную и использовать их при транзакции фрагмента во время onClickListerner.

Решение 3

A)Создайте метод в вашем FragmentB

public void changeText (String data) {
   textview.setText(data)
 }

B) и передайте значение из MainActivity

@Override
public void onDataReceived (String data) {
    myInterface.CallBack("Callbacked when onCreate method Created" + data);
    Log.d("Tiggered", "respond: ");
    FragmentManager manager = getFragmentManager();
    FragmentB fragmentB = (FragmentB) manager.findFragmentById(R.id.id_fragmentB);
    fragmentB.changeText(data);
}
...