第八章 使用RecyclerView显示列表(1/2)
有关RecyclerView、View Holder、Adapter之间的关系
CZT已经写过一个笔记来介绍了。但是这三个东西的关系确实有点乱,需要补充说明。
RecyclerView的作用,先是关联RecyclerView所需要的视图,这个视图并不是最终显示fragment的视图;其次设置RecyclerView工作时所需要的LayoutManager,LayoutManager来完成RecyclerView所不会亲自做的摆放屏幕上的列表项的工作,此外Layout Manager还负责定义屏幕滚动行为,具体实现方式根据LayoutManager的子类的多态来实现;最后是设置一个Adapter,Adapter的工作将在下一段具体说明。
Adapter,用于帮助RecyclerView来创建ViewHolder,并将获取到的单例对象绑定到ViewHolder中(bind()方法),将View Holder绑定到RecyclerView的视图上(onCreateViewHolder()方法)。
ViewHolder就是定义一个视图(根据指定的.xml文件),并且决定这个视图里面有什么视图组件,但是这个视图的视图组件的内容是由Adapter来绑定的。
总的来说就是,RecyclerView和ViewHolder是两个模板,大模板RecyclerView里面有很多小模板ViewHolder,但是模板的内容是不能由模板本身决定的,因为那样它就不是纯粹理性的模板了。Adapter就是决定这些模板内容的适配器。
有关两种Fragment
书上一直强调使用支持库中的Fragment,有一次我在自动补全库引用时,引用的是android.app.Fragment(import android.app.Fragment;),导致几个文件同时报错。
import android.app.Fragment;
import android.support.v4.app.Fragment;
这两种是不能同时使用的,要注意。
有关不同视图下相同的视图组件ID
在两个视图文件下出现了两个相同的组件的ID,但是很奇怪并没有报错,原因是在调用这些组件ID前就已经先确定好了在哪个视图文件下,例如:
super(inflater.inflate(R.layout.list_item_crime,parent,false));
itemView.setOnClickListener(this);
mTitleTextVIew=(TextView) itemView.findViewById(R.id.crime_title);
mDateTextVIew=(TextView)itemView.findViewById(R.id.crime_date);
很显然的在第一行先确定了视图文件,因此组件的ID可以看作是这个视图文件的成员变量,因此在不同文件中可以出现相同的组件ID。
有关Fragment中的onCreate()的必要性
在CrimeListFragment类中只出现了onCreateView()方法,是否说明onCreate是否是不必要的?即我将onCreate的内容全部写在onCreateView中似乎也未尝不可。只不过将一些初始化写在onCreate可以减少onCreateView生成视图的负担。
有关单例
在之前的文档里我提到过讲Activity的一个成员变量定义为static的,这个变量不会因为Activity的生命周期的变化而被重置,单例也是用的这个原理,只不过更加严格些。
它的构造方法是private的,保证了只有它本身能构造有且仅有的一个实例,这个实例可以通过public方法来被外界获取。
有关getactivity()
getActivity():获得Fragment依附的Activity对象。
activity是context的子类, 可以说activity就是一个context;getActivity()获得一个activity也就是获得了一个context。这个context会在之后的章节介绍,又是一个大坑。
这个getactivity()在各种地方出现了很多次:
...
mCrimeRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
...
CrimeLab crimeLab=CrimeLab.get(getActivity());
...
Toast.makeText(getActivity(),mCrime.getTitle()+" checked",Toast.LENGTH_SHORT).show();
...
LayoutInflater layoutInflater=LayoutInflater.from(getActivity());
...
这些方法以getactivity()的返回值——Fragment依附的Activity对象为参数,目的应该是确定他们的作用范围吧?
有关Inflater
在实际开发中LayoutInflater这个类还是非常有用的,它的作用类似于findViewById()。不同点是LayoutInflater是用来找res/layout/下的xml布局文件,并且实例化;而findViewById()是找xml布局文件下的具体widget控件(如Button、TextView等)。 具体作用: 1、对于一个没有被载入或者想要动态载入的界面,都需要使用LayoutInflater.inflate()来载入。