2017-06-12 4 views
6

私は、垂直RecyclerView内で別々のビューとして機能する複数のViewHoldersを持っています。 私は新しいArchitecture Components ViewModelで練習しています。RecyclerViewアダプタ内のアーキテクチャコンポーネントViewModelの使用方法は?

私のViewModelの中に私は観察したいMutableLiveDataのリストをいくつか持っています。しかし、どのように私は活動を漏らすことなく

ViewModelProviders.of((AppCompatActivity)getActivity()).get(FilterViewModel.class) 

mFilterViewModel.getCountries().observe(this, new Observer<ArrayList<TagModel>>() { 
      @Override 
      public void onChanged(@Nullable ArrayList<TagModel> tagModels) { 

      } 
     }); 

を呼び出すか、アダプターの内部でアクティビティを保存することができます。

私のViewModel

public class FilterViewModel extends ViewModel { 

private final MutableLiveData<ArrayList<TagModel>> mCountries; 
private final MutableLiveData<ArrayList<TagModel>> mSelectedCountryProvinceList; 
private final MutableLiveData<ArrayList<TagModel>> mDistanceList; 

public FilterViewModel(){ 

    mCountries = new MutableLiveData<>(); 
    mSelectedCountryProvinceList = new MutableLiveData<>(); 
    mDistanceList = new MutableLiveData<>(); 

    TagStore.getInstance().subscribe(new StoreObserver<TagSearchList>() { 
     @Override 
     public void update(TagSearchList object) { 
      mCountries.setValue(object.getCountries()); 
     } 

     @Override 
     public void update(int id, TagSearchList object) { 
      if (id == 5){ 
       TagStore.getInstance().unSubcribe(this); 
       update(object); 
      } 
     } 

     @Override 
     public void error(String error) { 

     } 
    }).get(5,"parent"); 

    TagStore.getInstance().subscribe(new StoreObserver<TagSearchList>() { 
     @Override 
     public void update(TagSearchList object) { 
      mSelectedCountryProvinceList.setValue(object.toList()); 
     } 

     @Override 
     public void update(int id, TagSearchList object) { 
      if (id == 6){ 
       TagStore.getInstance().unSubcribe(this); 
       update(object); 
      } 
     } 

     @Override 
     public void error(String error) { 

     } 
    }).get(6,"parent"); 

    TagStore.getInstance().subscribe(new StoreObserver<TagSearchList>() { 
     @Override 
     public void update(TagSearchList object) { 
      mDistanceList.setValue(object.toList()); 
     } 

     @Override 
     public void update(int id, TagSearchList object) { 
      if (id == 51){ 
       TagStore.getInstance().unSubcribe(this); 
       update(object); 
      } 
     } 

     @Override 
     public void error(String error) { 

     } 
    }).get(51,"parent"); 

} 

public void selectCountry(final TagModel country){ 
    TagStore.getInstance().subscribe(new StoreObserver<TagSearchList>() { 
     @Override 
     public void update(TagSearchList object) { 
      mSelectedCountryProvinceList.setValue(object.toList()); 
     } 

     @Override 
     public void update(int id, TagSearchList object) { 
      if (id == country.getId()){ 
       TagStore.getInstance().unSubcribe(this); 
       update(object); 
      } 
     } 

     @Override 
     public void error(String error) { 

     } 
    }).get(country.getId(),"parent"); 
} 

public LiveData<ArrayList<TagModel>> getCountries(){ 
    return mCountries; 
} 

public LiveData<ArrayList<TagModel>> getDistances(){ 
    return mDistanceList; 
} 

public LiveData<ArrayList<TagModel>> getProvinces(){ 
    return mSelectedCountryProvinceList; 
} 

}

+0

こんにちは。あなたはAndroid Data Bindingを代わりに使用したいのですが? – JuliaKo

+0

こんにちは@JuliaKo、MVVMに私のアプリをリファクタリングする私の意図ではありません。現時点では私はMVPを使用しています。 MVPフレームワークでViewModelクラスを使用して、ライフサイクルの問題を解決し、データと不要なObservableをリロードします。 –

+0

私はあなたが必要とするものはバインディングアダプタを実装することだと思うし、Googleチームはデータバインディングライフサイクルを意識させるが、それが起こるためには、ライフサイクルは1.0の安定したAPIをヒットする必要がある。 https://github.com/googlesamples/android-architecture-components/issues/34 – JuliaKo

答えて

0

この問題に対する私のソリューションです。

  • アクティビティまたはフラグメントに
  • レイアウト(フラグメントまたは活動のレイアウト)のための新しい変数(ViewModelに)を作成ViewModelProviders
  • であなたのViewModelのインスタンスを取得MutableLiveDataであなたのrecyclerViewを満たすデータを保持それを観察して、recyclerViewのアダプターにあなたが観測した値を記入してください。

ここでは、observeメソッドでアダプターインスタンスを作成しないように注意してください。 これをobserveメソッドで作成すると、リークが発生します。

+0

observeメソッドでアダプタを作成するとリークが発生する理由を説明できますか? –

0

将来の読者のためだけです。アクティビティで

  • をViewModelProviderインスタンスを作成する:私が提供できる 溶液

    ViewModelProviderプロバイダ= ViewModelProviders.of(本)アダプタのViewHolderクラスでは、アダプタのコンストラクタに

  • を渡し

  • 次に、FilterBindingインスタンスを受け取り、

    super(binding.getRoot());

  • インサイドonCreateViewHolderメソッドを実行し、コンストラクタを作成するだけでインスタンス化たとえば、DataBindingUtil.inflate(...)を使用してバインディングし、このバインディングをコンストラクタによる依存関係とみなしたViewHolderインスタンスを返します。

  • Inside ViewHolderクラスは、TagModelを使用するメソッドを作成します(または、yはアダプタを認識しておらず、ロジック内で何が起こっているのかを明確に理解していないためです)。バインディング:

    if (mBindings == null) { FilterViewModel vm = viewModelProvider.get(FilterViewModel.class); /*or instantiate? I am not sure about caching here, honestly. If you chose instantiating, then passing ViewModelProvider to the adapter is not needed*/ mBindings.setViewModel(vm); } mBindings.getViewModel(setItem(item)); mBindings.executePendingBindings();

  • そして、最後のために、ちょうどonBindViewHolder(内部でこのviewholderの結合方法を実行...)

正直言って、私はこの方法が素晴らしく、美しいとは思わないが、それは私が提供できるものすべてである。

関連する問題