Android Fragments 使用详解附代码实例

Fragments 诞生初衷

     自从Android 3.0中引入fragments 的概念,根据词海的翻译可以译为:碎片、片段。其上的是为了解决不同屏幕分辩率的动态和灵活UI设计。大屏幕如平板小屏幕如手机,平板电脑的设计使得其有 更多的空间来放更多的UI组件,而多出来的空间存放UI使其会产生更多的交互,从而诞生了fragments 。fragments 的设计不需要你来亲自管理view hierarchy 的复杂变化,通过将Activity 的布局分散到frament 中,可以在运行时修改activity 的外观,并且由activity 管理的back stack 中保存些变化。

 

      Fragments 设计理念

      在设计应用时特别是Android 应用 ,有众多的分辨率要去适应,而fragments 可以让你在屏幕不同的屏幕上动态管理UI。例如:通讯应用程序(QQ),用户列表可以在左边,消息窗口在右边的设计。而在手机屏幕用户列表填充屏幕当点击 某一用户时,则弹出对话窗口的设计,如下图:

 

Fragments的生命周期 

    每一个fragments 都有自己的一套生命周期回调方法和处理自己的用户输入事件。 对应生命周期可参考下图:

 

 其中大多数程序必须使用Fragments 必须实现的三个回调方法分别为:

onCreate

   系统创建Fragments 时调用,可做执行初始化工作或者当程序被暂停或停止时用来恢复状态,跟Activity 中的onCreate相当。 

onCreateView

   用于首次绘制用户界面的回调方法,必须返回要创建的Fragments 视图UI。假如你不希望提供Fragments 用户界面则可以返回NULL。 

onPause 

    当用户离开这个Fragments 的时候调用,这时你要提交任何应该持久的变化,因为用户可能不会回来。更多的事件可以参考上图的生命周期关系图。

Fragments 的类别

    系统内置了三种Fragments ,这三种Fragments 分别有不同的应用场景分别为:

DialogFragment

 对话框式的Fragments,可以将一个fragments 对话框并到activity 管理的fragments back stack 中,允许用户回到一个前曾摒弃fragments.

ListFragments

   类似于ListActivity 的效果,并且还提供了ListActivity 类似的onListItemCLick和setListAdapter等功能。

PreferenceFragments

   类似于PreferenceActivity .可以创建类似IPAD的设置界面。 

 

Fragments 的详细使用 

    首先先来看一张DEMO 效果图:

 

    左边点击时,右边的字符会与左边选中的项的字符相同。与IPAD上的设置界面很相似,这一点是否借鉴了ipad 上的UI呢?

相就的XML文件:

[html]  view plain copy
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:layout_width="match_parent"  
  4.     android:layout_height="match_parent"  
  5.     android:orientation="horizontal" >  
  6.   
  7.    <fragment class="com.xuzhi.fragment.FragmentDemoActivity$TitlesFragment" android:id="@+id/titles" android:layout_weight="1"  
  8.        android:layout_width="0px" android:layout_height="match_parent"  
  9.        />  
  10.      
  11.    <FrameLayout android:id="@+id/details" android:layout_weight="1" android:layout_width="0px" android:layout_height="match_parent"  
  12.        android:background="?android:attr/detailsElementBackground"  
  13.        ></FrameLayout>  
  14. </LinearLayout>  

主界面代码(己做注释):

