«

Android Fragment学习笔记(2) ----使用ListFragment显示列表(上)

时间:2024-3-2 17:25     作者:韩俊     分类: Android


上文的创建的“陋习”app模型层仅包含一个Crime实例,下面将添加一个包含Crime的列表


app的模型层将新增一个CrimeLab对象,该对象是一个数据集中存储池,用来存储Crime对象。当然也应相应的增加一个CrimeListActivity和CrimeListFragment。

1.更新CriminalIntent的模型层
单例与数据集中存储
在本app中,crime数组对象将存储在一个单例里。单例是特殊的Java类,在创建实例时,一个类仅允许创建一个实例

创建单例(CrimeLab.java):

<span style="font-family:Microsoft YaHei;">package com.example.crimialintent;

import android.content.Context;

/*
 * 在本app中,crime数组对象将存储在一个单例里。单例是特殊的Java类,在创建实例时,一个类仅允许创建一个实例
 * 应用在内存存在多久,单例就能存在多久
 * 要创建单例,须创建一个带有似有构造方法及get()方法的类,其中get()方法返回实例。
 */
public class CrimeLab {

    private static CrimeLab sCrimeLab;  //s前缀代表静态变量
    private Context mAppContext;

    private CrimeLab(Context appContext){
        mAppContext = appContext;
    }

/**
 * 注意在此方法中,我们并没有直接将Context参数传给构造方法,以为该context可能是activity或者另一个context对象,在应用整个
 * 生命周期中我们无法保证CrimeLab需要用到context,context就一直存在,所以,为了保证单例总是有Context可以使用,可以调用
 * getApplicationContext()方法。
 */
    public static CrimeLab get(Context c){

        if (sCrimeLab == null) {
            sCrimeLab = new CrimeLab(c.getApplicationContext());
        }
        return sCrimeLab;

    }

}
</span>

创建可容纳Crime对象的ArrayList (CrimeLab.java)
下面我们将Crime对象保存到CrimeLab中去。在CrimeLab的构造方法里,创建一个空的用来保存Crime对象的ArrayList。此外在添加getCrimes()和getCrime(UUID)方法。前者返回数组列表,后者返回带有指定ID的Crime对象。

<span style="font-family:Microsoft YaHei;">package com.example.crimialintent;

import java.util.ArrayList;
import java.util.UUID;

import android.content.Context;

/*
 * 在本app中,crime数组对象将存储在一个单例里。单例是特殊的Java类,在创建实例时,一个类仅允许创建一个实例
 * 应用在内存存在多久,单例就能存在多久
 * 要创建单例,须创建一个带有似有构造方法及get()方法的类,其中get()方法返回实例。
 */
public class CrimeLab {

    private static CrimeLab sCrimeLab; // s前缀代表静态变量
    private Context mAppContext;

    private ArrayList<Crime> mCrimes;

    private CrimeLab(Context appContext) {
        mAppContext = appContext;
        mCrimes = new ArrayList<Crime>();

        //生成100个crime
        for (int i = 0; i < 100; i++) {
            Crime c = new Crime();
            c.setTitle("第" + i +"个Crime");
            c.setSolved(i % 2 == 0);
            mCrimes.add(c);

        }
    }

    /**
     * 注意在此方法中,我们并没有直接将Context参数传给构造方法,以为该context可能是activity或者另一个context对象,在应用整个
     * 生命周期中我们无法保证CrimeLab需要用到context,context就一直存在,所以,为了保证单例总是有Context可以使用,可以调用
     * getApplicationContext()方法。
     */
    public static CrimeLab get(Context c) {

        if (sCrimeLab == null) {
            sCrimeLab = new CrimeLab(c.getApplicationContext());
        }
        return sCrimeLab;

    }

    public ArrayList<Crime> getCrimes() {
        return mCrimes;
    }

    public Crime getCrime(UUID id){
        for (Crime c : mCrimes){
            if(c.getId().equals(id))
                return c;
        }
        return null;
    }

}
</span>

