本节主要学习ListFragment的用法。
1.更新模型层,创建一个 CrimeLab 类用于存储多个Crime对象
CrimeLab采用单例模式,以便数据的集中存储
package com.criminalintent; import android.content.Context; import java.util.ArrayList; import java.util.List; import java.util.UUID; public class CrimeLab { private List<Crime> crimeList; private Context context; private CrimeLab(Context context){ this.context=context; crimeList=new ArrayList<Crime>(); for(int i=0;i<100;i++){ Crime crime=new Crime(); crime.setTitle("item"+i); crime.setSolved(i%2==0); crimeList.add(crime); } } private static CrimeLab instance; public static CrimeLab getInstance(Context context){ if(instance==null) instance=new CrimeLab(context.getApplicationContext()); return instance; } public List<Crime> getCrimeList(){ return crimeList; } public Crime getCrime(UUID uuid){ for(Crime c:crimeList){ if(c.getUuid()==uuid) return c; } return null; } }
2.创建 CrimeListFragment类以及CrimeAdapter内部类
该类继承于ListFragment类,也就是本节主要的学习内容,ListFragment中默认有一个ListView对象,所以我们不用再新创建一个ListView控件的视图,只需要实现Adapter控制器对象,然后调用setListAdapter(adapter)方法即可。
在此之前,我们先准备好Adapter需要的子布局视图 list_item_crime.xml
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content"> <CheckBox android:id="@+id/crime_list_item_solvedCheckBox" android:layout_width="wrap_content" android:layout_height="wrap_content" android:gravity="center" android:layout_alignParentRight="true" android:enabled="false" android:focusable="false" android:padding="4dp" /> <TextView android:id="@+id/crime_list_item_titleTextView" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_toLeftOf="@id/crime_list_item_solvedCheckBox" android:textStyle="bold" android:paddingLeft="4dp" android:paddingRight="4dp" android:text="Crime title" /> <TextView android:id="@+id/crime_list_item_dateTextView" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_below="@id/crime_list_item_titleTextView" android:layout_toLeftOf="@id/crime_list_item_solvedCheckBox" android:paddingLeft="4dp" android:paddingRight="4dp" android:paddingTop="4dp" android:text="Crime date" /> </RelativeLayout>
接下来创建CrimeListFragment
public class CrimeListFragment extends ListFragment { private List<Crime> crimeList; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); crimeList=CrimeLab.getInstance(getActivity()).getCrimeList(); getActivity().setTitle(R.string.crimes_title); // 构造adpter CrimeAdapter adapter=new CrimeAdapter(getActivity(),R.layout.list_item_crime,crimeList); setListAdapter(adapter); } @Override public void onListItemClick(ListView l, View v, int position, long id) { Crime crime= (Crime) getListAdapter().getItem(position); Log.d("item",crime.getTitle() + " was clicked"); } // CrimeAdapter控制ListView控件中的每个子布局如何显示,所以构造 CrimeAdapter需要一个子项布局视图,和数据链表 // 在此为 R.layout.list_item_crime和crimeList class CrimeAdapter extends ArrayAdapter<Crime>{ public CrimeAdapter(Context context, int resource, List<Crime> objects) { super(context, resource, objects); } @Override public View getView(int position, View convertView, ViewGroup parent) { Crime crime=getItem(position); if(convertView==null){ convertView=LayoutInflater.from(getContext()).inflate(R.layout.list_item_crime,null); } 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().toString()); CheckBox checkBox= (CheckBox) convertView.findViewById(R.id.crime_list_item_solvedCheckBox); checkBox.setChecked(crime.isSolved()); return convertView; } } }
3.抽象Activity类
在Activity的代码中,除了创建fragment的代码不同,其他都一样,所以可以将相同的代码抽出来,形成一个抽象父类。创建fragment的代码,写成一个抽象方法createFragment(),以后每创建一个Activity都只需重写creatFragment()方法即可。下面就是抽象出来的类
public abstract class SingleFragmentActivity extends FragmentActivity { protected abstract Fragment createFragment(); @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); FragmentManager fm=getSupportFragmentManager(); Fragment fragment=fm.findFragmentById(R.id.fragmentContainer); if(fragment==null){ fragment=createFragment(); fm.beginTransaction() .add(R.id.fragmentContainer,fragment) .commit(); } } }
4.修改MainActivity类,让其继承SingleFragmentActivtity,并重写createFragment方法
public class MainActivity extends SingleFragmentActivity { @Override protected Fragment createFragment() { return new CrimeListFragment(); } }
最后运行效果如下: