Android系列之Fragment(四)----ListFragment的使用


【聲明】 

歡迎轉載,但請保留文章原始出處→_→ 

生命壹號:http://www.cnblogs.com/smyhvae/ 

文章來源:http://www.cnblogs.com/smyhvae/p/4000483.html

 

【正文】

一、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示例:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:orientation="vertical"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
     android:paddingLeft="8dp"
     android:paddingRight="8dp">

    <ListView android:id="@id/android:list"
           android:layout_width="match_parent"
           android:layout_height="match_parent"
           android:background="#00FF00"
           android:layout_weight="1"
           android:drawSelectorOnTop="false"/>

    <TextView android:id="@id/android:empty"
           android:layout_width="match_parent"
           android:layout_height="match_parent"
           android:background="#FF0000"
           android:text="No data"/>
</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的代碼如下:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity" >

    <LinearLayout
        android:id="@+id/left"        
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="1"
        android:background="#cccccc"
        android:orientation="horizontal" >

        <Button
            android:id="@+id/button1"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:textSize="14sp"
            android:text="show ListFragment" />
    </LinearLayout>

    <LinearLayout
        android:id="@+id/center"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="2"
        android:background="#AFEEEE"
        android:orientation="vertical" >
    </LinearLayout>

    <LinearLayout
        android:id="@+id/center"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="2"
        android:background="#00FFFF"
        android:orientation="vertical" >
    </LinearLayout>

</LinearLayout>

實際上分配了三個線性布局,左側顯示按鈕,中間顯示標題,右側顯示詳情。這個布局文件對應的可視化界面如下:

(2)定義中間的ListFragment,即新建文件ArticleListFragment.java:

ArticleListFragment.java的代碼如下:

 1 package com.example.m01_listfragment01;
 2 
 3 import java.util.ArrayList;
 4 import java.util.List;
 5 
 6 import android.app.ListFragment;
 7 import android.os.Bundle;
 8 import android.view.LayoutInflater;
 9 import android.view.View;
10 import android.view.ViewGroup;
11 import android.widget.ArrayAdapter;
12 
13 public class ArticleListFragment extends ListFragment {
14 
15     private ArrayAdapter<String> adapter;
16 
17     @Override
18     public void onCreate(Bundle savedInstanceState) {
19         // TODO Auto-generated method stub
20         super.onCreate(savedInstanceState);
21         
22         //定義一個數組
23         List<String> data = new ArrayList<String>(); 24         for (int i = 0; i < 30; i++) { 25             data.add("smyh" + i); 26  } 27         //將數組加到ArrayAdapter當中
28         adapter = new ArrayAdapter<String>(getActivity(), 29  android.R.layout.simple_list_item_1, data); 30         //綁定適配器時,必須通過ListFragment.setListAdapter()接口,而不是ListView.setAdapter()或其它方法
31  setListAdapter(adapter); 32     }
33 
34     @Override
35     public View onCreateView(LayoutInflater inflater, ViewGroup container,
36             Bundle savedInstanceState) {
37         // TODO Auto-generated method stub
38         return super.onCreateView(inflater, container, savedInstanceState);
39     }
40 
41     @Override
42     public void onPause() {
43         // TODO Auto-generated method stub
44         super.onPause();
45     }
46 }

核心代碼是22至32行:我們讓這個Fragment繼承ListFragment,然后在onCreate()方法中定義一個ArrayAdapter,將數據放進去,最后綁定適配器就行了。需要注意的是,由於我們繼承的是ListFragment,這個Fragment默認自帶了一個布局,所以我們不需要重新新建布局文件了

(3)將中間的ListFragment加載到Activity當中去。當我們點擊按鈕時,就開始加載這個Fragment:

MainActivity.java的代碼如下:

 1 package com.example.m01_listfragment01;
 2 
 3 import android.app.Activity;
 4 import android.app.FragmentManager;
 5 import android.app.FragmentTransaction;
 6 import android.os.Bundle;
 7 import android.view.Menu;
 8 import android.view.View;
 9 import android.view.View.OnClickListener;
10 import android.widget.Button;
11 
12 public class MainActivity extends Activity {
13 
14     private FragmentManager manager;
15     private FragmentTransaction transaction;
16     @Override
17     protected void onCreate(Bundle savedInstanceState) {
18         super.onCreate(savedInstanceState);
19         setContentView(R.layout.activity_main);
20         Button button = (Button) findViewById(R.id.button1);
21         button.setOnClickListener(new OnClickListener() {
22             
23             //點擊按鈕,加載ListFragment
24  @Override 25             public void onClick(View v) { 26                 // TODO Auto-generated method stub
27                 manager = getFragmentManager(); 28                 transaction = manager.beginTransaction(); 29                 ArticleListFragment articleListFragment = new ArticleListFragment(); 30                 transaction.add(R.id.center, articleListFragment, "article"); 31  transaction.commit(); 32  } 33         });
34 
35     }
36 
37     @Override
38     public boolean onCreateOptionsMenu(Menu menu) {
39         // Inflate the menu; this adds items to the action bar if it is present.
40         getMenuInflater().inflate(R.menu.main, menu);
41         return true;
42     }
43 }

