RecyclerView是ListView的升级版,强化了ListView的某些不足。比如listView如果不使用一些技巧的话,listView的性能就会非常差;ListView只能实现纵向滚动的效果等。
顾名思义,ViewHolder只做一件事:容纳View视图
RecyclerView自身是不会创建视图,它创建的是ViewHolder,而ViewHolder引用这一个个itemView
如下图:
RecyclerView自己不会创建ViewHolder。这个任务实际是由adapter来完成的。adapter是个控制器对象,从模型层获取数据,然后提供给RecyclerView显示,起到桥梁的作用。
adapter负责:
1:创建必要的ViewHolder
2:绑定ViewHolder至模型层数据
recyclerView需要显示视图时,就会去找它的adapter。下图展示了一个recyclerView可能发起的会话。
首先,通过调用adapter的getItemCount()方法,RrecyclerView询问数组列表中包含多少个对象
接着,RecyclerView调用adapter的CreateViewHolder()方法创建ViewHolder以及ViewHolder要显示的视图。
最后,RecyclerView会传入ViewHolder及其位置,调用onBindViewHolder(ViewHolder,int position)方法。adapter会找到目标位置的数据并更新到ViewHolder的视图上。
具体代码如下;
private class CrimeHolder extends RecyclerView.ViewHolder implements View.OnClickListener { private TextView mTitleTextView; private TextView mDateTextView; private CheckBox mSolvedCheckBox; private Crime mCrime; public CrimeHolder(View itemView) { super(itemView); itemView.setOnClickListener(this); mTitleTextView = (TextView) itemView.findViewById(R.id.list_item_crime_title_text_view); mDateTextView = (TextView) itemView.findViewById(R.id.list_item_crime_date_text_view); mSolvedCheckBox = (CheckBox) itemView.findViewById(R.id.list_item_crime_solved_check_box); } public void bindCrime(Crime crime) { //在viewholder中实现的,所以还是可以说viewholder只是容纳视图 mCrime = crime; mTitleTextView.setText(mCrime.getTitle()); mDateTextView.setText(mCrime.getDate().toString()); mSolvedCheckBox.setChecked(mCrime.isSolved()); } @Override public void onClick(View v) { mCallbacks.onCrimeSelected(mCrime); } } private class CrimeAdapter extends RecyclerView.Adapter<CrimeHolder> { private List<Crime> mCrimes; public CrimeAdapter(List<Crime> crimes) { mCrimes = crimes; } @Override /* 锁定视图R.layout.list_item_crime,绑定到ViewHolder(CrimeHolder继承ViewHolder)中 */ public CrimeHolder onCreateViewHolder(ViewGroup parent, int viewType) { LayoutInflater layoutInflater = LayoutInflater.from(getActivity()); View view = layoutInflater.inflate(R.layout.list_item_crime, parent, false); return new CrimeHolder(view); } @Override /* 向viewHolder中的布局添加数据c */ public void onBindViewHolder(CrimeHolder holder, int position) { Crime crime = mCrimes.get(position); holder.bindCrime(crime); } @Override public int getItemCount() { return mCrimes.size(); } public void setCrimes(List<Crime> crimes) { mCrimes = crimes; } }
搞定了adapter,最后要做的就是将它和RecyclerView关联起来,该方法创建adapter,然后设置给RecyclerView。代码如下所示
@Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fragment_crime_list, container, false); mCrimeRecyclerView = (RecyclerView) view .findViewById(R.id.crime_recycler_view); mCrimeRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity())); if (savedInstanceState != null) { mSubtitleVisible = savedInstanceState.getBoolean(SAVED_SUBTITLE_VISIBLE);//得到saveInstanceState的值 } updateUI(); return view; }
public void updateUI() { CrimeLab crimeLab = CrimeLab.get(getActivity());//得到CrimeLab对象 List<Crime> crimes = crimeLab.getCrimes();//得到list对象 mAdapter = new CrimeAdapter(crimes);//将list对象添加到Adapter中 mCrimeRecyclerView.setAdapter(mAdapter);//启用这个adapter }