Android Criminal实例--(2)使用RecyclerView显示列表

标签: Android

接下来我们实现问题的列表。
效果如下图,点击后每一项弹出提示:
这里写图片描述

这是一个RecyclerView,每一项的内容都是一个item,包含title和date。
下面是RecyclerView的整体布局,相当于一个大的RecyclerView容器,

crime_list_fragment.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <android.support.v7.widget.RecyclerView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/crime_recycler"/>
</LinearLayout>

接下来是每一项的布局,即是包含title和date

crime_list_item.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    android:padding="10dp">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/list_title"
        android:text="list_title"
        />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/list_date"
        android:text="list_date"
        android:layout_marginTop="5dp"/>

</LinearLayout>

因为我们要通过一个activity显示fragment的内容,所以要将二者绑定,即CrimeListActivity和CrimeListFragment.因为每一次activity和fragment绑定代码大同小异,只是传入的fragment不同,所以我们将这些代码封装在一个类中:
即 FragmentActivity:

public abstract class FragmentActivity extends AppCompatActivity {

    public abstract Fragment createFragment();

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_crime);

        FragmentManager fm=getSupportFragmentManager();
        Fragment fragment=fm.findFragmentById(R.id.crime_container);
        if(fragment==null){
            fragment=createFragment();
            fm.beginTransaction()
                    .add(R.id.crime_container,fragment)
                    .commit();
        }

    }
}

这样,其他的activity需要绑定fragment只需要继承这个类即可,如下面的CrimeListActivity:

public class CrimeListActivity extends FragmentActivity {
    @Override
    public Fragment createFragment() {
        return new CrimeListFragment();
    }
}

接下来实现CrimeListFragment,将每一项的内容都要显示出来。

因为内容显示在RecyclerView中,而RecyclerView中包含每一项的内容,所以需要一个adapter即适配器来获取数据,并将数据显示在RecyclerView中。

因为Crime类是存储数据的,而RecyclerView显示大量数据,所以我们将这些数据存放在list数组中,通过list数组来获取每一个crime

public class CrimeLab {

    //创建静态单例
    private static CrimeLab sCrimeLab;

    public static CrimeLab getCrimeLab(Context context){
        if(sCrimeLab==null){
            sCrimeLab=new CrimeLab(context);
        }
        return sCrimeLab;
    }

    //向数组列表中添加对象
    public CrimeLab(Context context){
        mCrimes=new ArrayList<>();
        for(int i=0;i<100;i++){
            Crime crime=new Crime();
            crime.setTitle("Crime "+i);
            crime.setDate(new Date());
            mCrimes.add(crime);
        }
    }

    private List<Crime> mCrimes;

    //获取列表数组
    public List<Crime> getCrimes() {
        return mCrimes;
    }

    //返回列表数组中指定对象
    public Crime getCrime(UUID id){
        for(Crime crime:mCrimes){
            if(crime.getId().equals(id)){
                return crime;
            }
        }
        return null;
    }
}

又因为RecyclerView中的每一项都可以看成是一个ViewHolder,viewHolder能够展示不同的item,每一项中都有title和date,所以这两个TextView都放在viewHolder中进行初始化。

同时,每一项都要实现点击事件,所以也在viewHolder中实现,同时还要将CrimeLab中的内容与ViewHolder进行绑定

下面实现CrimeListFragment内部类CrimeHolder:

private class CrimeHolder extends RecyclerView.ViewHolder implements View.OnClickListener{

//初始化title和date
        private TextView list_title;
        private TextView list_date;

//将crime和每一项绑定
        Crime mCrime;
        public void bind(Crime crime){
            mCrime=crime;
            list_title.setText(crime.getTitle());
            list_date.setText(crime.getDate().toString());
        }

        public CrimeHolder(LayoutInflater inflater,ViewGroup parent){
            super(inflater.inflate(R.layout.crime_list_item,parent,false));

            list_title=(TextView)itemView.findViewById(R.id.list_title);
            list_date=(TextView)itemView.findViewById(R.id.list_date);

//为每一项添加点击事件
            itemView.setOnClickListener(this);
        }

        @Override
        public void onClick(View v) {
            Toast.makeText(getActivity(), mCrime.getTitle()+"click!", Toast.LENGTH_SHORT).show();
        }
    }

接下来是适配器的实现,适配器要将数据传递给RecyclerView
这里写图片描述

这里写图片描述

private class CrimeAdpater extends RecyclerView.Adapter<CrimeHolder>{

        private List<Crime> mCrimes;
//构造方法
        public CrimeAdpater(List<Crime> crimes){
            mCrimes=crimes;
        }

        @Override
        public CrimeHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            LayoutInflater layoutInflater=LayoutInflater.from(getActivity());
            return new CrimeHolder(layoutInflater,parent);
        }

//绑定
        @Override
        public void onBindViewHolder(CrimeHolder holder, int position) {

            Crime crime=mCrimes.get(position);
            holder.bind(crime);
        }

//返回RecyclerView中每一项的数量,即list里面的数据
        @Override
        public int getItemCount() {
            return mCrimes.size();
        }
    }

//显示内容,将adapter和RecyclerView绑定
    private void updateUI(){

        CrimeLab crimeLab=CrimeLab.getCrimeLab(getActivity());
        List<Crime> crimes=crimeLab.getCrimes();

        mCrimeAdpater=new CrimeAdpater(crimes);
        mRecyclerView.setAdapter(mCrimeAdpater);

    }
版权声明:本文为ayangann915原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/ayangann915/article/details/81287556