Android之再谈Fragment

上一次我写了一个Fragment的简单使用,这次我来实现这个:

首先想想上次写的东西 crime类 crimeFragmnet类 crimeActivity类

如上图的的前三个类。和上次一样这次我们来建CrimeLab类 crimeListFragement类和crimeListActivity类。

 

上次,我们为fragment加入xml布局文件,我们在重写onCreateView的方法中使用inflater把xml文件填充到我们的fragment;

public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View v=inflater.inflate(R.layout.fragment,container,false);

现在来看看这次我们的fragmnet类的代码
 1 package com.example.leiyunjie.crime;
 2 
 3 import android.os.Bundle;
 4 import android.support.v4.app.ListFragment;
 5 import android.util.Log;
 6 import android.view.View;
 7 import android.widget.ArrayAdapter;
 8 import android.widget.ListView;
 9 
10 import java.util.ArrayList;
11 
12 /**
13  * Created by leiyunjie on 2016/4/21.
14  */
15 public class CrimeListFragment extends ListFragment {
16 
17     private ArrayList<crime> mCrimes;
18     private static final String TGA="CrimeListFragment";
19     @Override
20     public void onCreate(Bundle savedInstanceState){
21         super.onCreate(savedInstanceState);
22         getActivity().setTitle("Crimes");
23         mCrimes=CrimeLab.get(getActivity()).getmCrimes();
24 
25         ArrayAdapter<crime> adapter=
26                 new ArrayAdapter<crime>(getActivity(),
27                         android.R.layout.simple_expandable_list_item_1,
28                         mCrimes);
29         setListAdapter(adapter);
30 
31     }
32     @Override
33     public void onListItemClick(ListView l, View v, int position, long id){
34         crime c=(crime)(getListAdapter()).getItem(position);
35         Log.d(TGA,c.getmTitle()+"was clicked");
36     }
37 }
crimelistFragment

这次我们的public class CrimeListFragment extends ListFragment  也就是这个crimelistfragment继承ListFragment,而ListFragment 类默认实现方法已生成了一个全屏 ListView 布局,我们也就可以不用自己布局了。现在我们要做的就是把要显示的crimelab对象放进这个listview布局。

现在来看看crimelab的代码

 1 package com.example.leiyunjie.crime;
 2 
 3 import android.content.Context;
 4 
 5 import java.util.ArrayList;
 6 import java.util.UUID;
 7 
 8 /**
 9  * Created by leiyunjie on 2016/4/21.
10  */
11 
12 //单例
13 public class CrimeLab {
14     private ArrayList<crime> mCrimes;
15 
16     private static CrimeLab sCrimeLaab;
17     private Context mAppContext;
18 
19    //随机产生100个实例
20     private CrimeLab(Context appContext){
21         mAppContext=appContext;
22         mCrimes=new ArrayList<crime>();
23         for(int i=0;i<100;i++){
24           crime c=new crime();
25             c.setmTitle("crime #"+i);
26             c.setmSolved(i%2==00);
27             mCrimes.add(c);
28         }
29 
30 
31     }
32     public static  CrimeLab get(Context c){
33         if(sCrimeLaab==null){
34             sCrimeLaab=new CrimeLab(c.getApplicationContext());
35         }
36         return sCrimeLaab;
37     }
38 
39     public  ArrayList<crime> getmCrimes(){
40 
41         return  mCrimes;
42     }
43 
44     public crime getCrime(UUID id){
45         for(crime c:mCrimes){
46             if(c.getmID().equals(id))
47                 return c;
48         }
49         return null;
50     }
51 
52 
53 
54 }
crimelab
我们将crime数组对象存储在一个单例里。单例是特殊的java类,在创建实例时,一个类仅允许创建一个实例。应用能够在内存里存在多久, 单例就能存在多久, 因此将对象列表保存在单例里可保持crime
数据的一直存在,不管activity、fragment及它们的生命周期发生什么变化。要创建单例,需创建一个带有私有构造方法及 get() 方法的类,其中 get() 方法返回实例。如实例已存在, get() 方法则直接返回它;如实例还未存在, get() 方法会调用构造方法来创建它。
public static  CrimeLab get(Context c){
if(sCrimeLaab==null){
sCrimeLaab=new CrimeLab(c.getApplicationContext());
}
return sCrimeLaab;
}
为了看看效果我产生100个随机对象来填充arraylist:
private CrimeLab(Context appContext){
mAppContext=appContext;
mCrimes=new ArrayList<crime>();
for(int i=0;i<100;i++){
crime c=new crime();
c.setmTitle("crime #"+i);
c.setmSolved(i%2==00);
mCrimes.add(c);
}
现在我们有了一个有着100个随机产生的crime对象的arraylist,接下来把他放到fragment中
先获得该arrylist
private ArrayList<crime> mCrimes;
 mCrimes=CrimeLab.get(getActivity()).getmCrimes();
然后该使用adapter来工作了
ArrayAdapter<crime> adapter=
new ArrayAdapter<crime>(getActivity(),
android.R.layout.simple_expandable_list_item_1,
mCrimes);
setListAdapter(adapter);

}

