Android是在Android 3.0(API level 11)開(kāi)始引入Fragment的(為了兼容較低版本的設(shè)備使用支持庫(kù)類(lèi))??梢园袴ragment看成Activity中的模塊,這個(gè)模塊有自己的布局,有自己的生命周期(由托管activity調(diào)用其周期方法),單獨(dú)處理自己的輸入,在Activity運(yùn)行的時(shí)候可以加載或者移除Fragment模塊。
ListFragment是Fragment的子類(lèi),內(nèi)置列表顯示支持功能。ListFragment通過(guò)內(nèi)置的ListView顯示綁定在其上面的數(shù)據(jù)。下面就通過(guò)例子了解具體的用法:
1、模型層 Day類(lèi)和DayLab類(lèi)
通過(guò)DayLab對(duì)象的getDays()方法獲取用來(lái)綁定的數(shù)據(jù)。
Day.java
package com.example.showdays;
import java.util.ArrayList;
public class Day {
private String mTitle;
public String getTitle() {
return mTitle;
}
public void setTitle(String mTitle) {
this.mTitle = mTitle;
}
}
DayLab.java
package com.example.showdays;
import java.util.ArrayList;
public class DayLab {
private ArrayList<Day> mDays;
public DayLab() {
mDays = new ArrayList<Day>();
for (int i = 1; i <= 10; i++) {
Day day = new Day();
day.setTitle("Title #" + i);
mDays.add(day);
}
}
public ArrayList<Day> getDays() {
return mDays;
}
}
2、創(chuàng)建DayListFragment類(lèi)
繼承ListFragment類(lèi)。并給其內(nèi)置的ListView設(shè)置Adapter
DayListFragment.java
package com.example.showdays;
import java.util.ArrayList;
import android.os.Bundle;
import android.support.v4.app.ListFragment;
import android.widget.ArrayAdapter;
public class DayListFragment extends ListFragment {
private ArrayList<Day> days;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
DayLab dayLab = new DayLab();
this.days = dayLab.getDays();
ArrayAdapter<Day> adapter = new ArrayAdapter(getActivity(),
android.R.layout.simple_list_item_1, days);
// 第一個(gè)參數(shù): Context對(duì)象,使用第二個(gè)參數(shù)的資源ID需要該Context對(duì)象
// 第二個(gè)參數(shù): 資源ID,可定位ArrayAdapter用來(lái)創(chuàng)建View對(duì)象的布局,這里的實(shí)參是 Android SDK提供的預(yù)定義布局資源
// 第三個(gè)參數(shù): 數(shù)據(jù)集
setListAdapter(adapter);// 給DayListFragment內(nèi)置的ListView設(shè)置adapter
}
}
3、創(chuàng)建DayActivity類(lèi)
繼承FragmentActivity類(lèi)。托管DayListFragment對(duì)象
其布局如下:
activity_day.xml
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/fragmentContainer"
android:layout_width="match_parent"
android:layout_height="match_parent" >
</FrameLayout>
在類(lèi)中引用此布局文件,并將DayListFragment對(duì)象放置在id為fragmentContainer的FrameLayout容器視圖中。
DayActivity.java
package com.example.showdays;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
public class DayActivity extends FragmentActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_day);
FragmentManager fm = getSupportFragmentManager();
// 繼承支持庫(kù)類(lèi)FragmentActivity獲取FragmentManager對(duì)象的方法
// 若繼承Activity使用getFragmentManager()
Fragment fragment = fm.findFragmentById(R.id.fragmentContainer);
if (fragment == null) { // 查看fragment事務(wù)隊(duì)列中是否存在此事物
fragment = new DayListFragment();
fm.beginTransaction().add(R.id.fragmentContainer, fragment)
.commit();
// 提交事務(wù)(資源ID作為唯一標(biāo)識(shí)符且通知視圖位置)
}
}
}
至此程序就可以正常運(yùn)行了,運(yùn)行效果如下圖:
可以看到,已經(jīng)呈現(xiàn)出列表形式,但是要顯示的內(nèi)容卻不是我想要的。
那是因?yàn)?nbsp;Android SDK提供的預(yù)定義布局資源(android.R.layout.simple_list_item_1)布局如下:
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/text1"
style="?android:attr/listItemFirstLineStyle"
android:paddingTop="2dip"
android:paddingBottom="3dip"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
</TextView>
這樣在ListView被實(shí)例化后與adapter會(huì)話時(shí),ArrayAdapter<Day>.getView()方法會(huì)調(diào)用Day對(duì)象的toString()方法,然后將返回值傳遞給TextView。
所以覆蓋Day對(duì)象toString()方法:
Day.java
package com.example.showdays;
import java.util.ArrayList;
public class Day {
private String mTitle;
public String getTitle() {
return mTitle;
}
public void setTitle(String mTitle) {
this.mTitle = mTitle;
}
@Override
public String toString() {
return mTitle;
}
}
此時(shí)再運(yùn)行程序,運(yùn)行效果如下圖:
4、自定義列表項(xiàng)
上面使用的是Android SDK提供的預(yù)定義布局資源,直接把數(shù)據(jù)放置在TextView組件中來(lái)顯示。
下面我就自定義一個(gè)列表項(xiàng)布局,將要顯示的信息用Button組件來(lái)顯示,布局如下:
my_list_item.xml
<Button xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:enabled="false" >
</Button>
因?yàn)長(zhǎng)istView更新視圖的時(shí)候都要調(diào)用ArrayAdapter<Day>.getView()方法來(lái)獲取View。所以要想把自己定義的列表項(xiàng)加入到ListView中,可以重寫(xiě)getView()方法,覆蓋它并返回一個(gè)自己定義的View。做出改變?nèi)缦拢?/p>
DayListFragment.java
package com.example.showdays;
import java.util.ArrayList;
import android.os.Bundle;
import android.support.v4.app.ListFragment;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.Button;
public class DayListFragment extends ListFragment {
private ArrayList<Day> days;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
DayLab dayLab = new DayLab();
this.days = dayLab.getDays();
DayAdapter adapter = new DayAdapter(days);
setListAdapter(adapter);
}
private class DayAdapter extends ArrayAdapter<Day> {
public DayAdapter(ArrayList<Day> days) {
super(getActivity(), 0, days);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) { // 此列表項(xiàng)是否存在,不存在則創(chuàng)建一個(gè)
convertView = getActivity().getLayoutInflater().inflate(
R.layout.my_list_item, null);
}
Day day = getItem(position); // 獲取當(dāng)前位置的Day對(duì)象
Button button = (Button) convertView.findViewById(R.id.button);
button.setText(day.toString());
return convertView;
}
}
}
最后運(yùn)行一下,運(yùn)行效果如下圖:
更多建議: