2016-12-28 7 views
1

hereのAndroid MVPアーキテクチャを学習しています。私の例では、機能をリフレッシュするために、recyclerviewのリストを表示する自分のシンプルなアプリケーションを作成しました。Android MVPアーキテクチャ - リポジトリとビュー間の通信

リストをプルすると、最初にrecyclerviewをクリアしてから、偽の遅延があるリポジトリから再びデータをリロードします。しかし、RecyclerViewAdpater内のデータをクリアすると、リポジトリ内のすべてのデータもクリアされ、何も表示されません。私は理由を理解できません。ここで

はプレゼンターとビュー(つまり断片である)の両方を作成し、私の活動です:

protected void onCreate(Bundle savedInstanceState) { 

      mainFragment = MainFragment.newInstance(); 

      FragmentTransaction transaction = getSupportFragmentManager().beginTransaction(); 
      transaction.add(R.id.contentFrame, mainFragment); 
      transaction.commit(); 

      new MainPresenter(new MainDataRepository(), mainFragment); 
    } 

は、ここに私の断片(MainFragment)だ - 注意: updateList(ヌル) - それは、すべてのデータを消去します場所です、リポジトリ内を含む:

public MainFragment() { 
    } 

    public static MainFragment newInstance() { 
     return new MainFragment(); 
    } 

    @Nullable 
    @Override 
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { 
     //.... 

     swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() { 
      @Override 
      public void onRefresh() { 
       recyclerAdapter.updateList(null); // **This is where it clears all data, including inside Repository** 

       Handler handler = new Handler(); 
       handler.postDelayed(new Runnable() { 
        @Override 
        public void run() { 
         mPresenter.loadList(); // to reload the list 
        } 
       }, 1500); 
      } 
     }); 

     //... 
    } 

    @Override 
    public void onResume() { 
     super.onResume(); 

     Handler handler = new Handler(); 
     handler.postDelayed(new Runnable() { 
      @Override 
      public void run() { 
       mPresenter.loadList(); 
      } 
     }, 3000); 
    } 

    @Override 
    public void setPresenter(MainContractor.Presenter presenter) { 
     mPresenter = presenter; 
    } 

    @Override 
    public void showList(List<String> mainDataList) { 
     if(recyclerAdapter == null) { 
      recyclerAdapter = new RecyclerAdapter(mainDataList); 
      recyclerView.setLayoutManager(new LinearLayoutManager(getActivity())); 
      recyclerView.setAdapter(recyclerAdapter); 
     }else{ 
      recyclerAdapter.updateList(mainDataList); 
     } 
    } 

ここに私のプレゼンター(MainPresenter)があります:

public MainPresenter(MainDataRepository mainDataRepository, MainContractor.View view){ 
     mMainDataRepository = mainDataRepository; 
     mMainContractorView = view; 

     view.setPresenter(this); 
    } 

    @Override 
    public void loadList() { 
     ArrayList<String> strings = mMainDataRepository.getList(); 

     mMainContractorView.showList(strings); 
    } 

はここに私のリポジトリ(MainDataRepository)です:

private ArrayList<String> repositoryList; 

    public MainDataRepository() { 
     createList(); 
    } 

    private void createList() { 
     if(repositoryList == null){ 
      repositoryList = new ArrayList<>(); 
     } 

     for (int i = 1; i <= 10; i++) { 
      repositoryList.add("Item " + i); 
     } 
    } 

    public ArrayList<String> getList(){ 
     return repositoryList; 
    } 

そして最後の1、これはどのように私はRecyclerAdapter内recyclerviewを更新しています:

public class RecyclerAdapter extends RecyclerView.Adapter<RecyclerAdapter.MyViewHolder> { 

    private List<String> stringsList; 

    public RecyclerAdapter(List<String> stringsList) { 
     this.stringsList = stringsList; 
    } 

    public void updateList(List<String> newStrings){ 
      if(newStrings != null){ 
       stringsList = newStrings; 
      }else{ 
       stringsList.clear(); 
      } 
      notifyDataSetChanged(); 
     } 

     //.... 
} 

はなぜRecyclerAdapter内部updateList mehodはまた、リポジトリ内のデータを消去しますつまり、ArrayList<String> repositoryList

+0

このサンプルプロジェクトはhttp://github.com/mmirhoseini/marvelでご覧になれます。この記事はhttps://hackernoon.com/yet-another-mvp-article-part-1-lets-get-プロジェクトを知るためにd3fd553b3e21を使用して、MVPをよりよく理解してください。 –

答えて

1

同じオブジェクトへの参照があるからです。あなたがリポジトリから自分のリストを返すところ はここで、より良いオプションは、そのコピーを返すことです:

public ArrayList<String> getList(){ 
    return new ArrayList<>(repositoryList); 
} 

そして、それがコピーされたアイテムを別のオブジェクトになります。

+0

あなたの微調整が正しく機能しています!しかし、私はこの 'mMainContractorView.showList(文字列);'は 'string'オブジェクトを値ではなく参照渡しに渡します。このシナリオでJavaは値渡しではありませんか? – Umarov

+0

@Umarovそれは値渡しで、リストを渡した後、それを他の参照に割り当ててからそれをクリアしますが、それでも同じリストです。参照渡しとは、過去の参照に何かを割り当てると、参照参照の値を上書きし、値渡しは新しい参照がオブジェクトを保持することを意味し、何かを割り当てた後は前のオブジェクトへの参照を失うだけです。あなたは関連する質問でもっと多くを読むことができます、多くの説明があります。 –

+0

これを読んで[this](http://stackoverflow.com/a/7893495/5985958)答え、私は今、値渡しが本当に意味を持っています。あなたの時間をありがとう! – Umarov

関連する問題