顺便说说adapter:
adapter的继承关系:

                

adapter和listview的对话


创建ArryAdapter时必须指定三个参数:Context,textViewResourceId,数组或list。对应上面的getActivity(), android.R.layout.simple_expandable_list_item_1, mCrimes。

就是把数组或list中的东西放到android.R.layout.simple_expandable_list_item_1代表的一个textview中,该textview将作为ArryAdapter的列表组件。

放好后我们就把Adapter反到ListView中就ok了,setListAdapter(adapter); 前面省略了默认的全屏 ListView 。

fragment算是写好了,现在要写一个activity来托管这个fragmnet了

看看代码

 1 package com.example.leiyunjie.crime;
 2 
 3 import android.support.v4.app.Fragment;
 4 
 5 /**
 6  * Created by leiyunjie on 2016/4/21.
 7  */
 8 public class CrimeListActivity extends SingleFragmentActivity {
 9     @Override
10     protected Fragment createFragment(){
11         return new CrimeListFragment();
12     }
13 }
crimelistactivity

是的,我们完全可以和上次写的activity代码一样,只不过要在一下代码段

if(fragment==null){
    fragment=XXXXXX;
    fm.beginTransaction()
   .add(R.id.fragment,fragment)
    .commit();
}
}

对就是 fragment=XXXXXX;这里不一样,如果我们要写很多不同的activity去托管fragment时,大部分代码就是在重复,这时我们可以考虑建立一个抽象类去减少重复代码

我们建立一个singlefragmentactivity类

 1 package com.example.leiyunjie.crime;
 2 
 3 import android.os.Bundle;
 4 import android.support.v4.app.Fragment;
 5 import android.support.v4.app.FragmentActivity;
 6 import android.support.v4.app.FragmentManager;
 7 
 8 /**
 9  * Created by leiyunjie on 2016/4/21.
10  */
11 public abstract class SingleFragmentActivity extends FragmentActivity {
12      protected abstract Fragment createFragment();
13     @Override
14     public void onCreate(Bundle saveInstanceState){
15         super.onCreate(saveInstanceState);
16         setContentView(R.layout.activity_fragment);
17         FragmentManager fm=getSupportFragmentManager();
18         Fragment fragment=fm.findFragmentById(R.id.fragment);
19         if(fragment==null){
20             fragment=createFragment();
21             fm.beginTransaction()
22                     .add(R.id.fragment,fragment)
23                     .commit();
24         }
25     }
26 }
SingleFragmentActivity

是的,在里面我使用了fragment=createFragment();

然后我们再新建activity时只要继承该抽象类,然后去实现该方法就ok了;

比如我们回到上一篇的文章,把其中的activity.java文件进行修改

package com.example.leiyunjie.crime;

import android.support.v4.app.Fragment;

public class crimeActivity extends SingleFragmentActivity {

    @Override
    protected Fragment createFragment(){
        return new crimeFragmnet();
    }
}

现在的代码清爽多了不是。

总结一下,这部分还是很简单的,就比上一篇文章多了arrayliat和arryadapter,以及建了个抽象类。注意这次我们继承的是listfragment类,所以不需要为fragment指定布局文件,其次activity的布局文我们还是使用的上次的布局文件,也就是在SingleFragmentActivity中的

public void onCreate(Bundle saveInstanceState){
super.onCreate(saveInstanceState);
setContentView(R.layout.activity_fragment);
......
这也大大将少了代码量,以后的学习中要尽量养成这种简约的习惯,养成良好的代码习惯

 

 

 

 



 

 

posted @ 2016-04-22 12:08  给世界一点光  阅读(629)  评论(0编辑  收藏  举报