2016-12-28 52 views
1

我正在学习Android MVP体系结构here。基于这个例子,我创建了我自己的简单应用程序,它只显示带有拉动功能的列表recyclerviewAndroid 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; 
    } 

,最后一个,这就是我更新recyclerview内RecyclerAdapter:

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(字符串);'会传递'字符串对象的值不参考。在这个场景中Java不是通过值传递的吗? – Umarov

+0

@Umarov它是按值传递的,你传递一个列表,然后你将它分配给其他引用,然后你清除它,但它仍然是相同的列表。传递引用意味着如果给过去的引用分配了某些内容,它将覆盖传入引用中的值,并且按值传递意味着新引用将保存对象,并且在分配内容后,您将只是失去了对前一个对象的引用。你可以阅读更多有关的问题,有很多解释 –

+0

阅读[this](http://stackoverflow.com/a/7893495/5985958)答案,我现在得到了什么传递的真正意义。感谢您的时间! – Umarov