接下来我们实现问题的列表。
效果如下图,点击后每一项弹出提示:
这是一个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);
}