1.在列表中,将新增一个CrimeLab对象,该对象是一个数据存储池,用来存储Creme对象,那么就activity视图包涵fragment的FragmentLayoyt组成,fragment由一个RecyclerView组成
2.运用单例模型来数据存储,运用能在内存活多久,那么单例就能活多久,因此将列表保存在单例里的话,那么就能随时地获取crime数据,要创立一个单例,那么就需要创建一个带有私有构造方法以及get()方法的类,如果实例已经存在,那么get()方法就直接返回它,不在就创建它
下面是模版代码
public class CrimeLab{
private static CrimeLab sCrimeLab;
public static CrimeLab get(Context context){
if(sCrimeLab == null) {
sCrimeLab = new CrimeLab(context);
}
private CrimeLab(Context context){
}
}
在这边,我们传入的是Context对象,然后在CrimeLab的构造方法创建一个空的List用户保存Crime对象,然后再添加两个方法 getCrimes(),和getCrime(UUID),前者是返回数组列表,后者是返回指定ID的Crime对象
如
public Crime getCrime(UUID id) {
for(Crime crime : mCrimes){
if(crime.getId().equals(id)){
return crime;
}
}
return null;
}
3.使用抽象activity托管fragment托管fragment,要创建一个fragment的activity时,那么就需要先创建一个视图,正常情况下,我们如果想要有一份通用的 activity_fragment.xml文件,用FraeLayout来作为容器视图
4.创建一个通用的超类来用于使用了fragment的activity类,代码如下面:
public abstract class SingleFragmentActivity extends AppCompatActivtiy{
protected abstract Fragment createFragment();
private void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstaceState);
setContentView(R.layout.activity_fragment);
FragmentManager fm = getSupportManager();
Fragment fragment = fm.findFragmentById(R.id.fragment_container);
if(fragment == null){
fragment createFragment();
fm.beginTransation()
.add(R.id.fragment_cotainer,fragment)
.commit;
}
}
}
在上面的代码中添加一个名为crrateFragment()的抽象方法,然后以后的SingleFragmentActivity的子类就需要来实现该方法,
以后如果某一个activity需要来托管一个fragment的话,那么就需要来继承上面那个类,然后来覆盖他的抽象方法,在该抽象方法中,我们可以用来创建自己需要fragment,而fragment的创建就需要自己创建一个类和一个视图,把两者之间联系起来
5.对于一个新建立的activity类,那么就需要注意是不是已经在配置文件中声明他了不然程序会崩了
6.对于RecyclerView ,ViewHolder,Adapter
RecyclerView是ViewGroup的子类,每一个列表项都是作为一个子对象来显示的,RecyclerView所作的就是一个回收利用。列表的View能够显示还需要有 ViewHolder子类和Adapter子类,ViewHolder只做一件事,那就是容纳View视图,ViewHolder的典型代码如下面
public class ListRow extends RecyclerView.ViewHolder{
public ImageView mThumbnail;
public ListRow(View view){
super(view);
mThumbnail = (ImageView)view.findViewById(R.id.thumnail);
}
}
ViewHolder为itemView而生:它引用着传给super(view)的整个View视图
下面是ViewHolder的使用实例
ListRow row = new ListRow(inflater.inflate(R.layout.list_row,parent,false));
View view = row.itemView;
ImageView thumbailView = row.mThumbnail;
RecyclerView自身不会创建视图,它创建的是ViewHolder,而ViewHolder引用着itemView,如果是复杂视图,viewHolder就得处理不同部分的itemview
而对于Adapter来说,由于RecycleView自己不创建ViewHolder,这个任务是由Adapter来完成的,Adapter是一个控制器,从模型中获取数据,然后提供给RecyclerView来显示,是沟通的桥梁
Adapter的作用是(1)创建必要的ViewHolder(2)绑定ViewHolder到模型的数据,此时如果一个RecycleView需要显示视图的时候,那么就会去找它的Adapter,下面是其主要的流程
(1)首先会调用Adapter的getItemCount()方法,RecycleView询问数组列表有多少个对象
(2)然后调用Adapter的onCreateViewHolder(ViewGroup,int)方法创建ViewHolder和要显示的视图
(3)最后,Recycler会传入ViewHolder及其位置,然后调用onBindViewHolder()方法,Adapter会找到目标位置的数据并将其绑定到ViewHolder的视图中去,绑定就是使用模型的数据填补视图
(4)一旦有足够的ViewHolder,那么就会停止调用onCreateViewHolder()方法,它会会回收调用旧的ViewHolder来节约时间和内存
7.如果想要使用RecyclerView,那么就要添加RecyclerView的视图,在xml中去使用RecyclerView,然后在碎片的视图中去联系RecyclerView
8.下面的任务就是视图与fragment的关联,下面是为碎片配置视图
public class CrimeListFragment extends Fragment {
private RecyclerView mCrimeRecyclerView;
public View onCreateView(LayoutInflater inflater,ViewGroup cotainer,Bundle savedInstance){
View view = infflater.inflate(R.layout.fragment_crime_list,container,false);//fragment_crime_list这个是那个xml文件的名字
mCrimeRecycleView = (RecyclerView)view.findViewById(R.id.crime_recycle_view);//crime_recycle_view这个是上面那个文件里面的RecycleView的id名字
mCrimeRecycleView.setLayoutManager(new LinearLayoutManager(getActivity()));
return view;
}
}
RecyclerView创建后,转发给LayoutManager对象,LayoutManager负责定义屏幕滚动的行为
9.实现ViewHolder和Adaper
(1)会在CrimeListFragment类中定义ViewHolder内部类,也就是在我们自己的列表类的里面,在ViewHolder内部类里面,他会实例化和使用我们自己定义的列表项布局,如下面:
public class CrimeListFragment extends Fragment {
private class CrimeHolder extends RecyclerView.ViewHolder{
private TextView mTitleTextView;//实例化组件
public CrimeHolder(LayoutInflater inflater,ViewGroup parent){
super(inflater.inflater(R.layout.list_item_crime,parent,false));
mTitleTextView = (TextView)itemView.findViewById(R.id.crime_title);//实例化组件,针对列表项里面的某个小组件来进行实例化
}
}
}
在这里,我们实例化了list_item_crime布局,然后传入super(),也就是在ViewHolder的构造方法,这样ViewHolder因此来引用这个布局
定义完ViewHolder后,就需创建Adapter
private class CrimeAdapter extends RecyclerView.Adapter<CrimeHolder> {
private List<Crime> mCrimes;
public CrimeAdapter(List<Crime> crimes) {
mCrimes = crimes;
}
}
然后需要在Adapter中实现三个方法,
public CrimeHolder onCreateViewHolder(ViewGroup parent,int viewType){
LayoutInflater layoutInflater = LayoutInflater.from(getActivity());
return new CrimeHolder(layoutInflater,parent);
}
public void onBindViewHolder(CrimeHolder holder,int position){
Crime crime = mCrime.get(position);
holder.bind(crime);
}
public int getItemCount(){
return mCrime.size();
}
上面三个方法中,当RecycleView需要新的ViewHolder来显示列表时,就会调用onCreateViewHolder方法,这个方法里面我们创建一个LayoutInflater,然后用它来创建CrimeHolder
而对于onBindViewHolder()方法中,我们是用来绑定数据的,就是让Java的代码和组件关联起来,每一次视图的实例化都是绑定,对于一次性的工作我们应该把他们放在一次任务中去,但在绑定数据之前我们应该在ViewHolder中去实例化相关组件(可以在上面的ViewHolder的类中去看),然后在ViewHolder类中我们需要建立一个bind()方法,这样就当有新的Crime要在CrimeHolder中显示时,都要去调用它一次,下面是这个方法
public void bind(Crime crime) {
mCrime = crime;
mTitleTextView.setText(mCrime.getTitle());
}
最后我们就需要在在Adapter中去使用这个方法,也就是在onBindViewHolder(CrimeHolder holder,int position)中去使用,可以看上面的onBindViewHolder()方法
当我们做好Adapter后,我们最后就要将它和RecyclerView关联起来,那么我们就应该实现一个设置CrimeListFragment用户界面的updateUI方法,在该方法中创建CrimeAdapter,然后设置给RecyclerView,如下面的代码
在类中
private CrimeAdapter mAdapter;
在onCreateView()方法中
updateUI();
private void updateUI(){
CrimeLab crimeLab = CrimeLab.get(getActivity());
List<Crime> crimes = crimeLab.getCrimes();
mAdapter = new CrimeAdapter(crimes);//这里是上面的CrimeAdapter的构造器
mCrimeRecyclerView.setAdapter(mAdapter);
}
10.实现响应,如果我们想要在RecyclerView上实现功能,那么我们还需要对它实现点击功能,但对于RecycleView它需要我们自己来实现触摸的功能,而由于列表项视图既然都关联着ViewHolder,那么我们就可以让ViewHolder为它来监听用户触摸事件,如下面的代码
private class CrimeHolder extends RecycleView.ViewHolder implements View.OnClickListener {
public CrimeHolder(LayoutInter inflater,ViewGroup parent) {
super(inflater.nflate(R.layout.list_item_crime,parent,false));
itemView.setOnClickListener(this);
}
}