Fragment平板技术开发(二)

源码实战----------Fragment使用
    
1.res/../BookListFragment.java
    自定义类,继承于ListFragment,无需实现OnCreateView()方法,用于 Activity右边显示列表fragment
(1)定义Callbacks接口:定义一个回调接口Callback,用于实现该Fragment与它所在的Activity交互;
(2)实现onCreate(Bundle savedInstanceState)方法:通过Adapter所提供的多个列表项,设置Fragment列表显示的列表项;
(3)实现onAttach(Activity activity)方法:将Fragment添加并显示到Acitvity中,并将传入的activity对象强制类型转化为 Callbacks接口对象,以便调用接口公共方法onItemSelected(Integer id)响应用户单击的某列表项;
(4)实现ListFragment的onListItemClick(ListView l, View v, int position, long id)方法:
    当用户点击Acitivity中的某项列表时,onListItemClick方法被激发。在这个方法中调用接口的onItemSelected来与activity共享事件。 onItemSelected()传入的参数id是列表的被选中的行ID,另一个 fragment(B)( BookDetailFragment )用这个ID来从程序的ContentProvider中取得标题的内容。
  1. package com.example.android_fragment_1;  
  2. import android.app.Activity;   
  3. import android.app.ListFragment;  
  4. import android.os.Bundle;  
  5. import android.view.View;  
  6. import android.widget.ArrayAdapter;  
  7. import android.widget.ListView;  
  8. public class BookListFragment extends ListFragment {   
  9.   //1.定义一个回调接口Callback,用于实现该Fragment与它所在的Activity交互(注意:该接口的实现需要在Activity中)   
  10.  private Callbacks mCallbacks;  //Callbacks接口对象  
  11.  public interface Callbacks  
  12.  {  
  13.   public void onItemSelected(Integer id);   //参数为Map集合的键  
  14.  }  
  15.    
  16.  //2.onCreate方法中为该ListFragment设置Adapter,让该ListFragment显示该Adapter所提供的多个列表项  
  17.  @Override  
  18.  public void onCreate(Bundle savedInstanceState) {  
  19.   // TODO Auto-generated method stub  
  20.   super.onCreate(savedInstanceState);  
  21.   setListAdapter(new ArrayAdapter<BookContent.Book>(getActivity(),//  
  22.     android.R.layout.simple_list_item_activated_1,  
  23.     android.R.id.text1,  
  24.     BookContent.ITEMS));     //  
  25.  }  
  26.   
  27.  @Override  
  28.  public void onAttach(Activity activity) {  
  29.   // TODO Auto-generated method stub  
  30.   super.onAttach(activity);  
  31.   //a.如果Activity中没有实现Callbacks接口,抛出异常  
  32.   if(!(activity instanceof Callbacks))  
  33.   {  
  34.    throw new IllegalStateException("异常:BookListFragment所在的Activity必须实现Callback接口!");  
  35.   }  
  36.   //把该Activity当成Callbacks对象(就是这一句导致出现NullPointerException错误)  
  37.         mCallbacks=(Callbacks)activity;  
  38.  }  
  39.    
  40.  //4.当该Fragment从他所属的Acitivity中被删除时,调用该方法  
  41.  @Override  
  42.  public void onDetach() {  
  43.   super.onDetach();  
  44.   mCallbacks=null;  //将mCallbacks赋值为null  
  45.  }  
  46.    
  47.  //5.当用户单击某列表项时激发该回调方法  
  48.  @Override  
  49.  public void onListItemClick(ListView l, View v, int position, long id) {  
  50.   super.onListItemClick(l, v, position, id);  
  51.   mCallbacks.onItemSelected(BookContent.ITEMS.get(position).id);//激发mCallbacks接口的onItemSelected方法  
  52.  }  
  53. public void setActivateOnItemClick(boolean activateOnItemClick) {  
  54. getListView().setChoiceMode(activateOnItemClick ? ListView.CHOICE_MODE_SINGLE:ListView.CHOICE_MODE_NONE);  
  55.  }  
  56. }  

2.res/../ BookDetailFragment.java:
      onItemSelected()传入的参数id是列表的被选中的行ID, BookDetailFragment 用这个ID来从程序的ContentProvider中取得标题的内容。  
(1)实现onCreate(Bundle savedInstanceState)方法:
    获取启动该Fragment时传入的ITEM_ID参数并根据该ID获取BookContent的ITEM_MAP中的图书信息
