Android UI Fragment探索之进阶篇

一、ListFragment、ListView及ArrayAdapter

  ListFragment的ListView将列表展示给用户,ListView是ViewGroup的子类,每一项都作为ListView的一个View子对象显示。那么,Veiw对象显示的视图从哪来呢?答案是adapter

  Adapter是一个控制器对象,从模型层获取数据,并将之提供给ListView显示,起到沟通桥梁的作用。Adapter负责:

  • 创建必要的视图对象。
  • 用模型层数据填充视图对象。
  • 将准备好的视图对象返回给ListVeiw。
     1 public class CrimeListFragment extends ListFragment
     2 {
     3     // method var
     4     private ArrayList<Crime> mCrimes;
     5 
     6     // method function
     7     @Override
     8     public void onCreate(Bundle savedInstanceState)
     9     {
    10         super.onCreate(savedInstanceState);
    11         getActivity().setTitle(R.string.crime_title);
    12         // data source
    13         mCrimes = CrimeLab.get(getActivity()).getCrimes();
    14 
    15         // 创建adapter数据源
    16         ArrayAdapter<Crime> adapter = new ArrayAdapter<Crime>(getActivity(),
    17                 android.R.layout.simple_list_item_1, mCrimes);
    18         // 添加adapter数据源
    19         setListAdapter(adapter);
    20     }
    21 
    22 }

     PS:默认的ArrayAdapter<T>.getView(...)实现方法依赖于toString()方法。它首先生成布局的视图,然后找到指定位置的数据源对象,并对其调用toString()方法,最后,得到字符串信息并传递给UI控件。

二、使用自定义列表项

  1. 创建list_item_crime.xml文件:
     1 <RelativeLayout
     2     xmlns:android="http://schemas.android.com/apk/res/android"
     3     xmlns:tools="http://schemas.android.com/tools"
     4     android:layout_width="match_parent"
     5     android:layout_height="match_parent">
     6 
     7     <CheckBox
     8         android:id="@+id/list_item_checkbox"
     9         android:layout_width="wrap_content"
    10         android:layout_height="wrap_content"
    11         android:gravity="center"
    12         android:layout_alignParentRight="true"
    13         android:enabled="false"
    14         android:padding="4dp"/>
    15 
    16     <TextView
    17         android:id="@+id/list_item_titletext"
    18         android:layout_width="match_parent"
    19         android:layout_height="wrap_content"
    20         android:layout_toLeftOf="@+id/list_item_checkbox"
    21         android:textStyle="bold"
    22         android:paddingLeft="4dp"
    23         android:paddingRight="4dp"
    24         android:text="Crime title"/>
    25 
    26     <TextView
    27         android:id="@+id/list_item_datetext"
    28         android:layout_width="match_parent"
    29         android:layout_height="wrap_content"
    30         android:layout_below="@+id/list_item_titletext"
    31         android:layout_toLeftOf="@+id/list_item_checkbox"
    32         android:paddingLeft="4dp"
    33         android:paddingRight="4dp"
    34         android:text="Crime date"/>
    35 
    36 </RelativeLayout>

     

  2. 继承ArrayAdapter<T>类,重写获取getView(...)方法(继承这部分这里使用Java的内部类实现):
     1 public class CrimeListFragment extends ListFragment
     2 {
     3     // method var
     4     private ArrayList<Crime> mCrimes;
     5     // click item tag
     6     private static final String sTag = "CrimeListFragment";
     7 
     8     // method function
     9     @Override
    10     public void onCreate(Bundle savedInstanceState)
    11     {
    12         super.onCreate(savedInstanceState);
    13         getActivity().setTitle(R.string.crime_title);
    14         // data source
    15         mCrimes = CrimeLab.get(getActivity()).getCrimes();
    16 
    17         // 创建adapter数据源
    18         CrimeAdapter adapter = new CrimeAdapter(mCrimes);
    19         // 添加adapter数据源
    20         setListAdapter(adapter);
    21     }
    22 
    23     @Override
    24     public void onListItemClick(ListView l, View v, int position, long id)
    25     {
    26         Crime c = (Crime)(getListAdapter()).getItem(position);
    27 //        Crime c = (CrimeAdapter)(getListAdapter().getItem(position));
    28         Log.d(sTag, c.getmTitle() + " was clicked.");
    29     }
    30 
    31     public class CrimeAdapter extends ArrayAdapter<Crime>
    32     {
    33         public CrimeAdapter(ArrayList<Crime> crimes)
    34         {
    35             super(getActivity(), 0, crimes);
    36         }
    37 
    38         @Override
    39         public View getView(int position, View convertView, ViewGroup parent)
    40         {
    41             if (null == convertView)
    42             {
    43                 convertView = getActivity().getLayoutInflater()
    44                         .inflate(R.layout.list_item_crime, null);
    45             }
    46             Crime c = getItem(position);
    47 
    48             TextView title = (TextView)convertView.findViewById(R.id.list_item_titletext);
    49             title.setText(c.getmTitle());
    50             TextView date = (TextView)convertView.findViewById(R.id.list_item_datetext);
    51             date.setText(c.getmDate().toString());
    52             CheckBox solved = (CheckBox)convertView.findViewById(R.id.list_item_checkbox);
    53             solved.setEnabled(c.getmSolved());
    54 
    55             return convertView;
    56         }
    57     }
    58 
    59 }

    PS: 这里有一点需要注意,由于列表项中,有CheckBox控件,CheckBox默认是可聚焦的,所以,点击列表项会被解读为切换CheckBox状态,自然也就不能触发onListItemClick(...)方法。解决方法为,将CheckBox默认聚焦设置false即可。

    1 android:focusable="false"

     

你可能感兴趣的:(Android UI Fragment探索之进阶篇)