开头
今天是第三天,希望能一直坚持下去,不会中断。
使用RecyclerView
RecyclerView类来自于Google支持库。要使用它,首先要添加RecyclerView依赖库。单击File->Project Stricture...菜单选择App,然后点击
Dependencies,再点击+按钮弹出依赖库添加窗口,找到并选择recyclerview-v7支持库,单击OK完成添加。
RecyclerView视图需要在CrimeListFragment布局文件中定义,创建布局文件fragment_crime_list.xml,并修改视图为RecyclerView,如下面代码所示:
<android.support.v7.widget.RecyclerView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/crime_recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
配置完CrimeListFragment的视图,接下来就是视图和fragment的关联。如下面代码所示:public class CrimeListFragment extends Fragment {
private RecyclerView mCrimeRecyclerView;
@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()));
return view;
}
}
没有LayoutManagerd的支持,不仅RecyclerView无法工作,还会导致应用崩溃。所以,RecyclerView视图创建完成之后,就立即转交给了LayoutManager对象。如前所述,RecyclerView类的任务就是回收再利用以及定位屏幕上的TextView视图。实际上,定位的任务被委托给了
LayoutManager。除了在屏幕上定位列表项,LayoutManager还负责定义屏幕滚动行为。因此,没有LayoutManager,RecyclerView也就
没法正常工作了。Android将来可能会改变这种工作模式,但现在就是如此。
实现Adapter和ViewHolder
首先在CrimeListFragment类定义Viewholder内部类,如下代码所示:
public class CrimeListFragment extends Fragment {
...
private class CrimeHolder extends RecyclerView.ViewHolder {
public TextView mTitleTextView;
public CrimeHolder(View itemView) {
super(itemView);
mTitleTextView = (TextView) itemView;
}
}
}
可以看到,ViewHolder类引用了用于显示crime标题的TextView视图。这就要求itemView必须是个TextView,否则代码会崩溃。定义完ViewHolder,接下来的任务是创建adapter,如下代码所示:
public class CrimeListFragment extends Fragment {
...
private class CrimeAdapter extends RecyclerView.Adapter<CrimeHolder> {
private List<Crime> mCrimes;
public CrimeAdapter(List<Crime> crimes) {
mCrimes = crimes;
}
}
}
ViewHolder需要被创建或与Crime对象关联时,RecyclerView会和它沟通。RecyclerView不关心也不了解具体的Crime对象,这是Adapter要做的事。接下来,在CrimeAdapter中实施三个方法,如下代码所示:
private class CrimeAdapter extends RecyclerView.Adapter<CrimeHolder> {
...
@Override
public CrimeHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater layoutInflater = LayoutInflater.from(getActivity());
View view = layoutInflater
.inflate(android.R.layout.simple_list_item_1, parent, false);
return new CrimeHolder(view);
}
@Override
public void onBindViewHolder(CrimeHolder holder, int position) {
Crime crime = mCrimes.get(position);
holder.mTitleTextView.setText(crime.getTitle());
}
@Override
public int getItemCount() {
return mCrimes.size();
}
}
RecyclerView需要新的View视图来显示列表项时,会调用onCreateViewHolder方法。在这个方法内部,我们创建View视图,然后封装到ViewHolder中。此时,RecyclerView并不要求封装视图装载数据。
为得到View视图,我们实例化了Android标准库中名为simple_list_item_1的布局。该布局定义了美观的TextView视图,主要
用于列表项的展示。接下来要说的是onBindViewHolder方法。该方法会把ViewHolder的View视图和模型层数据绑定起来。
收到ViewHolder和列表项在数据集中的索引位置后,我们通过索引位置找到要显示的数据进行绑定。绑定完毕,刷新显示View视图。
所谓索引位置,实际上就是数组中Crime的位置。取出目标数据后,通过发送crime标题给ViewHolder的TextView视图,我们就完成了
Crime数据和View视图的绑定。搞定了 Adapter,最后要做的就是将它和 RecyclerView关联起来。实现一个设置CrimeListFragment用
户界面的updateUI方法,该方法创建CrimeAdapter,然后设置给RecyclerView,如下代码所示:
public class CrimeListFragment extends Fragment {
private RecyclerView mCrimeRecyclerView;
private CrimeAdapter mAdapter;
@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()));
updateUI();
return view;
}
private void updateUI() {
CrimeLab crimeLab = CrimeLab.get(getActivity());
List<Crime> crimes = crimeLab.getCrimes();
mAdapter = new CrimeAdapter(crimes);
mCrimeRecyclerView.setAdapter(mAdapter);
}
...
}
总结
今天事情多,写得有点赶,本来想写更多的,但是时间不够了,今天的修炼就这样吧。