這個代碼比較簡單,就不多解釋了。

現在運行程序,初始界面如下:

點擊左側的按鈕后,顯示如下:

注:如果想實現:點擊中間的某個item,彈出吐司顯示那個item中的內容,可以在上方的ArticleListFragment.java中的監聽事件里添加如下代碼:

(代碼放置的位置是:讓它和Fragment的生命周期方法並列就行了)

1     @Override
2     public void onListItemClick(ListView l, View v, int position, long id) {
3         // TODO Auto-generated method stub
4         super.onListItemClick(l, v, position, id);
5         String item = adapter.getItem(position);
6         Toast.makeText(getActivity(), item, 1).show();
7     } 

由此我們可以看到,監聽事件的函數為onListItemClick(),可以直接寫,不需要set。

這里面關鍵代碼在第05行,通過getItem()接收那個item,然后用字符串來接收。

我們先去掉這部分的監聽事件代碼,繼續往下看。

(4)點擊中間ListFragment的item,加載右邊的DetailFragment:

我們在中間ListFragment中添加一個按鈕的監聽事件,監聽事件的函數為onListItemClick(),ArticleListFragment.java在上面代碼的基礎之上,添加的代碼如下:

(代碼放置的位置是:讓它和Fragment的生命周期方法並列就行了)

 1     //點擊按鈕,加載最右側的Fragment
 2     @Override
 3     public void onListItemClick(ListView l, View v, int position, long id) {
 4         // TODO Auto-generated method stub
 5         super.onListItemClick(l, v, position, id);
 6         
 7         //點擊按鈕后,加載右邊的Fragment
 8         FragmentManager manager = getFragmentManager();
 9         FragmentTransaction transaction = manager.beginTransaction();
10         DetailFragment detailFragment = new DetailFragment();
11         //記住:這個地方必須用replace,而不是用add
12         transaction.replace(R.id.right, detailFragment, "detailFragment"); 13         
14         //將中間的item的內容放到Bundle對象當中,然后放到最右側Frament的參數當中
15         String item = adapter.getItem(position); 16         Bundle args = new Bundle(); 17         args.putString("item",item); 18  detailFragment.setArguments(args); 19         //Toast.makeText(getActivity(), item, 1).show();       
20         
21         transaction.commit();
22     }

上面的代碼中,我們是在中間的Fragment中點擊按鈕,然后加載右邊的Fragment,然后要注意14至18行的核心代碼,看一下它是如何通過bundle來傳遞數據的

需要注意的是,第12行代碼必須用replace的方式加載右側的fragment,而不是add;如果用add,運行的錯誤稍后將展示出來。

(5)定義右邊的DetailFragment:

先定義布局文件,在里面加一個TextView,fragment_detail.xml的代碼如下:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="TextView" />
</LinearLayout>

然后新建文件,DetailFragment.java的代碼如下: 

 1 package com.example.m01_listfragment01;
 2 
 3 import android.app.Fragment;
 4 import android.os.Bundle;
 5 import android.view.LayoutInflater;
 6 import android.view.View;
 7 import android.view.ViewGroup;
 8 import android.widget.TextView;
 9 
10 public class DetailFragment extends Fragment {
11 
12 
13     @Override
14     public void onCreate(Bundle savedInstanceState) {
15         // TODO Auto-generated method stub
16         super.onCreate(savedInstanceState);
17     }
18 
19     @Override
20     public View onCreateView(LayoutInflater inflater, ViewGroup container,
21             Bundle savedInstanceState) {
22         // TODO Auto-generated method stub
23         View view = inflater.inflate(R.layout.fragment_detail, null);
24         TextView textView = (TextView)view.findViewById(R.id.textView1);
25         textView.setText(""+getArguments().getString("item")); 26         return view;
27     }
28 
29     @Override
30     public void onPause() {
31         // TODO Auto-generated method stub
32         super.onPause();
33     }    
34 }

核心代碼是第25行,仔細看一下我們是怎么通過鍵值對來拿到中間的Fragment傳遞過來的item的內容

現在運行程序,一次點擊左邊的按鈕和中間的item,效果如下:

如果我們在中間的Fragment中錯誤地通過add方式加載右邊的Fragment,而不是通過replace方式,最終錯誤的效果如下:

也就是說,每點擊一次中間的item,就會在右邊繼續加載一個文本,而不是替代的方式,很顯然,這種方式不是我們想要的。

 

【索引】

如果你對本文存在疑惑,請參考本人關於Fragment的系列文章:(不斷更新)

Android系列之Fragment(一)----Fragment加載到Activity當中

Android系列之Fragment(二)----Fragment的生命周期和返回棧

Android系列之Fragment(三)----Fragment和Activity之間的通信(含接口回調)

Android系列之Fragment(四)----ListFragment的使用

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM