Android中Fragment

来源:互联网 发布:sqlserver清空数据库 编辑:程序博客网 时间:2024/06/11 00:59

以前也了解过Fragment,但是由于项目中使用的少或是基本不适用,导致后面也就对它忽视了。现在项目中很多都会使用到Fragment,那就再来学习下吧。


1.Fragment:碎片

Fragment是应用中Activity的一部分UI或是行为。Fragment有自己的生命周期,layout,接受属于输入事件,并且可以在Activity运行期间添加和删除。这样就可以灵活控制UI。可以在一个Activity中放多个不同的Fragment,也可以在不同Activity中重用某一个Fragment。Fragment不能单独存在,必须嵌套在Activity中,它的生命周期也依赖于宿主Activity的生命周期。


2.生命周期

(1)Activity的生命周期


(2)Fragment的生命周期


(3)对比


(4)方法介绍

onAttach(Activity) called once the fragment is associated with its activity. 
Fragment与Activity关联的时候调用,一般在第一次发生关联的时候调用。

onCreate(Bundle) called to do initial creation of the fragment. 
初始化创建一个Fragment的时候调用,一般在第一次初始化时被调用。

onCreateView(LayoutInflater, ViewGroup, Bundle) creates and returns the view hierarchy associated with the fragment. 
创建并返回与fragment相关联的view对象。

onActivityCreated(Bundle) tells the fragment that its activity has completed its own Activity.onCreate(). 
当宿主Activity的onCreate方法调用时通知fragment。

onStart() makes the fragment visible to the user (based on its containing activity being started). 
用户可见状态。

onResume() makes the fragment interacting with the user (based on its containing activity being resumed). 
用户可交互状态。

onPause() fragment is no longer interacting with the user either because its activity is being paused or a fragment operation is modifying it in the activity. 
fragment不再与用户交互。

onStop() fragment is no longer visible to the user either because its activity is being stopped or a fragment operation is modifying it in the activity. 
fragment对用户不可见。

onDestroyView() allows the fragment to clean up resources associated with its View.
fragment的视图被移除。

onDestroy() called to do final cleanup of the fragment's state. 
fragment的状态被销毁。

onDetach() called immediately prior to the fragment no longer being associated with its activity. 
fragment与Activity不再关联。


3.建立 Fragment 的步骤

(1)创建fragment对应的布局,如frag_message.xml

<?xml version="1.0" encoding="utf-8"?><FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:id="@+id/message_fl"    android:layout_width="match_parent"    android:layout_height="match_parent" >    <TextView        android:id="@+id/message_tv"        android:layout_width="match_parent"        android:layout_height="wrap_content"         android:text="@string/message_display"/></FrameLayout>
(2)创建这个fragment,如MessageFragment

public class MessageFragment extends Fragment {@Overridepublic void onAttach(Activity activity) {// TODO Auto-generated method stubsuper.onAttach(activity);Log.d("zhangmq", "MessageFragment onAttach");}@Overridepublic void onCreate(Bundle savedInstanceState) {// TODO Auto-generated method stubsuper.onCreate(savedInstanceState);Log.d("zhangmq", "MessageFragment onCreate");}@Overridepublic View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {// TODO Auto-generated method stubLog.d("zhangmq", "MessageFragment onCreateView");return inflater.inflate(R.layout.frag_message, container, false);}@Overridepublic void onActivityCreated(Bundle savedInstanceState) {// TODO Auto-generated method stubsuper.onActivityCreated(savedInstanceState);Log.d("zhangmq", "MessageFragment onActivityCreated");}@Overridepublic void onStart() {// TODO Auto-generated method stubsuper.onStart();Log.d("zhangmq", "MessageFragment onStart");}@Overridepublic void onResume() {// TODO Auto-generated method stubsuper.onResume();Log.d("zhangmq", "MessageFragment onResume");}@Overridepublic void onPause() {// TODO Auto-generated method stubsuper.onPause();Log.d("zhangmq", "MessageFragment onPause");}@Overridepublic void onDestroyView() {// TODO Auto-generated method stubsuper.onDestroyView();Log.d("zhangmq", "MessageFragment onDestroyView");}@Overridepublic void onDestroy() {// TODO Auto-generated method stubsuper.onDestroy();Log.d("zhangmq", "MessageFragment onDestroy");}@Overridepublic void onDetach() {// TODO Auto-generated method stubsuper.onDetach();Log.d("zhangmq", "MessageFragment onDetach");}@Overridepublic void onStop() {// TODO Auto-generated method stubsuper.onStop();Log.d("zhangmq", "MessageFragment onStop");}}
(3)把Fragment添加到Activity中,有两种方式,静态添加和动态添加。

静态添加:在layout中直接添加,把fragment当做一个控件。

<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"    android:orientation="horizontal"    tools:context=".MainActivity" >    <fragment         android:name="com.zhangmq.qqfragmentdemo.MessageFragment"        android:id="@+id/message"        android:layout_weight="1"        android:layout_width="0dp"        android:layout_height="match_parent"/>         <fragment         android:name="com.zhangmq.qqfragmentdemo.ContactFragment"        android:id="@+id/contact"        android:layout_weight="2"        android:layout_width="0dp"        android:layout_height="match_parent"/>    </LinearLayout>
当系统创建这个Activity布局时,它实例化每一个在布局中指定的Fragment,并调用每一个Fragment.onCreateView方法来获取每一个Fragment布局。系统将从Fragment返回的View直接插入到<fragment>标签所在的地方。


动态添加:在Activity中添加。

在layout中定义一个fragment_container,用来放置fragment。

<RelativeLayout 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" >    <FrameLayout        android:id="@+id/fragment_container"        android:layout_width="match_parent"        android:layout_height="match_parent" />    <LinearLayout        android:id="@+id/option_ll"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:layout_alignParentBottom="true"        android:orientation="horizontal" >        <TextView            android:id="@+id/display_message_tv"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_marginLeft="50dp"            android:text="@string/message" />        <TextView            android:id="@+id/display_contact_tv"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_marginLeft="50dp"            android:text="@string/contact" />        <TextView            android:id="@+id/display_dynamic_tv"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_marginLeft="50dp"            android:text="@string/dynamic" />    </LinearLayout></RelativeLayout>
在Activity中:

public class MainActivity extends Activity {TextView display_message_tv = null;TextView display_contact_tv = null;TextView display_dynamic_tv = null;MessageFragment mf = null;ContactFragment cf = null;DynamicFragment df = null;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);findViews();mf = new MessageFragment();cf = new ContactFragment();df = new DynamicFragment();FragmentManager fm = getFragmentManager();FragmentTransaction ft = fm.beginTransaction();ft.add(R.id.fragment_container, mf);ft.addToBackStack(null);ft.commit();}private void findViews() {display_message_tv = (TextView) findViewById(R.id.display_message_tv);display_message_tv.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View arg0) {// TODO Auto-generated method stubstartPreferenceFragment(mf,true);}});display_contact_tv = (TextView) findViewById(R.id.display_contact_tv);display_contact_tv.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View arg0) {// TODO Auto-generated method stubstartPreferenceFragment(cf,true);}});display_dynamic_tv = (TextView) findViewById(R.id.display_dynamic_tv);display_dynamic_tv.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View arg0) {// TODO Auto-generated method stubstartPreferenceFragment(df,true);}});}public void startPreferenceFragment(Fragment fragment, boolean push) {        FragmentTransaction transaction = getFragmentManager().beginTransaction();        transaction.replace(R.id.fragment_container, fragment);        if (push) {            transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);            transaction.addToBackStack("fragment");        } else {            transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);        }        transaction.commitAllowingStateLoss();    }@Overridepublic boolean onCreateOptionsMenu(Menu menu) {// Inflate the menu; this adds items to the action bar if it is present.getMenuInflater().inflate(R.menu.main, menu);return true;}}
关键:

FragmentManager fm = getFragmentManager();FragmentTransaction ft = fm.beginTransaction();ft.add(R.id.fragment_container, mf);ft.addToBackStack(null);ft.commit();

最简单的Fragment就添加到Activity中咯。


4.android.app.Fragment & android.support.v4.app.Fragment
区别:

(1)支持的最低版本不同

android.app.Fragment支持的最低版本是 android:minSdkVersion="11"

android.support.v4.app.Fragment支持的最低版本是 android:minSdkVersion="4"
(2)导入包
android.app.Fragment不需要导入jar包
android.support.v4.app.Fragment需要导入jar包:android.support.v4.app.Fragment
(3)获得FragmentManager的方式不同
在android.app.Fragment中
FragmentManager fm = getFragmentManager();
在android.support.v4.app.Fragment中
FragmentManager mFragmentManager = getSupportFragmentManager()
(4)宿主Activity不同
android.app.Fragment可以在一般的Activity中使用
android.support.v4.app.Fragment必须在FragmentActivity中使用,即Activity必须继承FragmentActivity


5.注意

(1)必须最后调用commit()

添加多个fragment到同一个容器,则添加的顺序决定了他们在view hierarchy中显示的顺序。

(2)按back键不是马上回到Home界面,而是会先会退到没有add fragment之前的状态
addToBackStack方法将fragment添加到一个Fragment事务的back stack。并允许用户通过BACK键返回到前一个Fragment状态。

如上述例子,运行:



然后:点击 联系人 ,再点击 消息 ,

然后按返回键,会返回到联系人主页,再按返回键,会返回到消息主页,再按返回键,会返回到Activity没有add任何fragment的界面,再按返回键,才会退出应用。log为:

01-01 15:28:35.539: V/BoostFramework(8172): BoostFramework() : mPerf = com.qualcomm.qti.Performance@aca99bb01-01 15:28:35.540: V/BoostFramework(8172): BoostFramework() : mPerf = com.qualcomm.qti.Performance@4bc9ed801-01 15:28:35.650: D/zhangmq(8172): MessageFragment onAttach01-01 15:28:35.651: D/zhangmq(8172): MessageFragment onCreate01-01 15:28:35.651: D/zhangmq(8172): MessageFragment onCreateView01-01 15:28:35.657: D/zhangmq(8172): MessageFragment onActivityCreated01-01 15:28:35.657: D/zhangmq(8172): MessageFragment onStart01-01 15:28:35.658: D/zhangmq(8172): MessageFragment onResume01-01 15:28:38.418: D/zhangmq(8172): MessageFragment onPause01-01 15:28:38.422: D/zhangmq(8172): MessageFragment onStop01-01 15:28:38.423: D/zhangmq(8172): MessageFragment onDestroyView01-01 15:28:38.446: D/zhangmq(8172): ContactFragment onAttach01-01 15:28:38.446: D/zhangmq(8172): ContactFragment onCreate01-01 15:28:38.446: D/zhangmq(8172): ContactFragment onCreateView01-01 15:28:38.466: D/zhangmq(8172): ContactFragment onActivityCreated01-01 15:28:38.466: D/zhangmq(8172): ContactFragment onStart01-01 15:28:38.466: D/zhangmq(8172): ContactFragment onResume01-01 15:28:40.513: D/zhangmq(8172): ContactFragment onPause01-01 15:28:40.514: D/zhangmq(8172): ContactFragment onStop01-01 15:28:40.514: D/zhangmq(8172): ContactFragment onDestroyView01-01 15:28:40.517: D/zhangmq(8172): MessageFragment onCreateView01-01 15:28:40.524: D/zhangmq(8172): MessageFragment onActivityCreated01-01 15:28:40.524: D/zhangmq(8172): MessageFragment onStart01-01 15:28:40.524: D/zhangmq(8172): MessageFragment onResume01-01 15:28:44.591: D/zhangmq(8172): MessageFragment onPause01-01 15:28:44.591: D/zhangmq(8172): MessageFragment onStop01-01 15:28:44.591: D/zhangmq(8172): MessageFragment onDestroyView01-01 15:28:44.597: D/zhangmq(8172): ContactFragment onCreateView01-01 15:28:44.608: D/zhangmq(8172): ContactFragment onActivityCreated01-01 15:28:44.608: D/zhangmq(8172): ContactFragment onStart01-01 15:28:44.608: D/zhangmq(8172): ContactFragment onResume01-01 15:28:46.375: D/zhangmq(8172): ContactFragment onPause01-01 15:28:46.375: D/zhangmq(8172): ContactFragment onStop01-01 15:28:46.375: D/zhangmq(8172): ContactFragment onDestroyView01-01 15:28:46.382: D/zhangmq(8172): MessageFragment onCreateView01-01 15:28:46.389: D/zhangmq(8172): MessageFragment onActivityCreated01-01 15:28:46.389: D/zhangmq(8172): MessageFragment onStart01-01 15:28:46.389: D/zhangmq(8172): MessageFragment onResume01-01 15:28:46.693: D/zhangmq(8172): ContactFragment onDestroy01-01 15:28:46.693: D/zhangmq(8172): ContactFragment onDetach01-01 15:28:47.534: D/zhangmq(8172): MessageFragment onPause01-01 15:28:47.535: D/zhangmq(8172): MessageFragment onStop01-01 15:28:47.535: D/zhangmq(8172): MessageFragment onDestroyView01-01 15:28:47.537: D/zhangmq(8172): MessageFragment onDestroy01-01 15:28:47.537: D/zhangmq(8172): MessageFragment onDetach


6.Fragment与Activity通信

(1)一个给定的Fragment实例是与它的宿主Activity一一对应的。

(2)Fragment通过getActivity方法来获得Activity实例,然后很容易通过Activity实例在Activity布局中查找一个控件View。如:
ListView list = (ListView)getActivity().findViewById(R.id.list);
(3)Activity通过FragmentManager获得一个Fragment的引用来调用Fragment中的方法,通过findFragmentById或是findFragmentByTag方法来获得Fragment实例。如:
mf = (MessageFragment) getFragmentManager().findFragmentById(R.id.message);
(4)两个Fragment之间通信
两个Fragment之间,通过宿主Activity来进行通信。
主要方法:在FragmentA中定义监听器接口,然后Activity实现这个监听器接口,然后在实现监听器函数中可以操作FragmentB。
public class ArticalFragment extends Fragment {@Overridepublic void onCreate(Bundle savedInstanceState) {// TODO Auto-generated method stubsuper.onCreate(savedInstanceState);}@Overridepublic View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {// TODO Auto-generated method stubreturn inflater.inflate(R.layout.artical_fragment, container,false);}@Overridepublic void onPause() {// TODO Auto-generated method stubsuper.onPause();}public ArticalFragment() {// TODO Auto-generated constructor stub}}
public class HeadlinesFragment extends ListFragment {private ArrayList<String> listHeadlines = new ArrayList<String>();private OnArticalSelectedListener mListener = null;@Overridepublic void onCreate(Bundle savedInstanceState) {// TODO Auto-generated method stubsuper.onCreate(savedInstanceState);listHeadlines.add("111111");listHeadlines.add("222222");listHeadlines.add("333333");listHeadlines.add("444444");listHeadlines.add("555555");listHeadlines.add("666666");listHeadlines.add("777777");listHeadlines.add("888888");setListAdapter(new ArrayAdapter<String>(getActivity(),android.R.layout.simple_list_item_1 ,listHeadlines));}@Overridepublic View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {// TODO Auto-generated method stubreturn inflater.inflate(R.layout.headlines_fragment, container,false);}@Overridepublic void onPause() {// TODO Auto-generated method stubsuper.onPause();}public interface OnArticalSelectedListener {public void onArticalSelected(int position);}//当添加Fragment到Activity时有系统调用@Overridepublic void onAttach(Activity activity) {// TODO Auto-generated method stubsuper.onAttach(activity);try{mListener = (OnArticalSelectedListener)activity;}catch(ClassCastException e){throw new ClassCastException(activity.toString()+"must implements OnArticalSelectedListener");}}@Overridepublic void onListItemClick(ListView l, View v, int position, long id) {// TODO Auto-generated method stubmListener.onArticalSelected(position);}}
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:id="@+id/fragment_container"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="horizontal"    tools:context=".MainActivity" >    <fragment         android:name="com.example.fragmenttest.HeadlinesFragment"        android:id="@+id/headline"        android:layout_weight="1"        android:layout_width="0dp"        android:layout_height="match_parent"/>        <fragment         android:name="com.example.fragmenttest.ArticalFragment"        android:id="@+id/artical"        android:layout_weight="2"        android:layout_width="0dp"        android:layout_height="match_parent"/>    </LinearLayout>
public class MainActivity extends FragmentActivity implementsOnArticalSelectedListener {private String[] listArtical = { "这个是111111", "这个是222222", "这个是333333","这个是444444", "这个是555555", "这个是666666", "这个是777777", "这个是888888" };HeadlinesFragment mHeadlinesFragment = null;ArticalFragment mArticalFragment = null;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);mHeadlinesFragment = (HeadlinesFragment) getSupportFragmentManager().findFragmentById(R.id.headline);mArticalFragment = (ArticalFragment) getSupportFragmentManager().findFragmentById(R.id.artical);ActionBar actionBar = getActionBar();actionBar.hide();}@Overridepublic void onArticalSelected(int position) {// TODO Auto-generated method stubTextView showArtical = (TextView) findViewById(R.id.showArtical);showArtical.setText(listArtical[position]);}}
<?xml version="1.0" encoding="utf-8"?><FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:id="@+id/articals"    android:layout_width="match_parent"    android:layout_height="match_parent" >    <TextView        android:id="@+id/showArtical"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="zhouhy"        android:textSize="30dp" >    </TextView></FrameLayout>
<?xml version="1.0" encoding="utf-8"?><FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:id="@+id/headlines"    android:layout_width="match_parent"    android:layout_height="match_parent" >   <ListView          android:id="@+id/android:list"          android:layout_width="fill_parent"          android:layout_height="wrap_content"           />  </FrameLayout>





0 0
原创粉丝点击