0

У меня есть Activity1 с TabLayout из двух фрагментов (каждый из них с презентатором). Как только я нажимаю кнопку на Панели инструментов, запускается новый Activity2 (с startActivityWithResults), который содержит простой список. При выборе одного из элементов в списке Activity2 возвращает выбранную строку в предыдущий Activity1 (тот, который имеет TabLayout).Оператор активности обновит фрагменты tablayout

Теперь, когда функция onActivityResult вызывается в Activity1, она вызовет API (с использованием презентатора), который получит новые результаты, а затем он должен обновить два фрагмента в TabLayout. Я собираюсь сделать это с RxJava, но я не знаю, с чего начать.

Activity1:

public class Activity1 extends BaseActivity { 

@Inject 
Actvity1Presenter mPresenter; 

public static Intent newIntent(Context packageContext) { 
    return new Intent(packageContext, Activity1.class); 
} 

@LayoutRes 
protected int getLayoutRedIs() { 
    return R.layout.app_bar_activity1; 
} 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(getLayoutRedIs()); 

    FwApplication.component(this).inject(this); 

    mPresenter.attachView(this); 

    Toolbar tb = (Toolbar) findViewById(R.id.toolbar_chips); 
    setSupportActionBar(tb); 
    getSupportActionBar().setDisplayHomeAsUpEnabled(true); 
    getSupportActionBar().setHomeAsUpIndicator(R.drawable.ic_back_arrow); 

    mTabLayout = (TabLayout) findViewById(R.id.tab_layout); 
    mTabLayout.addTab(mTabLayout.newTab().setText("TAB1")); 
    mTabLayout.addTab(mTabLayout.newTab().setText("TAB2")); 
    mTabLayout.setTabGravity(TabLayout.GRAVITY_FILL); 

    mViewPager = (ViewPager) findViewById(R.id.viewpager); 
    mViewPager.setAdapter(new PagerAdapter(getSupportFragmentManager(), 
      mTabLayout.getTabCount())); 
    mViewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(mTabLayout)); 
    mTabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() { 
     @Override 
     public void onTabSelected(TabLayout.Tab tab) { 
      mViewPager.setCurrentItem(tab.getPosition()); 
     } 

     @Override 
     public void onTabUnselected(TabLayout.Tab tab) { 

     } 

     @Override 
     public void onTabReselected(TabLayout.Tab tab) { 

     } 
    }); 
} 

@Override 
protected void onActivityResult(int requestCode, int resultCode, Intent data) { 
    if (requestCode == PICK_ITEM_CODE) { 
     if (resultCode == RESULT_OK) { 
      mPresenter.updateResults(data); 
     } 

     if (resultCode == RESULT_CANCELED) { 

     } 
    } 
} 

И пейджера:

public class PagerAdapter extends FragmentPagerAdapter { 

int mNumOfTabs; 

public PagerAdapter(FragmentManager fm, int NumOfTabs) { 
    super(fm); 
    this.mNumOfTabs = NumOfTabs; 
} 

@Override 
public Fragment getItem(int position) { 
    switch (position) { 
     case 0: 
     return Fragment1.newInstance(); 
     break; 
     case 1: 
     return Fragment2.newInstance(); 
     break; 
    } 
} 

@Override 
public int getCount() { 
    return mNumOfTabs; 
} 
} 

EDIT

ActivityPresenter:

public class ActivityPresenter implements Presenter<ActivityView>, 
    Interactor.OnFinishedListener<Response> { 

private static final String TAG = "FW.ActivityPresenter"; 

@Inject 
QueryPreferences mQueryPreferences; 

private Interactor mInteractor; 
private ActivityView mView; 
private NetworkService mNetworkService; 
private boolean mUseCache; 
private String mQuery; 
private int mPage; 

private PublishSubject<Response> mPublishSubject = PublishSubject.create(); 

Observable<Response> getObservableResults() { 
    return mPublishSubject; 
} 

@Inject 
public ActivityPresenter(NetworkService networkService) { 
    mNetworkService = networkService; 
    mInteractor = new InteractorImpl(mNetworkService); 
} 

public void onSearchQueryListener(String query, int page) { 
    mQuery = mQueryPreferences.getStoredQuery(); 
    mUseCache = query.equals(mQuery); 

    if (!mUseCache) { 
     mQueryPreferences.setStoredQuery(query); 
     Log.d(TAG, "Query added to cache: " + query); 
    } 

    mPage = page; 
    mInteractor.loadResults(this, query, false, page); 
} 

@Override 
public void onFinished(Response response) { 
    if (mView != null) { 
     mPublishSubject.onNext(response); 
    } 
} 

@Override 
public void onError(Throwable throwable) { 
    if (mView != null) { 
     mView.showMessage(throwable.getMessage()); 
    } 
} 

@Override 
public void attachView(ActivityView mvpView) { 
    mView = mvpView; 
} 

@Override 
public void detachView() { 
    mView = null; 
    mInteractor.unSubscribe(); 
} 
} 

InteractorImpl:

