zoukankan      html  css  js  c++  java
  • 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的使用

  • 相关阅读:
    系统分析师考试
    系统分析师
    软件设计师考试
    海恩法则”的启示:制度不落到实处事故必发
    eclipse下生成Java类图和时序图,生成UML图
    bzoj4010【HNOI2015】菜肴制作
    atitit.提升开发效率---MDA 软件开发方式的革命(5)----列表查询建模
    【数据结构和算法16】堆排序
    这一路走来,冷暖自知 (附算法demos)
    c++实现二叉搜索树
  • 原文地址:https://www.cnblogs.com/qianguyihao/p/4000483.html
Copyright © 2011-2022 走看看