【正文】
一、ListFragement的介绍:
ListFragment继承于Fragment。因此它具有Fragment的特性,能够作为activity中的一部分,目的也是为了使页面设计更加灵活。相比Fragment,ListFragment的内容是以列表(list)的形式显示的。
1、ListFragment布局:
ListFragment的默认布局包含一个list view。因此,在ListFragment对应的布局文件中,必须指定一个 android:id 为 “@android:id/list” 的ListView控件! 若用户想修改listview,可以在onCreateView(LayoutInflater, ViewGroup, Bundle)中进行修改。当然,用户也可以在ListFragment的布局中包含其它的控件。
下面是官方文档中ListFragment对应的一个layout示例:
01.
<?xml version=
'1.0'
encoding=
'utf-8'
?>
02.
<LinearLayout xmlns:android=
'http://schemas.android.com/apk/res/android'
03.
android:orientation=
'vertical'
04.
android:layout_width=
'match_parent'
05.
android:layout_height=
'match_parent'
06.
android:paddingLeft=
'8dp'
07.
android:paddingRight=
'8dp'
>
08.
09.
<ListView android:id=
'@id/android:list'
10.
android:layout_width=
'match_parent'
11.
android:layout_height=
'match_parent'
12.
android:background=
'#00FF00'
13.
android:layout_weight=
'1'
14.
android:drawSelectorOnTop=
'false'
/>
15.
16.
<TextView android:id=
'@id/android:empty'
17.
android:layout_width=
'match_parent'
18.
android:layout_height=
'match_parent'
19.
android:background=
'#FF0000'
20.
android:text=
'No data'
/>
21.
</LinearLayout>
ListView中每一行的显示内容,是通过设置适配器ListAdapter来实现的。我们既可以自定义,也可以采用系统默认的layout。后面的应用实例中,会分别列举2种情况下的显示
2、绑定数据:
ListFragment绑定ListView的数据(即绑定适配器)时,必须通过ListFragment.setListAdapter()接口来绑定数据,而不是使用ListView.setAdapter() 或其它方法
二、通过ArrayAdapter来加载ListFragment的举例:
【举例】现在将平板电脑分成三部分:点击左侧的按钮,出现中间的新闻标题列表(ListFragment),点击中间ListFragment的某个item,在最右侧的fragment中显示详情。
新建工程文件m01_ListFragment01:
(1)定义activity_main.xml的布局:
activity_main.xml的代码如下:
01.
<LinearLayout xmlns:android=
'http://schemas.android.com/apk/res/android'
02.
xmlns:tools=
'http://schemas.android.com/tools'
03.
android:layout_width=
'match_parent'
04.
android:layout_height=
'match_parent'
05.
tools:context=
'.MainActivity'
>
06.
07.
<LinearLayout
08.
android:id=
'@+id/left'
09.
android:layout_width=
'0dp'
10.
android:layout_height=
'match_parent'
11.
android:layout_weight=
'1'
12.
android:background=
'#cccccc'
13.
android:orientation=
'horizontal'
>
14.
15.
<Button
16.
android:id=
'@+id/button1'
17.
android:layout_width=
'match_parent'
18.
android:layout_height=
'wrap_content'
19.
android:textSize=
'14sp'
20.
android:text=
'show ListFragment'
/>
21.
</LinearLayout>
22.
23.
<LinearLayout
24.
android:id=
'@+id/center'
25.
android:layout_width=
'0dp'
26.
android:layout_height=
'match_parent'
27.
android:layout_weight=
'2'
28.
android:background=
'#AFEEEE'
29.
android:orientation=
'vertical'
>
30.
</LinearLayout>
31.
32.
<LinearLayout
33.
android:id=
'@+id/center'
34.
android:layout_width=
'0dp'
35.
android:layout_height=
'match_parent'
36.
android:layout_weight=
'2'
37.
android:background=
'#00FFFF'
38.
android:orientation=
'vertical'
>
39.
</LinearLayout>
40.
41.
</LinearLayout>
实际上分配了三个线性布局,左侧显示按钮,中间显示标题,右侧显示详情。这个布局文件对应的可视化界面如下:
(2)定义中间的ListFragment,即新建文件ArticleListFragment.java:
ArticleListFragment.java的代码如下:
01.
1
package
com.example.m01_listfragment01;
02.
2
03.
3
import
java.util.ArrayList;
04.
4
import
java.util.List;
05.
5
06.
6
import
android.app.ListFragment;
07.
7
import
android.os.Bundle;
08.
8
import
android.view.LayoutInflater;
09.
9
import
android.view.View;
10.
10
import
android.view.ViewGroup;
11.
11
import
android.widget.ArrayAdapter;
12.
12
13.
13
public
class
ArticleListFragment
extends
ListFragment {
14.
14
15.
15
private
ArrayAdapter<String> adapter;
16.
16
17.
17
@Override
18.
18
public
void
onCreate(Bundle savedInstanceState) {
19.
19
// TODO Auto-generated method stub
20.
20
super
.onCreate(savedInstanceState);
21.
21
22.
<strong>
22
//定义一个数组
23.
23
List<String> data =
new
ArrayList<String>();
24.
24
for
(
int
i =
0
; i <
30
; i++) {
25.
25
data.add(
'smyh'
+ i);
26.
26
}
27.
27
//将数组加到ArrayAdapter当中
28.
28
adapter =
new
ArrayAdapter<String>(getActivity(),
29.
29
android.R.layout.simple_list_item_1, data);
30.
30
//绑定适配器时,必须通过ListFragment.setListAdapter()接口,而不是ListView.setAdapter()或其它方法
31.
31
setListAdapter(adapter);
32.
</strong>
32
}
33.
33
34.
34
@Override
35.
35
public
View onCreateView(LayoutInflater inflater, ViewGroup container,
36.
36
Bundle savedInstanceState) {
37.
37
// TODO Auto-generated method stub
38.
38
return
super
.onCreateView(inflater, container, savedInstanceState);
39.
39
}
40.
40
41.
41
@Override
42.
42
public
void
onPause() {
43.
43
// TODO Auto-generated method stub
44.
44
super
.onPause();
45.
45
}
46.
46
}
核心代码是22至32行:我们让这个Fragment继承ListFragment,然后在onCreate()方法中定义一个ArrayAdapter,将数据放进去,最后绑定适配器就行了。需要注意的是,由于我们继承的是ListFragment,这个Fragment默认自带了一个布局,所以我们不需要重新新建布局文件了。
(3)将中间的ListFragment加载到Activity当中去。当我们点击按钮时,就开始加载这个Fragment:
MainActivity.java的代码如下:
01.
1
package
com.example.m01_listfragment01;
02.
2
03.
3
import
android.app.Activity;
04.
4
import
android.app.FragmentManager;
05.
5
import
android.app.FragmentTransaction;
06.
6
import
android.os.Bundle;
07.
7
import
android.view.Menu;
08.
8
import
android.view.View;
09.
9
import
android.view.View.OnClickListener;
10.
10
import
android.widget.Button;
11.
11
12.
12
public
class
MainActivity
extends
Activity {
13.
13
14.
14
private
FragmentManager manager;
15.
15
private
FragmentTransaction transaction;
16.
16
@Override
17.
17
protected
void
onCreate(Bundle savedInstanceState) {
18.
18
super
.onCreate(savedInstanceState);
19.
19
setContentView(R.layout.activity_main);
20.
20
Button button = (Button) findViewById(R.id.button1);
21.
21
button.setOnClickListener(
new
OnClickListener() {
22.
22
23.
23
//点击按钮,加载ListFragment
24.
<strong>
24
@Override
25.
25
public
void
onClick(View v) {
26.
26
// TODO Auto-generated method stub
27.
27
manager = getFragmentManager();
28.
28
transaction = manager.beginTransaction();
29.
29
ArticleListFragment articleListFragment =
new
ArticleListFragment();
30.
30
transaction.add(R.id.center, articleListFragment,
'article'
);
31.
31
transaction.commit();
32.
32
}
33.
</strong>
33
});
34.
34
35.
35
}
36.
36
37.
37
@Override
38.
38
public
boolean
onCreateOptionsMenu(Menu menu) {
39.
39
// Inflate the menu; this adds items to the action bar if it is present.
40.
40
getMenuInflater().inflate(R.menu.main, menu);
41.
41
return
true
;
42.
42
}
43.
43
}
这个代码比较简单,就不多解释了。
现在运行程序,初始界面如下:
点击左侧的按钮后,显示如下:
注:如果想实现:点击中间的某个item,弹出吐司显示那个item中的内容,可以在上方的ArticleListFragment.java中的监听事件里添加如下代码:
(代码放置的位置是:让它和Fragment的生命周期方法并列就行了)
1.
1
@Override
2.
2
public
void
onListItemClick(ListView l, View v,
int
position,
long
id) {
3.
3
// TODO Auto-generated method stub
4.
4
super
.onListItemClick(l, v, position, id);
5.
5
String item = adapter.getItem(position);
6.
6
Toast.makeText(getActivity(), item,
1
).show();
7.
7
}
由此我们可以看到,监听事件的函数为onListItemClick(),可以直接写,不需要set。
这里面关键代码在第05行,通过getItem()接收那个item,然后用字符串来接收。
我们先去掉这部分的监听事件代码,继续往下看。
(4)点击中间ListFragment的item,加载右边的DetailFragment:
我们在中间ListFragment中添加一个按钮的监听事件,监听事件的函数为onListItemClick(),ArticleListFragment.java在上面代码的基础之上,添加的代码如下:
(代码放置的位置是:让它和Fragment的生命周期方法并列就行了)
01.
1
//点击按钮,加载最右侧的Fragment
02.
2
@Override
03.
3
public
void
onListItemClick(ListView l, View v,
int
position,
long
id) {
04.
4
// TODO Auto-generated method stub
05.
5
super
.onListItemClick(l, v, position, id);
06.
6
07.
7
//点击按钮后,加载右边的Fragment
08.
8
FragmentManager manager = getFragmentManager();
09.
9
FragmentTransaction transaction = manager.beginTransaction();
10.
10
DetailFragment detailFragment =
new
DetailFragment();
11.
11
//记住:这个地方必须用replace,而不是用add
12.
<strong>
12
transaction.replace(R.id.right, detailFragment,
'detailFragment'
);
13.
</strong>
13
14.
<strong>
14
//将中间的item的内容放到Bundle对象当中,然后放到最右侧Frament的参数当中
15.
15
String item = adapter.getItem(position);
16.
16
Bundle args =
new
Bundle();
17.
17
args.putString(
'item'
,item);
18.
18
detailFragment.setArguments(args);
19.
19
//</strong><strong>Toast.makeText(getActivity(), item, 1).show(); </strong>
20.
20
21.
21
transaction.commit();
22.
22
}
上面的代码中,我们是在中间的Fragment中点击按钮,然后加载右边的Fragment,然后要注意14至18行的核心代码,看一下它是如何通过bundle来传递数据的。
需要注意的是,第12行代码必须用replace的方式加载右侧的fragment,而不是add;如果用add,运行的错误稍后将展示出来。
(5)定义右边的DetailFragment:
先定义布局文件,在里面加一个TextView,fragment_detail.xml的代码如下:
01.
<?xml version=
'1.0'
encoding=
'utf-8'
?>
02.
<LinearLayout xmlns:android=
'http://schemas.android.com/apk/res/android'
03.
android:layout_width=
'match_parent'
04.
android:layout_height=
'match_parent'
05.
android:orientation=
'vertical'
>
06.
07.
<TextView
08.
android:id=
'@+id/textView1'
09.
android:layout_width=
'wrap_content'
10.
android:layout_height=
'wrap_content'
11.
android:text=
'TextView'
/>
12.
</LinearLayout>
然后新建文件,DetailFragment.java的代码如下:
package com.example.m01_listfragment01;
01.
1
package
com.example.m01_listfragment01;
02.
2
03.
3
import
android.app.Fragment;
04.
4
import
android.os.Bundle;
05.
5
import
android.view.LayoutInflater;
06.
6
import
android.view.View;
07.
7
import
android.view.ViewGroup;
08.
8
import
android.widget.TextView;
09.
9
10.
10
public
class
DetailFragment
extends
Fragment {
11.
11
12.
12
13.
13
@Override
14.
14
public
void
onCreate(Bundle savedInstanceState) {
15.
15
// TODO Auto-generated method stub
16.
16
super
.onCreate(savedInstanceState);
17.
17
}
18.
18
19.
19
@Override
20.
20
public
View onCreateView(LayoutInflater inflater, ViewGroup container,
21.
21
Bundle savedInstanceState) {
22.
22
// TODO Auto-generated method stub
23.
23
View view = inflater.inflate(R.layout.fragment_detail,
null
);
24.
24
TextView textView = (TextView)view.findViewById(R.id.textView1);
25.
<strong>
25
textView.setText(
''
+getArguments().getString(
'item'
));
26.
</strong>
26
return
view;
27.
27
}
28.
28
29.
29
@Override
30.
30
public
void
onPause() {
31.
31
// TODO Auto-generated method stub
32.
32
super
.onPause();
33.
33
}
34.
34
}
核心代码是第25行,仔细看一下我们是怎么通过键值对来拿到中间的Fragment传递过来的item的内容。
现在运行程序,一次点击左边的按钮和中间的item,效果如下:
如果我们在中间的Fragment中错误地通过add方式加载右边的Fragment,而不是通过replace方式,最终错误的效果如下:
也就是说,每点击一次中间的item,就会在右边继续加载一个文本,而不是替代的方式,很显然,这种方式不是我们想要的。
文章来源:http://www.cnblogs.com/smyhvae/p/4000483.html
联系方式:smyhvae@163.com