[java]  view plain copy
  1. package com.xuzhi.fragment;  
  2. import android.app.Activity;  
  3. import android.app.AlertDialog;  
  4. import android.app.Fragment;  
  5. import android.app.FragmentTransaction;  
  6. import android.app.ListFragment;  
  7. import android.os.Bundle;  
  8. import android.util.TypedValue;  
  9. import android.view.LayoutInflater;  
  10. import android.view.View;  
  11. import android.view.ViewGroup;  
  12. import android.widget.ArrayAdapter;  
  13. import android.widget.ListView;  
  14. import android.widget.ScrollView;  
  15. import android.widget.TextView;  
  16.   
  17. public class FragmentDemoActivity extends Activity {  
  18.   
  19.     public static String[] array = { "text1,""text2""text3""text4",  
  20.             "text5,""text6""text7""text8" };  
  21.   
  22.     /** Called when the activity is first created. */  
  23.     @Override  
  24.     public void onCreate(Bundle savedInstanceState) {  
  25.         super.onCreate(savedInstanceState);   
  26.         setContentView(R.layout.main);  
  27.     }  
  28.   
  29.           
  30.     public static class TitlesFragment extends ListFragment {  
  31.   
  32.         boolean mDualPane;  
  33.         int mCurCheckPosition = 0;  
  34.           
  35.         @Override  
  36.         public void onCreate(Bundle savedInstanceState) {  
  37.             // TODO Auto-generated method stub  
  38.             super.onCreate(savedInstanceState);  
  39.             System.out.println("Fragment-->onCreate");  
  40.         }  
  41.           
  42.         @Override  
  43.         public View onCreateView(LayoutInflater inflater, ViewGroup container,  
  44.                 Bundle savedInstanceState) {  
  45.             // TODO Auto-generated method stub  
  46.             System.out.println("Fragment-->onCreateView");  
  47.             return super.onCreateView(inflater, container, savedInstanceState);  
  48.         }  
  49.           
  50.         @Override  
  51.         public void onPause() {  
  52.             // TODO Auto-generated method stub  
  53.             super.onPause();  
  54.             System.out.println("Fragment-->onPause");  
  55.         }  
  56.           
  57.           
  58.         @Override  
  59.         public void onStop() {  
  60.             // TODO Auto-generated method stub  
  61.             super.onStop();  
  62.               
  63.             System.out.println("Fragment-->onStop");  
  64.         }  
  65.           
  66.         @Override  
  67.         public void onAttach(Activity activity) {  
  68.             // TODO Auto-generated method stub  
  69.             super.onAttach(activity);  
  70.             System.out.println("Fragment-->onAttach");  
  71.         }  
  72.           
  73.         @Override  
  74.         public void onStart() {  
  75.             // TODO Auto-generated method stub  
  76.             super.onStart();  
  77.             System.out.println("Fragment-->onStart");  
  78.         }  
  79.           
  80.         @Override  
  81.         public void onResume() {  
  82.             // TODO Auto-generated method stub  
  83.             super.onResume();  
  84.             System.out.println("Fragment-->onResume");  
  85.         }  
  86.           
  87.         @Override  
  88.         public void onDestroy() {  
  89.             // TODO Auto-generated method stub  
  90.             super.onDestroy();  
  91.             System.out.println("Fragment-->onDestroy");  
  92.         }  
  93.           
  94.           
  95.   
  96.         @Override  
  97.         public void onActivityCreated(Bundle savedInstanceState) {  
  98.             // TODO Auto-generated method stub  
  99.             super.onActivityCreated(savedInstanceState);  
  100.             System.out.println("Fragment-->onActivityCreted");  
  101.             setListAdapter(new ArrayAdapter<String>(getActivity(),  
  102.                     android.R.layout.simple_list_item_1, array));  
  103.   
  104.             View detailsFrame = getActivity().findViewById(R.id.details);  
  105.   
  106.             mDualPane = detailsFrame != null  
  107.                     && detailsFrame.getVisibility() == View.VISIBLE;  
  108.   
  109.             if (savedInstanceState != null) {  
  110.                 mCurCheckPosition = savedInstanceState.getInt("curChoice"0); //从保存的状态中取出数据  
  111.             }  
  112.   
  113.             if (mDualPane) {  
  114.                 getListView().setChoiceMode(ListView.CHOICE_MODE_SINGLE);  
  115.   
  116.                 showDetails(mCurCheckPosition);  
  117.             }  
  118.         }  
  119.   
  120.         @Override  
  121.         public void onSaveInstanceState(Bundle outState) {  
  122.             // TODO Auto-generated method stub  
  123.             super.onSaveInstanceState(outState);  
  124.   
  125.             outState.putInt("curChoice", mCurCheckPosition);//保存当前的下标  
  126.         }  
  127.   
  128.         @Override  
  129.         public void onListItemClick(ListView l, View v, int position, long id) {  
  130.             // TODO Auto-generated method stub  
  131.             super.onListItemClick(l, v, position, id);  
  132.             showDetails(position);  
  133.         }  
  134.   
  135.         void showDetails(int index) {  
  136.             mCurCheckPosition = index;   
  137.             if (mDualPane) {  
  138.                 getListView().setItemChecked(index, true);  
  139.                 DetailsFragment details = (DetailsFragment) getFragmentManager()  
  140.                         .findFragmentById(R.id.details);   
  141.                 if (details == null || details.getShownIndex() != index) {  
  142.                     details = DetailsFragment.newInstance(mCurCheckPosition);   
  143.   
  144.                     //得到一个fragment 事务(类似sqlite的操作)  
  145.                     FragmentTransaction ft = getFragmentManager()  
  146.                             .beginTransaction();  
  147.                     ft.replace(R.id.details, details);//将得到的fragment 替换当前的viewGroup内容,add则不替换会依次累加  
  148.                     ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);//设置动画效果  
  149.                     ft.commit();//提交  
  150.                 }  
  151.             } else {  
  152.                 new AlertDialog.Builder(getActivity()).setTitle(  
  153.                         android.R.string.dialog_alert_title).setMessage(  
  154.                         array[index]).setPositiveButton(android.R.string.ok,  
  155.                         null).show();  
  156.             }  
  157.         }  
  158.     }  
  159.   
  160.     /** 
  161.      * 作为界面的一部分,为fragment 提供一个layout 
  162.      * @author terry 
  163.      * 
  164.      */  
  165.     public static class DetailsFragment extends Fragment {  
  166.   
  167.         public static DetailsFragment newInstance(int index) {   
  168.             DetailsFragment details = new DetailsFragment();  
  169.             Bundle args = new Bundle();  
  170.             args.putInt("index", index);  
  171.             details.setArguments(args);  
  172.             return details;  
  173.         }  
  174.   
  175.         public int getShownIndex() {  
  176.             return getArguments().getInt("index"0);  
  177.         }  
  178.   
  179.         @Override  
  180.         public View onCreateView(LayoutInflater inflater, ViewGroup container,  
  181.                 Bundle savedInstanceState) {  
  182.             // TODO Auto-generated method stub  
  183.             if (container == null)  
  184.                 return null;  
  185.   
  186.             ScrollView scroller = new ScrollView(getActivity());  
  187.             TextView text = new TextView(getActivity());  
  188.   
  189.             int padding = (int) TypedValue.applyDimension(  
  190.                     TypedValue.COMPLEX_UNIT_DIP, 4, getActivity()  
  191.                             .getResources().getDisplayMetrics());  
  192.             text.setPadding(padding, padding, padding, padding);  
  193.             scroller.addView(text);  
  194.   
  195.             text.setText(array[getShownIndex()]);  
  196.             return scroller;  
  197.         }  
  198.     }  
  199. }  

之后的操作即可以像平常Android的menu用法一样,代码为:

[java]  view plain copy
  1. @Override  
  2.         public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {  
  3.             // TODO Auto-generated method stub  
  4.             super.onCreateOptionsMenu(menu, inflater);  
  5.              menu.add("Menu 1a").setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);  
  6.                 menu.add("Menu 1b").setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);  
  7.         }  
  8.           
  9.         @Override  
  10.         public boolean onOptionsItemSelected(MenuItem item) {  
  11.             // TODO Auto-generated method stub  
  12.             Toast.makeText(getActivity(), "index is"+getShownIndex()+" && menu text is "+item.getTitle(), 1000).show();  
  13.             return super.onOptionsItemSelected(item);  
  14.         }  

DEMO下载:

Android FramentDEMO

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值