(2)实现onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)方法:
    a.为图书详情Fragment加载一个界面布局文件,为两个文本框;
    b.根据传入的参数ID来更新View容器,使文本框显示不同的内容;
  1. package com.example.android_fragment_1;  
  2. import android.app.Fragment;  
  3. import android.os.Bundle;  
  4. import android.view.LayoutInflater;  
  5. import android.view.View;  
  6. import android.view.ViewGroup;  
  7. import android.widget.TextView;  
  8. /*功能: 
  9.  * 使用Fragment将会显示加载一份简单的界面布局文件,并根据传入的参数来更新 
  10.  * 界面组件*/  
  11. public class BookDetailFragment extends Fragment {  
  12.  public static final String ITEM_ID="item_id";  
  13.  BookContent.Book book;  //保存该Fragment显示的book对象  
  14.    
  15.  @Override  
  16.  public void onCreate(Bundle savedInstanceState) {  
  17.   super.onCreate(savedInstanceState);  
  18.   //如果启动该Fragment时包含了ITEM_ID参数,其中 Map containsKey(String Key) 判断key有没有对应的value值; 有,则返回true 没有,则返回false  
  19.   //从Bundle对象中获取传入的参数(键值对)  
  20.   if(getArguments().containsKey(ITEM_ID))  
  21.   {  
  22.        book=BookContent.ITEM_MAP.get(getArguments().getInt(ITEM_ID));  
  23.    //获取启动该Fragment时传入的ITEM_ID参数并根据该ID获取BookContent的ITEM_MAP中的图书信息?  
  24.   }  
  25.  }  
  26.  //2.重写该方法:该方法返回的View将作为Fragment显示的组件  
  27.  @Override  
  28.  public View onCreateView(LayoutInflater inflater, ViewGroup container,  
  29.    Bundle savedInstanceState) {  
  30.   //a.加载/res/layout/目录下的fragment_book_detail.xml布局文件,返回一个view目的使该fragment的布局显示在Activity中  
  31.   View view=inflater.inflate(R.layout.fragment_book_detail, //指明当前fragment的资源文件  
  32.          container, //父容器控件  
  33.          false);     //表明是否连接该布局和其父容器控件(这里系统已经插入了布局到父容器中)  
  34.   /*将图书信息中的标题、属性显示在容器的两个文本框中*/  
  35.   if(book!=null)  
  36.   {  
  37.   //b.让book_title文本框显示book对象的title属性  
  38.    ((TextView) view.findViewById(R.id.book_title)).setText(book.title);  
  39.   //c.让book_desc文本框显示book对象的desc属性  
  40.    ((TextView) view.findViewById(R.id.book_desc)).setText(book.desc);  
  41.   }  
  42.   return view;  
  43.  }  
  44.    
  45. }  

其中界面资源布局文件为/res/layout/fragment_book_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来显示图书标题 -->
 <TextView
     style="?android:attr/textAppearanceLarge"
     android:id="@+id/book_title"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
     android:padding="16dp"/>
 <!-- 定义一个TextView来显示图书描述 -->
 <TextView
     style="?android:attr/textAppearanceLarge"
     android:id="@+id/book_desc"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
     android:padding="16dp"/>
</LinearLayout>
3.res/../SelectBookActivity.java
应用程序主Acitivity
(1)加载activity要显示的布局文件(two panes)
(2)实现Callbacks接口的onItemSelected(Integer id)方法:
       Activity从FragmentA获取传入的ID,用来启动FragmentB
  1. package com.example.android_fragment_1;  
  2. import android.app.Activity;   
  3. import android.os.Bundle;  
  4. public class SelectBookActivity extends Activity implements BookListFragment.Callbacks   
  5. {  
  6.  @Override  
  7.  protected void onCreate(Bundle savedInstanceState) {  
  8.   // TODO Auto-generated method stub  
  9.   super.onCreate(savedInstanceState);  
  10.  //1.加载Activity自己的布局资源/res/layout/main.xml并显示(two panes)  
  11.   setContentView(R.layout.activity_book_twopane);  
  12.  }  
  13.    
  14.  //2.实现Callbacks接口必须实现的方法,用于实现该Fragment与它所在的Activity交互(即选择点击哪个列表项,向Fragment传入参数id)//更新Activity右边内容  
  15.    
  16.  @Override  
  17.  public void onItemSelected(Integer id) {  
  18.   //a.创建Bundle,准备向Fragment传入参数  
  19.   Bundle arguments=new Bundle();  
  20.   arguments.putInt(BookDetailFragment.ITEM_ID, id); //装入值id到"item_id"键  
  21.   //b.创建BookDetailFragment对象,并项Fragment传入参数  
  22.   BookDetailFragment fragment=new BookDetailFragment();  
  23.   fragment.setArguments(arguments);  
  24.   //c.使用fragment替换book_detail_container容器当前显示的Fragment  
  25.   getFragmentManager().beginTransaction()  
  26.     .replace(R.id.book_detail_container, fragment)  
  27.     .commit();  
  28.    
  29.   /*注释:这一句等价于.... 
  30.    * FragmentManager Manager=getFragmentManager(); 
  31.    * FragmentTransaction Transaction=Manager.beginTransaction(); 
  32.    * Transaction.replace(R.id.book_detail_container, Manager); 
  33.    * Transaction.commit(); 
  34.    * */  
  35.  }  
  36. }  

