Android编程权威指南(第三版)第八章挑战练习:recyclerView viewType

题目要求如图:

Android编程权威指南(第三版)第八章挑战练习:recyclerView viewType_第1张图片

1、因为有两个列表项,所以要新建一个xml布局文件,我这里命名为“list_item_call_crime.xml”,其实就在原来基础上多加一个按钮




    
    
    
    

2、要加入报警的crime,所以在Crime类中增加一下代码

public class Crime {

    ......
    //是否报警
    private boolean mCallPolice;

    public void setCallPolice(boolean requiresPolice) {
        mCallPolice = requiresPolice;
    }

    public boolean isCallPolice() {
        return mCallPolice;
    }
}

3、在CrimeLab中赋值

/*private说明只有其他类不能构造自己*/
    private CrimeLab(Context context){
        mCrimes=new ArrayList<>();
        //存入100个Crime对象
        for (int i=0;i<100;i++){
            Crime crime=new Crime();
            crime.setTitle("Crime #"+i);
            crime.setSolved(i%2==0);
            //每隔五个就是警方介入的crime,为0则报警
            crime.setCallPolice(i%5==0);
            mCrimes.add(crime);
        }
    }

4、接下来便是新增一个ViewHolder,在CrimeHolder的基础上修改就好


/*定义一个新的callPoliceCrimeHolder内部类
    一个CrimeHolder对应一行列表项,对应布局为 list_item_crime*/
    private class callPoliceCrimeHolder extends RecyclerView.ViewHolder implements View.OnClickListener{
        /*绑定列表项前需要实例化布局内的相关组件*/
        private TextView mTitleTextView;
        private TextView mDateTextView;
        private Crime mCrime;
        private Button mCallPolice;

        public callPoliceCrimeHolder(LayoutInflater inflater,ViewGroup parent){
            /*首先实例化 list_item_call_crime 布局
            * 然后传给super()即ViewHolder的构造方法*/
            super(inflater.inflate(R.layout.list_item_call_crime,parent,false));
            //实例化布局内的相关组件
            mTitleTextView=(TextView)itemView.findViewById(R.id.crime_title);
            mDateTextView=(TextView) itemView.findViewById(R.id.crime_date);
            mCallPolice=(Button)itemView.findViewById(R.id.call_police);
            mCallPolice.setOnClickListener(this);
        }

        /*只要收到一个crime,CrimeHolder就会刷新显示mTitleTextView和mDateTextView*/
        public void bind(Crime crime){
            mCrime=crime;
            mTitleTextView.setText(mCrime.getTitle());
            mDateTextView.setText(mCrime.getDate().toString());
        }

        @Override
        public void onClick(View view) {
            Toast.makeText(getActivity(),"you call 110",Toast.LENGTH_SHORT).show();
        }
    }

5、然后修改适配器CrimeAdapter,注意因为添加了一个callPoliceCrimeHolder,所以要做出适当修改,如

private class CrimeAdapter extends RecyclerView.Adapter{}

以及其他CrimeHolder改为RecyclerView.ViewHolder

private class CrimeAdapter extends RecyclerView.Adapter{
        private List mCrimes;

        public CrimeAdapter(List crimes){
            mCrimes=crimes;
        }

        /*增加视图类别功能*/
        @Override
        public int getItemViewType(int position) {
            //为真不报警
            if (mCrimes.get(position).isCallPolice()){
                return 1;
            }else {
                return 0;
            }
        }

        /*当需要一个新的ViewHolder来显示列表项时,会调用这个*/
        @Override
        public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            //先创建LayoutInflater
            LayoutInflater layoutInflater=LayoutInflater.from(getActivity());

            //判断上面的viewType的值判断使用什么布局,即getItemViewType的返回值
            if (viewType == 0) {
                return new CrimeHolder(layoutInflater, parent);
            } else {
                return new callPoliceCrimeHolder(layoutInflater, parent);
            }
        }

        /*需要绑定数据(上下滑动屏幕)时,就会读取当前位置并绑定*/
        @Override
        public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
            if (holder instanceof CrimeHolder){
                Crime crime=mCrimes.get(position);
                ((CrimeHolder)holder).bind(crime);
            }else if (holder instanceof callPoliceCrimeHolder){
                Crime crime=mCrimes.get(position);
                ((callPoliceCrimeHolder)holder).bind(crime);
            }
        }

        @Override
        public int getItemCount() {
            return mCrimes.size();
        }
    }

    private void updateUI(){
        CrimeLab crimeLab=CrimeLab.getCrimeLab(getActivity());//获取单例类
        List crimes=crimeLab.getCrimes();//获取单例类中的数据
        /*创建一个包含所有crimes对象数据的adapter,会调用内部的三个函数*/
        mAdapter=new CrimeAdapter(crimes);
        mCrimeRecyclerView.setAdapter(mAdapter);
    }
}
8、大功告成,编译运行就好了



你可能感兴趣的:(Android学习)