public class InteractorImpl implements Interactor { 

private static final String TAG = "FW.InteractorImpl"; 

private NetworkService mNetworkService; 
private Subscription mSubscription; 

public InteractorImpl(NetworkService networkService) { 
    mNetworkService = networkService; 
} 

@Override 
public void loadResults(final OnFinishedListener listener, String query, boolean useCache, int page) { 
    Observable<Response> responseObservable = (Observable<Response>) 
      mNetworkService.getObservable(mNetworkService.getAPI().getResponseObservable(query, page), Response.class, true, useCache); 

    mSubscription = responseObservable.subscribe(new Observer<Response>() { 
     @Override 
     public void onCompleted() { 

     } 

     @Override 
     public void onError(Throwable e) { 
      Log.e(TAG, e.getMessage()); 
      listener.onError(e); 
     } 

     @Override 
     public void onNext(Response response) { 
      listener.onFinished(response); 
     } 
    }); 
} 

public void unSubscribe() { 
    if(mSubscription != null && !mSubscription.isUnsubscribed()) { 
     mSubscription.unsubscribe(); 
    } 
} 
} 

FragmentPresenter:

public class FragmentPresenter implements Presenter<FragmentView>, 
    Interactor.OnFinishedListener<Response> { 

private static final String TAG = "FW.FragmentPres"; 

@Inject 
QueryPreferences mQueryPreferences; 

private Interactor mInteractor; 
private FragmentView mView; 
private NetworkService mNetworkService; 

private ActivityPresenter mActvityPresenter; 

@Inject 
public FragmentPresenter(NetworkService networkService) { 
    mNetworkService = networkService; 
    mInteractor = new InteractorImpl(mNetworkService); 
} 

void attachRecipeActivityPresenter(ActivityPresenter activityPresenter) { 
    mActvityPresenter = activityPresenter; 
    mActvityPresenter.getObservableResults().subscribe(data -> showData(data)); 
} 

private void showData(Response response) { 
    if (response.getResults().getModels().isEmpty() && mPage == 0) { 
     mView.showNoResults(); 
    } else { 
     mView.showResults(response.getResults().getModels()); 
    } 
} 

@Override 
public void onError(Throwable throwable) { 
    if (mView != null) { 
     mView.hideProgressBar(); 
     mView.showMessage(throwable.getMessage()); 
    } 
} 

@Override 
public void attachView(FragmentView mvpView) { 
    mView = mvpView; 
} 

@Override 
public void detachView() { 
    mView = null; 
    mInteractor.unSubscribe(); 
} 
} 
+0

Я обновил свой ответ. Проверьте это. –

ответ

1

Использование Retrofit2 и RxAndroid ваш метод будет выглядеть следующим образом:

public void updateResults(String data) { 
    yourRetrofitAPI.getSomething(data) 
      .subscribeOn(Schedulers.io()) 
      .observeOn(AndroidSchedulers.mainThread()) 
      .doOnSubscribe(() -> { 
       // show your progress dialog 
      }) 
      .subscribe(result -> { 
       // pass result to your view 
      }, error -> { 
       // hide your progress dialog 
       // get error message and send to your view 
      },() -> { 
       // hide your progress dialog 
      }); 
} 

interface YourRetrofitAPI { 
    @GET("/yourResource/{data}") 
    Observable<String> getSomething(@Path("data") String data); 
} 

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

public class ExampleUnitTest { 
    @Test 
    public void testSample() throws Exception { 
     ActivityPresenter activityPresenter = new ActivityPresenter(); 

     Fragment1Presenter fragment1Presenter = new Fragment1Presenter(); 
     Fragment2Presenter fragment2Presenter = new Fragment2Presenter(); 

     fragment1Presenter.attachActivityPresenter(activityPresenter); 
     fragment2Presenter.attachActivityPresenter(activityPresenter); 

     Observable.range(1, 10) 
       .delay(2, TimeUnit.SECONDS, Schedulers.immediate()) 
       .subscribe(integer -> activityPresenter.queryData("query: " + integer)); 
    } 

    class ActivityPresenter { 
     PublishSubject<String> publishSubject = PublishSubject.create(); 

     Observable<String> serverDataAsObservable() { 
      return publishSubject.map(s -> String.format("%d - %s", System.currentTimeMillis(), s)); 
     } 

     void queryData(String input) { 
      // based on your input you should query data from server 
      // and then emit those data with publish subject 
      // then all subscribers will receive changes 
      publishSubject.onNext(input); 
     } 
    } 

    class Fragment1Presenter { 
     private ActivityPresenter activityPresenter; 

     void attachActivityPresenter(ActivityPresenter activityPresenter) { 
      this.activityPresenter = activityPresenter; 
      this.activityPresenter.serverDataAsObservable() 
        .subscribe(data -> showData(data)); 
     } 

     private void showData(String data) { 
      System.out.println("showing data on fragment1 with " + data); 
     } 
    } 

    class Fragment2Presenter { 
     private ActivityPresenter activityPresenter; 

     void attachActivityPresenter(ActivityPresenter activityPresenter) { 
      this.activityPresenter = activityPresenter; 
      this.activityPresenter.serverDataAsObservable() 
        .subscribe(data -> showData(data)); 
     } 

     private void showData(String data) { 
      System.out.println("showing data on fragment2 with " + data); 
     } 
    } 
} 

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

С уважением.

+0

Родриго, спасибо за ваш ответ. Хотя мой вопрос немного другой. Подумайте, что у меня есть в основном SearchView, а ниже - TabLayout. Таким образом, в зависимости от того, что вы ищете результаты в фрагментах в tabLayout изменения. Поэтому в основном я хочу понять, как SearchView может обновить два фрагмента после получения результатов. Таким образом, один вызов (с использованием Retrofit) -> 2 фрагмента обновлен – user1341300

+1

Вы можете сделать свой ActivityPresenter для связи с вашими презентаторами фрагментов. Затем вы передаете данные и показываете фрагменты. –

+0

Как может ActivityPresenter взаимодействовать с докладчиками фрагментов? Интерфейс, а затем обратный вызов? – user1341300