標籤:
Fragment是3.0引入的新組件,在3.0之前需要引入v4包的Fragment進行向下相容,在項目中會頻繁用到。
先說下3.0的Fragment用法。
其中,Fragment的生命週期就不多說了,首先構建Fragment 的View對象。
@Overridepublic View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {// TODO Auto-generated method stubView v = inflater.inflate(R.layout.fragment02, null);return v;}
然後在Activity中顯示目標Fragment。
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); fg3 = new Fragment03(); //擷取fragment管理器 FragmentManager fm = getFragmentManager(); //開啟事務 FragmentTransaction ft = fm.beginTransaction(); //把內容顯示至幀布局 ft.replace(R.id.fl, fg3); //提交 ft.commit(); }
需要注意的是Fragment只能替換Activity中的FrameLayout。
<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" android:orientation="horizontal" > <FrameLayout android:id="@+id/fl" android:layout_weight="1" android:layout_width="0dp" android:layout_height="match_parent" ></FrameLayout> <LinearLayout android:layout_width="wrap_content" android:layout_height="match_parent" android:orientation="vertical" > <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="fragment01" android:onClick="click1" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="fragment02" android:onClick="click2" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="fragment03" android:onClick="click3" /> </LinearLayout></LinearLayout>
之後我們說下Fragment 的向下相容模式:
首先,我們要先匯入系統內建的V4包。
package com.itheima.supportfragment;import android.os.Bundle;import android.app.Activity;import android.support.v4.app.FragmentActivity;import android.support.v4.app.FragmentManager;import android.support.v4.app.FragmentTransaction;import android.view.Menu;import android.view.View;public class MainActivity extends FragmentActivity { private Fragment03 fg3;@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); fg3 = new Fragment03(); //擷取fragment管理器 FragmentManager fm = getSupportFragmentManager(); //開啟事務 FragmentTransaction ft = fm.beginTransaction(); //把內容顯示至幀布局 ft.replace(R.id.fl, fg3); //提交 ft.commit(); }}
與上者使用方法大體相同,都是替換Activity中的FrameLayout布局。
最後說下Activity與Fragment之間資料的傳遞。
@Overridepublic View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {// TODO Auto-generated method stubView v = inflater.inflate(R.layout.fragment01, null);final EditText et = (EditText) v.findViewById(R.id.et);Button bt = (Button) v.findViewById(R.id.bt);bt.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {String text = et.getText().toString();//把資料傳遞給activity((MainActivity)getActivity()).setText(text);}});return v;}Fragment向Activity傳遞資料時,直接調用getActivity()擷取Activity的對象。
public void click4(View v){ String text = et_main.getText().toString(); //傳遞資料 fg3.setText(text); }Activity向Fragment傳遞資料時,先new一個Fragment即可。
但是一般Fragment與Activity之間最好利用回調介面的方式進行資料傳遞。這樣做的好處是利於Fragment的重用性。
public static class FragmentA extends ListFragment{ ... //Container Activity must implement this interface public interface OnArticleSelectedListener{ public void onArticleSelected(Uri articleUri); } ...}
public static class FragmentA extends ListFragment{ OnArticleSelectedListener mListener; ... @Override public void onAttach(Activity activity){ super.onAttach(activity); try{ mListener =(OnArticleSelectedListener)activity; }catch(ClassCastException e){ throw new ClassCastException(activity.toString()+"must implement OnArticleSelectedListener"); } } ...}
如果activity沒有實現那個介面,fragment拋出ClassCastException異常。如果成功了,mListener成員變數儲存OnArticleSelectedListener的執行個體。於是fragmentA就可以調用mListener的方法來與activity共用事件。例如,如果fragmentA是一個ListFragment,每次選中列表的一項時,就會調用fragmentA的onListItemClick()方法,在這個方法中調用onArticleSelected()來與activity共用事件,如下:
public static class FragmentA extends ListFragment{ OnArticleSelectedListener mListener; ... @Override public void onListItemClick(ListView l,View v,int position,long id){ //Append the clicked item's row ID with the content provider Uri Uri noteUri =ContentUris.withAppendedId(ArticleColumns.CONTENT_URI,id); //Send the event and Uri to the host activity mListener.onArticleSelected(noteUri); } ...}
FragmentManager用來管理Fragment的,利用Activity的getFragmentManager()取得它的執行個體.
FragmentManager可以做如下一些事情:
1、使用findFragmentById() (用於在activity layout中提供一個UI的fragment)或findFragmentByTag()(適用於有或沒有UI的fragment)擷取activity中存在的fragment
2、將fragment從後台堆棧中彈出, 使用 popBackStack()
3、使用addOnBackStackChangeListener()註冊一個監聽後台堆棧變化的listener.
FragmentTransaction是對Fragment進行添加,替換,移除等操作的。
在使用add(),replace(),remove()時可以動態給每一個Fragment添加一個標籤,下次方便FragmentManager通過tag標籤進行尋找。最後記得ft.commit();
當執行一個移除fragment的事務時, 如果沒有調用 addToBackStack(), 那麼當事務提交後, 那個fragment會被銷毀,並且使用者不能導航回到它. 有鑒於此, 當移除一個fragment時,如果調用了 addToBackStack(), 那麼fragment會被停止, 如果使用者導航回來,它將會被恢複.////我認為是重要的, 以上的話,可以理解,remove後,加到堆棧後。按返回還是可以返回到之前的fragment。fragment的顯示和隱藏可以用FragmentTransaction的show 或是hide來實現, ft.show(fragment); ft.hide(fragment);
Fragment,FragmentManager, FragmentTransaction詳解