Android学习笔记(八)

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设计吧。

发表评论