Вызов Fragment2 для результата из Fragment1 - PullRequest
0 голосов
/ 21 сентября 2018

У меня есть базовое действие, в котором у меня есть 2 фрагмента (скажем, Fragment1 & Fragment2). Мне нужно вызвать Fragment2 из Fragment1 для сбора данных, а затем использовать его во Fragment1.

Я знаю этот вызовActivity для результата можно получить внутри onActivityResult baseActivity, но как я буду вызывать Fragment2 из Fragment1 для цели результата?

Ответы [ 3 ]

0 голосов
/ 21 сентября 2018

Без MVVM

Самым простым способом, который я предполагаю, является использование Fragment.setTargetFragment(@Nullable Fragment fragment, int requestCode)

из фрагмента 1:

val fragment = Fragment2.newInstane()
fragment.setTargetFragment(this, 10)

из фрагмента2, когда вы хотите получить результат обратно к фрагменту 1:

fun setResultBack(){
    val intent = Intent()
    // inject anything to intent here
    getTargetFragment().onActivityResult(10, Activity.RESULT_OK, intent)
    fragmentManager.popBackStack()
}

наконец переопределить onActivityResult из фрагмента 1:

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
    if(requestCode == 10){
        // handle result here
    } 
    else super.onActivityResult(requestCode, resultCode, data)
}

И это работает во всех случаях, даже после восстановления состояния фрагмента или послеизменение конфигурации.

с MVVM

Использование модели общего представления в соответствии с рекомендациями документации

0 голосов
/ 21 сентября 2018

Я бы порекомендовал взглянуть на эту тесную связь и рефакторинг, чтобы фрагменты не были так тесно связаны, а выборка данных аналогичным образом отделена.Взгляните на различные ресурсы в MVP, MVC или MVVP для этой концепции.

Иногда, тем не менее, вам нужно передать информацию одного фрагмента другому.Типичный / рекомендуемый способ сделать это - определить интерфейс «фрагмента обратного вызова», который требуется вашим фрагментам, и этот интерфейс реализуется вашим Activity.Таким образом, Activity является средой для связи (которая помогает отделить фрагменты.) Вы можете использовать собственный базовый класс для своих фрагментов, чтобы у них было общее определение интерфейса.

public class MyBaseFragment extends Fragment {
    public interface FragmentCallbacks {
        //  Use whatever arguments you may require here
        void fetchData();
    }

    protected FragmentCallbacks  mCallbacks;

    @Override
    void onAttach(Context context) {
        try {
            mCallbacks = (FragmentCallbacks)context;
        } catch (ClassCastException e) {
            throw new RuntimeException("Activity must implement FragmentCallbacks");
        }
    }
}

Теперь вFragment1 вы можете вызвать mCallbacks.fetchData(), который Activity может использовать для вызова открытого метода, который вы создаете в Fragment2.Когда он получает данные обратно (возможно, асинхронно), он может затем предоставить их Fragment1 с помощью открытого метода, который вы создаете.

0 голосов
/ 21 сентября 2018

Я думаю, вы получите подсказку из этого решения.Потому что я не могу написать код для вашего требования, но это даст вам представление о том, что вы можете сделать.

public class Fragment1 extends android.support.v4.app.Fragment {
    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        if (context instanceof ActivityHome) {
            ((ActivityHome) context).setFragment1(this);
        }
    }
}

public class ActivityHome extends AppCompatActivity {
    Fragment1 fragment1;

    public void setFragment1(Fragment1 fragment1) {
        this.fragment1 = fragment1;
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (fragment1 != null) fragment1.onActivityResult(requestCode, resultCode, data);
    }
}

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

(1) Создание класса данных

public static class MessageEvent { /* Additional fields if needed */ }

(2) Подписаться на событие

@Subscribe(threadMode = ThreadMode.MAIN)  
public void onMessageEvent(MessageEvent event) {/* Do something */};

(3) Регистрация и отмена регистрации

 @Override
 public void onStart() {
     super.onStart();
     EventBus.getDefault().register(this);
 }

 @Override
 public void onStop() {
     super.onStop();
     EventBus.getDefault().unregister(this);
 }

и запуск из любого места

 EventBus.getDefault().post(new MessageEvent());
...