天天看點

Fragment初學7——Fragment在Android開發中的應用1

Fragment的常用功能

通過getFragmentManager()方法,可以得到FragmentManager對象,主要完成下面的功能

(1).得到已經存在Fragment對象

如果該fragment在布局檔案中指定了id,通過findFragmentById()得到對象,或者指定了tag可以通過findFragmentByTag()得到對象

Fragment fragment = getFragmentManager().findFragmentByTag("one"); 

Fragment fragment = getFragmentManager().findFragmentById(id); 

(2).注冊OnBackStackChangedListener監聽器

可以用來監聽該任務對應的傳回棧資訊,當該傳回棧狀态發生改變時,執行對應的onBackStackChanged()方法

manager.addOnBackStackChangedListener(new FragmentManager.OnBackStackChangedListener() { 

    @Override  

    public void onBackStackChanged() {  

        Toast.makeText(MainActivity.this, "傳回棧狀态發生改變", Toast.LENGTH_SHORT).show(); 

    }  

});  

(3).彈出傳回棧

模拟使用者點選傳回鍵,将指定的fragment從傳回棧中彈出,該操作為異步的。前提是該fragment對象使用beginTransaction().addToBackStack("right")添加進傳回棧

 //Pop the top state off the back stack

manager.popBackStack();

(4).FragmentTransaction事務

事務主要包含一些操作的集合,比如增加移除替換,動畫設定等等

FragmentManager fragmentManager = getFragmentManager();

        FragmentTransaction transaction = fragmentManager.beginTransaction();

        transaction.add(R.id.framelayout_fragment_main, new FragmentOne(), "ONE");

        transaction.commit();

(5).Fragment狀态管理

/* 

 * 管理Fragment的狀态 

 *  如果在一個主activityViewGroup中添加一個fragment, 

 *  如果手機螢幕旋轉了,目前activity被銷毀重建,fragment也被activityManager建立 

 *  故在onCreate中,需要判斷一下 

 */  

@Override  

protected void onCreate(Bundle savedInstanceState) {  

    super.onCreate(savedInstanceState);  

    setContentView(R.layout.activity_main);  

  FragmentManager manager = getFragmentManager(); 

   if (manager.findFragmentByTag("TWO") == null) { 

       // if(savedInstanceState == null)也可判斷該fragment是否已經加載  

        manager.beginTransaction()  

            .replace(R.id.framelayout_fragment_main, fragmentTwo, "TWO") 

           .setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN)// 設定動畫  

           .addToBackStack("TWO") // 将該fragment加入傳回堆  

        // 送出事務  

        .commit();  

}  

fragment辨別符

每個fragment需要定義一個唯一的辨別符,如果activity被銷毀又重新啟動,系統能夠恢複該fragment的狀态。如果想重新恢複,需滿足下面有3種方式之一:

1.  定義ID

在布局檔案中,通過定義android:id屬性定義,例如

<fragment

        android:id="@+id/fragment_title_main"

        android:name="com.example.activity.TitleFragment"

        android:layout_width="match_parent"

        android:layout_height="45dp" />

2.指明tag

也可以在布局檔案中,通過定義android:id屬性定義,例如

       android:tag="title"

    或者使用FragmentTransaction對象的add()和replace()時指定tag,例如

       FragmentTransaction transaction = fragmentManager.beginTransaction();

       transaction.commit();

或者

       transaction.replace(R.id.framelayout_fragment_main, fragmentTwo, "TWO");

       transaction.addToBackStack(null);

        transaction.commit();

3.viewgroup ID

如果該fragment既沒有id也沒有tag,系統将使用container view布局的id

下面是一個舉例說明,demo有一個主界面,三個fragment,點選第一個按鈕,切換到第二個界面,點選第二個按鈕,切換到第三個界面,然後點選Back鍵依次回退。這很類似Android的 Activity跳轉,當然這裡是Fragment實作的,使用者點選Back鍵,實際是Fragment回退棧不斷的彈棧。調用FragmentTransaction.addToBackStack(String)添加一個Fragment事務到回退棧

MainActivity.java代碼如下

public class MainActivity extends Activity {

    @Override

    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        requestWindowFeature(Window.FEATURE_NO_TITLE);

        // getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,

        // WindowManager.LayoutParams.FLAG_FULLSCREEN);

        setContentView(R.layout.activity_main);

        FragmentManager fragmentManager = getFragmentManager();

//直接将FragmentOne添加到布局檔案中的FrameLayout中

    }

}

布局如下

<?xml version="1.0" encoding="utf-8"?>

<RelativeLayout xmlns:android="

http://schemas.android.com/apk/res/android

"

    android:layout_width="match_parent"

    android:layout_height="match_parent" >

    <FrameLayout

        android:id="@+id/framelayout_fragment_main"

        android:layout_height="match_parent" />

</RelativeLayout>

FragmentOne.java如下

public class FragmentOne extends Fragment {

    private Button mButton;

    public View onCreateView(LayoutInflater inflater, ViewGroup container,

            Bundle savedInstanceState) {

        // return inflater.inflate(R.layout.fragment_one, container, false);

        View view = inflater.inflate(R.layout.fragment_one, container, false);

        mButton = (Button) view.findViewById(R.id.btn_fragment_one);

        mButton.setOnClickListener(new OnClickListener() {

            @Override

            public void onClick(View v) {

                // TODO Auto-generated method stub

                FragmentTwo fragmentTwo = new FragmentTwo();

                FragmentManager fragmentManager = getFragmentManager();

                FragmentTransaction transaction = fragmentManager.beginTransaction();

                transaction.replace(R.id.framelayout_fragment_main, fragmentTwo, "TWO");

                transaction.addToBackStack(null);

                transaction.commit();

            }

        });

        return view;

replace()方法,實際是remove和add的合體, 并且如果不添加事務到回退棧,前一個Fragment執行個體會被銷毀。這裡我們調用transaction.addToBackStack(null);将目前的事務添加到了回退棧,是以FragmentOne執行個體不會被銷毀,但是視圖層次依然會被銷毀,即會調用onDestoryView和

onCreateView,從效果上看就是我們在跳轉前在文本框輸入的内容,在使用者Back得到第一個界面的時候不見了。

FragmentTwo.java代碼如下

public class FragmentTwo extends Fragment {

        View view = inflater.inflate(R.layout.fragment_two, container, false);

        mButton = (Button) view.findViewById(R.id.btn_fragment_two);

                FragmentThree fragmentThree = new FragmentThree();

                transaction.hide(FragmentTwo.this);

                transaction.add(R.id.framelayout_fragment_main, fragmentThree, "THREE");

在FragmentTwo中我們沒有使用replace,而是先隐藏了目前的Fragment,然後添加了FragmentThree的執行個體,最後将事務添加到回退棧。這樣做的目的就是視圖不會重繪,也就是我們在FragmentTwo的EditText填寫的内容,使用者Back

回來時,資料還儲存着。

源代碼

參考文章:

http://blog.csdn.net/zimo2013/article/details/12239349 http://blog.csdn.net/lmj623565791/article/details/37992017

繼續閱讀