ListFragment简介与用法

来源:互联网 发布:android 电子商城源码 编辑:程序博客网 时间:2024/06/05 10:06

创建存储数据的单例类

package com.huangfei.criminalintent;import java.util.Date;import java.util.UUID;public class Crime {    private UUID mId;    private String mTitle;    private Date mDate;    private boolean mSolved;    public Crime(){        //生成唯一标识符        mId = UUID.randomUUID();        setDate(new Date());    }    public String getTitle() {        return mTitle;    }    public void setTitle(String title) {        mTitle = title;    }    public UUID getId() {        return mId;    }    public Date getDate() {        return mDate;    }    public void setDate(Date date) {        mDate = date;    }    public boolean isSolved() {        return mSolved;    }    public void setSolved(boolean solved) {        mSolved = solved;    }    @Override    public String toString() {        return mTitle;    }}
package com.huangfei.criminalintent;import java.util.ArrayList;import java.util.UUID;import android.content.Context;/** *  * @author huangfeihong * CrimeLab类是单例模式。应用能在内存里存在多久,单例就能存在多久,因此将对象列表保存在单例里可保持crime数据的一直存在, * 不管activity、fragment及它们的生命周期发生什么变化。 */public class CrimeLab {    private ArrayList<Crime> mCrimes;    private static CrimeLab sCrimeLab;    private Context mAppContext;    private CrimeLab(Context appContext){        mAppContext = appContext;        mCrimes = new ArrayList<Crime>();        for (int i = 0; i < 100; i++) {            Crime crime = new Crime();            crime.setTitle("Crime #" + i);            crime.setSolved(i % 2 == 0);            mCrimes.add(crime);        }    }    /**     * 在get(Context)方法里,我们并没有直接将Context参数传递给构造方法。该Context可能是一个Activity,也可能是另一个Context对象,     * 如Serivie。在应用的整个生命周期里,我们无法保证只要CrimeLab需要用到Context对象,Context就一定存在。     * 因此,为保证单例总是有Context可以使用,可调用getApplicationContext()方法,将不确定是否存在的Context对象替换成 application context。     * application context是针对应用的全局性Context。任何时候,只要应用层面的单例,就该一直使用application context。     */    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 crime : mCrimes) {            if(crime.getId().equals(id))//UUID之间比较方式                return crime;        }        return null;    }}

创建ListFragment

package com.huangfei.criminalintent;import java.util.ArrayList;import android.os.Bundle;import android.support.v4.app.ListFragment;import android.util.Log;import android.view.View;import android.view.ViewGroup;import android.widget.ArrayAdapter;import android.widget.CheckBox;import android.widget.ListView;import android.widget.TextView;/** *  * @author huangfeihong 无需覆盖onCreateView(...)方法或为CrimeListFragment生成布局。 *         ListFragment类默认实现方法已经生成了一个全屏ListView布局。 */public class CrimeListFragment extends ListFragment {    private static final String TAG = "CrimeListFragment";    private ArrayList<Crime> mCrimes;    @Override    public void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        // 设置操作栏(旧版本设备为标题栏)上的标题文字        getActivity().setTitle(R.string.crimes_title);        mCrimes = CrimeLab.get(getActivity()).getCrimes();        /**         * android.R.layout.simple_list_item_1是Android         * SDK提供的预定义布局资源。该布局拥有一个TextView根元素。 也可指定其他布局,只要满足布局的根元素是TextView即可。         *          * 默认的ArrayAdapter<T>.getView(...)实现方法依赖于toString()方法。它首先生成布局视图,         * 然后找到指定位置的Crime对象并对其调用 toString()方法,最后得到字符串信息并传递给TextView。         *///      ArrayAdapter<Crime> adapter = new ArrayAdapter<Crime>(getActivity(),//              android.R.layout.simple_list_item_1, mCrimes);        CrimeAdapter adapter = new CrimeAdapter(mCrimes);        // 该方法是ListFragment类的便利方法,使用它可为CrimeListFragment管理的内置ListView设置adapter。        setListAdapter(adapter);    }    /**     * 响应用户对列表项的点击事件     */    @Override    public void onListItemClick(ListView l, View v, int position, long id) {        super.onListItemClick(l, v, position, id);        Crime crime = (Crime) getListAdapter().getItem(position);        Log.d(TAG, crime.getTitle() + "was clicked");    }    private class CrimeAdapter extends ArrayAdapter<Crime> {        public CrimeAdapter(ArrayList<Crime> crimes) {            /**             * 这里调用超类的构造方法来绑定Crime对象的数组列表。由于不打算使用预定义布局, 我们传入0作为布局参数。             */            super(getActivity(), 0, crimes);        }        @Override        public View getView(int position, View convertView, ViewGroup parent) {            if (convertView == null)                convertView = getActivity().getLayoutInflater().inflate(                        R.layout.list_item_crime, null);            Crime crime = getItem(position);            TextView titleTextView = (TextView) convertView                    .findViewById(R.id.crime_list_item_titleTextView);            titleTextView.setText(crime.getTitle());            TextView dateTextView = (TextView) convertView                    .findViewById(R.id.crime_list_item_dateTextView);            dateTextView.setText(crime.getDate().toLocaleString());            /**             * CheckBox默认是聚焦的。这意味着,点击列表项会被解读为切换CheckBox的状态,自然也就无法触发onListItemClick(...)方法了。             * 由于ListView的这种内部特点,出现在列表项布局内的任何可聚焦组件(如CheckBox或Button)都应设置为非聚焦状态(android:focusable="false"),             * 从而保证用户点击列表项后能够获得预期效果。             */            CheckBox solvedCheckBox = (CheckBox) convertView                    .findViewById(R.id.crime_list_item_solvedCheckBox);            solvedCheckBox.setChecked(crime.isSolved());            return convertView;        }    }}

创建托管Fragment的Activity

普通托管Fragment的通用Activity

package com.huangfei.criminalintent;import android.os.Bundle;import android.support.v4.app.Fragment;import android.support.v4.app.FragmentActivity;import android.support.v4.app.FragmentManager;/** *  * @author huangfeihong * 普通托管Fragment的通用Activity */public abstract class SingleFragmentActivity extends FragmentActivity {    protected abstract Fragment createFragment();     @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_fragment);        /**         * 因为使用了支持库及FragmentActivity类,因此这里调用的方法是getSupportFragmentManager()。如果不考虑Honeycomb以前版本的兼容性问题,         * 可直接继承Activity类并调用getFragmentManager()方法。         *          * FragmentManager类负责管理fragment并将它们的视图添加到activity的视图层级结构中。         * FragmentManager类具体管理的是:         *  1、fragment队列;         *  2、fragment事务的回退栈。         */        FragmentManager fm = getSupportFragmentManager();        Fragment fragment = fm.findFragmentById(R.id.fragmentContainer);        if(fragment == null){            fragment = createFragment();            /**             * 这段代码创建并提交一个fragment事务。             * fragment事务被用来添加、移除、附加、分离或替换fragment队列中的fragment。这是使用fragment             * 在运行时组装和重新组装用户界面的核心方式。FragmentManager管理着fragment事务的回退栈。             *              * add(容器视图资源ID, 新创建的fragment)             * 容器视图资源ID的作用:             *  1、告知FragmentManagerfragment视图应该出现在activity视图的什么地方;             *  2、是FragmentManager队列中fragment的唯一标识符,见第25行代码’             */            fm.beginTransaction().add(R.id.fragmentContainer, fragment).commit();        }    }}

实现普通托管Fragment的通用Activity

public class CrimeListActivity extends SingleFragmentActivity {    @Override    protected Fragment createFragment() {        return new CrimeListFragment();    }}

代码地址

0 0