Adapter的notifyDataSetChanged方法會通知RecyclerView刷新全部的可見列表項。 在CriminalIntent應用里,這個方法不夠高效,我們知道,返回CrimeListFragment時,最多只有一個Crime 實例會發生變化。 只需要刷新列表項中的單個crime項的話,應該使用RecyclerView.Adapter的notifyItemChanged(int)方法。修改代碼調用這個方法很簡單,但如何定位並刷新具體位置的列表項呢?這是個問題。
之前在CriminalIntent應用里面為itemView實現了點擊事件。
1 private class CrimeHolder extends RecyclerView.ViewHolder implements View.OnClickListener{ 2 3 ...... 4 5 public CrimeHolder(View itemView){ 6 super(itemView); 7 itemView.setOnClickListener(this); 8 mTitleTextView = (TextView)itemView.findViewById(R.id.list_item_crime_title_text_view); 9 mDateTextView = (TextView)itemView.findViewById(R.id.list_item_crime_date_text_view); 10 mSolvedCheckBox = (CheckBox)itemView.findViewById(R.id.list_item_crime_solved_check_box); 11 } 12 13 @Override 14 public void onClick(View v){16 Intent intent = CrimeActivity.newIntent(getActivity(),mCrime.getId()); 17 startActivity(intent); 18 } 19 20 ...... 21 }
所以現在可以通過點擊事件獲取到我們點擊條目的位置。
首先添加一個全局變量
int position;
然后修改onClick()中的方法
@Override public void onClick(View v){ position = mCrimeRecyclerView.getChildAdapterPosition(v); //將獲取到的位置賦值給之前定義的變量 Intent intent = CrimeActivity.newIntent(getActivity(),mCrime.getId()); startActivity(intent); }
這里簡單說下RecyclerView.getChildAdapterPosition()方法,此方法可以獲取ItemView在Adapter中的位置。它接受一個view參數,將onClick()方法中的view參數傳入即可。
最后修改updataUI()方法中的刷新方法
private void updateUI(){ //單例模式獲取CrimeLab 對象 CrimeLab crimeLab = CrimeLab.get(getActivity()); //獲取數據 List<Crime> crimes = crimeLab.getCrimes(); if(mAdapter == null){ mAdapter = new CrimeAdapter(crimes); mCrimeRecyclerView.setAdapter(mAdapter); }else{ mAdapter.notifyItemChanged(position); //這里使用的是notifyItemChanged()方法。 傳入的參數為position } }
github:https://github.com/FlashFrog/CriminalIntentChallenge.git