2.创建ListFragment
继承自ListFragment。

CrimeListFragment.java

<span style="font-family:Microsoft YaHei;">package com.example.crimialintent;

import java.util.ArrayList;

import android.os.Bundle;
import android.support.v4.app.ListFragment;

public class CrimeListFragment extends ListFragment { //继承自android.support.v4.app

    private ArrayList<Crime> mCrimes;
    /*
     * 该fragment便利方法不仅可以返回托管的activity,且允许fragment处理更多的frgment事务。
     */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        getActivity().setTitle(R.string.crime_title);//设置操作栏的标题
    /**
     * CrimelistFragment需要先获取存储在CrimeLab中的Crime列表。
     */
        mCrimes = CrimeLab.get(getActivity()).getCrimes();  

    }
}</span>

3.使用抽象activity托管fragment 下面我们创建一个用于托管CrimeListFragment的CrimeListActivity类,当然首先还是为他创建视图。 对于CrimeListActivity,我们仍可以使用定义在activity_crime.xml文件中的布局。布局文件中并没有指定一个特定的fragment,因此只要有activity托管一个fragment,我们就可以使用该布局文件,为了显示通用性,我们将它重命名为activity_fragment.xml
<span style="font-family:Microsoft YaHei;"><FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/fragmentContainer"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.example.crimialintent.CrimeActivity" >

</FrameLayout>
</span>

抽象activity类: 回顾我们前面写的CrimeActivity类,该类代码几近通用,唯一不同的地方就是CrimeFragment类在添加到FragmentManager之前的实例化代码部分:
<span style="font-family:Microsoft YaHei;">fragment = new CrimeFragment();</span>
为避免重复性输入,我们创建一个名为SingleFragmentActivity的新类,选择FragmentActivity类作为它的超类,然后勾选abstract选项,让其成为一个抽象类 添加一个通用超类(SingleFragmentActivity):
<span style="font-family:Microsoft YaHei;">package com.example.crimialintent;

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;

public abstract class SimpleFragmentActivity extends FragmentActivity {
    protected abstract Fragment createFragment();//>>>>>>>>>>比原CrimeActivity多添加一个抽象方法,我们可以用它实例化新的fragment

    @Override
    public void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_fragment);

        /*
         * 将Fragment添加到activity中: 1.获取FragmentManager
         * 2.获取一个Fragment交由FragmentManager管理
         */
        FragmentManager fm = getSupportFragmentManager();// 获取FragmentManager本身
        Fragment fragment = fm.findFragmentById(R.id.fragmentContainer);//通过资源ID向FragmentMananger请求获取Fragment

        if (fragment == null) {
            fragment = createFragment(); //>>>>>>>>>>>>>>>>>>>>>>>>
                                        //>>>>此处与原来的CrimeActivity(fragment = new CrimeFragment();)代码略有不同

            //创建一个新的Fragment事务,加入一个添加操作,然后提交事务
            fm.beginTransaction().add(R.id.fragmentContainer, fragment)
                    .commit();
        }

    }

}
</span>
使用抽象类(CrimeListActivity.java):
<span style="font-family:Microsoft YaHei;">package com.example.crimialintent;

import android.support.v4.app.Fragment;

public class CrimeListActivity extends SimpleFragmentActivity {

    @Override
    protected Fragment createFragment() {
        // TODO Auto-generated method stub
        return new CrimeListFragment(); // 实现该方法并返回一个新的CrimeListFragment实例
    }

}
</span>
CrimeActivity.java:
<span style="font-family:Microsoft YaHei;">package com.example.crimialintent;

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;

public class CrimeActivity extends FragmentActivity { //继承自FragmentActivity

    private Fragment createFragment() {
        // TODO Auto-generated method stub
        return new CrimeFragment();
    }

}
</span>
到真机运行一下

当前还没有内容,但是CrimeListFragment已经被赋予了访问Crime的能力,休息下~ 我们将crime列表通过listview显示在屏幕上







标签: android

热门推荐