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"

     

三、向FrameLayout容器中,动态载入一个Layout布局对象

  在fragment_main.xml文件中,FrameLayout标签中,嵌入一个FrameLayout标签:

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <LinearLayout
 3     xmlns:android="http://schemas.android.com/apk/res/android"
 4     android:orientation="vertical"
 5     android:layout_width="match_parent"
 6     android:layout_height="match_parent">
 7 
 8     <LinearLayout
 9         android:layout_width="match_parent"
10         android:layout_height="wrap_content">
11 
12         <TextView
13             android:layout_width="wrap_content"
14             android:layout_height="wrap_content"
15             android:text="@string/main_name"
16             android:textColor="#000"
17             android:textSize="14sp"/>
18 
19         <EditText
20             android:id="@+id/name"
21             android:layout_width="match_parent"
22             android:layout_height="wrap_content"
23             android:textSize="14sp"
24             android:textColor="#000"/>
25 
26     </LinearLayout>
27 
28     <LinearLayout
29         android:layout_width="match_parent"
30         android:layout_height="wrap_content">
31 
32         <TextView
33             android:layout_width="wrap_content"
34             android:layout_height="wrap_content"
35             android:text="@string/main_tel"
36             android:textColor="#000"
37             android:textSize="14sp"/>
38 
39         <EditText
40             android:id="@+id/tel"
41             android:layout_width="match_parent"
42             android:layout_height="wrap_content"
43             android:textSize="14sp"
44             android:textColor="#000"/>
45 
46     </LinearLayout>
47 
48     <LinearLayout
49         android:layout_width="match_parent"
50         android:layout_height="wrap_content"
51         android:orientation="horizontal"
52         android:gravity="center">
53 
54         <Button
55             android:id="@+id/insert"
56             android:layout_width="wrap_content"
57             android:layout_height="wrap_content"
58             android:text="@string/main_insert"
59             android:textColor="#000"/>
60 
61         <Button
62             android:id="@+id/query"
63             android:layout_width="wrap_content"
64             android:layout_height="wrap_content"
65             android:text="@string/main_query"
66             android:textColor="#000"/>
67 
68     </LinearLayout>
69 
70     <FrameLayout
71         android:id="@+id/user_list"
72         android:layout_width="match_parent"
73         android:layout_height="wrap_content">
74 
75         </FrameLayout>
76 
77 </LinearLayout>

  在代码中,为user_list动态载入一个ListFragment元素,(UserListFragment):

1 public class UserListFragment extends ListFragment
2 {
3 ......
4 }

  将UserListFragment嵌入FrameLayout布局标签中:

1 // 获取Fragment管理系统对象
2 FragmentManager fm = getFragmentManager();
3 // 创建一个fragment对象
4 UserListFragment userListFragment = UserListFragment.newInstance(data);
5 // 通过Fragment管理器,将新创建的fragment对象添加到指定的布局容器中
6 fm.beginTransaction().add(R.id.user_list, userListFragment).commit();

 

posted @ 2016-03-23 23:01  naray  阅读(252)  评论(0编辑  收藏  举报