Android权威编程指南第八章挑战练习。7,8章内容很多,看的比较慢,再过几周考试暂时停更。补充一下,书中的支持库版本已更新,不使用support版本。
implementation 'androidx.recyclerview:recyclerview:1.1.0'
挑战练习 RecyclerView ViewType
请在RecyclerView中创建两类列表项:一般性crime,以及需警方介入的crime。要完成这个挑战,你需要用到RecyclerView.Adapter的视图类别功能(view type)。在Crime对象里,再添加一个mRequiresPolice实例变量,使用它并借助getItemViewType(int)方法,确定该加载哪个视图到CrimeAdapter。
onCreateViewHolder(ViewGroup, int)方法里基于getItemViewType(int)方法返回的viewType值,需要返回不同的ViewHolder。如果是一般性crime,就仍然使用原始布局;如果是需警方介入的crime,就使用一个带联系警方按钮的新布局。
题解
主要思路
我们需要显示不用的item布局,当这个item需要“联系警察”时,切换到“联系警察”的xml布局文件,为此需要自定义一个ViewHolder,再利用书中提示的viewType参数让Adapter选择不同的item布局显示就可以了。
详细步骤
定义布局
既然要显示出一个不同的item布局,我们先去创建一个带有联系警察Button的xml文件
文件名为
list_item_police_crime.xml
内容:
显示出的效果:
添加联系警察变量
因为需要标识这个Crime是否需要联系警察,所以在Crime里创建一个bool变量。并自动创建Setter和Getter方法
既然添加了变量,就要初始化。在CrimeLab中初始化哪些Crime需要显示这个布局,我自己设置成隔三个显示,其实就是一个Demo,能显示出来就行。你也可以自己定义显示哪些。
创建PoliceHolder
先上代码,和CrimeHolder是类似的,只改动了几个地方。
private class PoliceHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
private Crime mCrime;
public PoliceHolder(LayoutInflater inflater, ViewGroup parent) {
super(inflater.inflate(R.layout.list_item_police_crime, parent, false));
itemView.setOnClickListener(this);
mTittleTextView = itemView.findViewById(R.id.crime_title);
mDateTextView = itemView.findViewById(R.id.crime_date);
Button callPolice = itemView.findViewById(R.id.call_police);
callPolice.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(getActivity(), "已经叫警察了", Toast.LENGTH_SHORT).show();
}
});
}//列表itemView的布局
public void bind(Crime crime) {
mCrime = crime; //绑定数据
mTittleTextView.setText((mCrime.getTitle()));
mDateTextView.setText(mCrime.getDate().toString());
}
@Override
public void onClick(View v) {
Toast.makeText(getActivity(), mCrime.getTitle() + "点击!", Toast.LENGTH_SHORT).show();
}
}
private void updateUI() {
CrimeLab crimeLab = CrimeLab.get(getActivity());
List<Crime> crimes = crimeLab.getCrimes();
ItemAdapter adapter = new ItemAdapter(crimes);
mCrimeRecyclerView.setAdapter(adapter);
}
}
定义了按钮的动作
切换了布局(废话)
这就是PoliceHolder需要做的全部工作了。滑稽????
修改Adapter(最重要的环节)
首先我变更了Adapter的名字,因为现在这个适配器需要对两个Holder绑定,然后把泛型删除(用不上)
定义不同的ViewType,先添加书中提到的这个方法。
更改onCreatViewHolder方法,返回类型不再是CrimeHolder。我们需要给RecycleView传回不同的ViewHolder。
数据绑定同样需要更改,使用下转型转换
完成!
显示效果
界面很丑,等有空进行第九章UI设计吧。