其中界面资源布局文件为/res/layout/activity_book_twopane.xml
<?xml version="1.0" encoding="utf-8"?>
<!-- 定义一个水平排列的LinearLayout,并指定使用中等分隔条 -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal"
    android:layout_marginLeft="16dp"
    android:layout_marginRight="16dp"
    android:divider="?android:attr/dividerHorizontal"
    android:showDividers="middle">
    <!-- 使用资源文件方式:添加一个fragment到Activity中 -->
    <fragment
        android:name="com.example.android_fragment_1.BookListFragment"
        android:id="@+id/book_list"
        android:layout_height="match_parent"
        android:layout_width="0dp"
        android:layout_weight="1"/>
    <!-- 添加一个FrameLayout容器,用于显示图书详细信息 -->
    <FrameLayout
        android:id="@+id/book_detail_container"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="3"/>
</LinearLayout>
<!--说明:这个布局文件就定义了Activity的显示界面:
 左边将会显示一个ListFragment,右边只是一个FrameLayout容器
 其中FrameLayout容器将会动态更新其中显示的Fragment -->

4.res/../BookContent.java
    用于模拟系统的数据模型
 (1)List集合为左边fragment提供图书(标题)列表项数据
    public static List<Book> ITEMS=new ArrayList<Book>();
对于List集合来说,book为(1,"疯狂Android讲义","个人评价:这本书很好,就是有点厚!"2...3...)
 (2)Map集合为右边fragment提供图书详情(标题、属性)数据
    public static Map<Integer,Book> ITEM_MAP =new HashMap<Integer,Book>();
对应Map集合来说,键book.id<--->值(1.......2.......3......)
  1. package com.example.android_fragment_1;  
  2. import java.util.ArrayList;  
  3. import java.util.HashMap;  
  4. import java.util.List;  
  5. import java.util.Map;  
  6. public class BookContent {  
  7.  //1.定义一个内部类,作为系统的业务对象  
  8.  public static class Book  
  9.  {  
  10.   public Integer id;     //Map键  
  11.   public String title;  
  12.   public String desc;  
  13.   public Book(Integer id,String title,String desc)//构造函数,初始化图书详情的"map键,标题,内容"  
  14.   {  
  15.    this.id=id;  
  16.    this.title=title;  
  17.    this.desc=desc;  
  18.   }  
  19.   public String toString()  
  20.   {  
  21.    return title;  
  22.   }  
  23.  }  
  24.  //2.使用List集合记录系统所包含的Book对象ITEMS,利用它调用其add(对象)方法项List集合中添加列表项  
  25.  public static List<Book> ITEMS=new ArrayList<Book>();  
  26.  //3.使用Map集合记录系统所包含的Book对象ITEM_MAP,利用它调用put(Key,Value)方法向Map集合中添加列表项  
  27.  public static Map<Integer,Book> ITEM_MAP =new HashMap<Integer,Book>();  
  28.  static{  
  29.    //使用静态初始化代码,将Book对象添加到List集合、Map集合中  
  30.    addItem(new Book(1,"疯狂Android讲义","个人评价:这本书很好,就是有点厚!"));  
  31.    addItem(new Book(2,"数学之美","个人评价:来自自然语音的使者"));  
  32.    addItem(new Book(3,"大话数据结构","个人评价:不知道怎样,听说很不错"));  
  33.  }  
  34.  private static void addItem(Book book) {  
  35.   // TODO Auto-generated method stub  
  36.   ITEMS.add(book);   //添加List集合中列表项  
  37.   ITEM_MAP.put(book.id,book);//添加Map集合中列表项  
  38.  }  
  39. }  

/*注释:
 * static{},称为static代码块,也叫静态代码块。是在类中独立于类成员的static语句块,可以有多个且位置可以随便放。
 * 它不属于任何的方法体内,JVM加载类时会执行这些静态的代码块,如果有多个则按先后顺序执行且每个代码块智会被执行依次。
 * 比如,我们可以利用静态代码块可以对一些statci变量进行赋值*/
Fragment平板技术开发(二)_第1张图片

你可能感兴趣的:(android,应用)