2013年1月17日 星期四

Fragment間的資料傳遞


HelloFragment這篇我們在Androdi寫了第一支的Fragment程式,在生命週期這篇我們明白了Fragment生命週期,接著我們繼續討論Fragment與Fragment間的資料傳遞。


複習一下HelloFragment這篇中實作2: 動態增加Fragment部分,我們使用FragmentManager類別來管理Activity的Fragment [見參考1]。所以我們可以透過FragmentManager中的findFragmentById() 或者 findFragmentByTag() 就可以改變Fragment中所定義的參數或布景元件等。
還有一個常用的類別就是FragmentTransaction,這個類別主要功能是可以在Activity中新增、刪除、修改、查詢 Fragment [見參考2]。
而在FragmentTransaction中有一個addToBackStack()方法,使用這個方法的時機通常是在尚未執行commit()前的UI介面增加到 Back Stack 中,當切到下一個Fragment畫面後可以按下倒退鍵便將上一個UI介面回復[見參考3]。

下面就用一個簡單的程式來實作Fragment與Fragment間的資料傳遞。

佈景:
activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="horizontal" >

    <LinearLayout
        android:id="@+id/rightLinearLayout"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:layout_weight="2"
        android:background="#DEDEEE"
        android:orientation="vertical" >
    </LinearLayout>

    <LinearLayout
        android:id="@+id/leftLinearLayout"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:layout_weight="1"
        android:background="#DEEEDE"
        android:orientation="vertical" >
    </LinearLayout>

</LinearLayout>


-------------------------------------------------------------------------------------------
fragment1.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Fragment1"
        android:textColor="#0000FF" />

    <Button
        android:id="@+id/left_button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="按鍵" />

</LinearLayout>


-------------------------------------------------------------------------------------------
fragment2.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Fragment2"
        android:textColor="#0000FF" />

    <EditText
        android:id="@+id/editText1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

</LinearLayout>


程式碼:
MainActivity.java

package edu.nkut.fragmenttest;

import android.app.Activity;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.os.Bundle;

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        MyFragment1 MyFragment1Ref = new MyFragment1();
        MyFragment2 MyFragment2Ref = new MyFragment2();

        FragmentManager fm = getFragmentManager();
        FragmentTransaction ft = fm.beginTransaction();
        ft.add(R.id.leftLinearLayout, MyFragment1Ref, "leftfragment");
        ft.add(R.id.rightLinearLayout, MyFragment2Ref, "rightfragment");
        // ft.addToBackStack(null);
        ft.commit();

    }
}


-------------------------------------------------------------------------------------------
MyFragment1.java

package edu.nkut.fragmenttest;

import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;

public class MyFragment1 extends Fragment {
    private Button button1;
    private View view;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        view = inflater.inflate(R.layout.fragment1, container, false);
        button1 = (Button) view.findViewById(R.id.left_button1);

        button1.setOnClickListener(new OnClickListener() {
            public void onClick(View v) {
                Fragment rightFragment = MyFragment1.this.getFragmentManager().findFragmentByTag("rightfragment");
                EditText editTextRef = (EditText) rightFragment.getView().findViewById(R.id.editText1);
                editTextRef.setText("按下 Fragment1 按鍵");
            }
        });
        return view;
    }
}


-------------------------------------------------------------------------------------------
MyFragment2.java

package edu.nkut.fragmenttest;

import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

public class MyFragment2 extends Fragment {

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View v = inflater.inflate(R.layout.fragment2, container, false);
        return v;
    }
}


執行結果:

上述執行程式時當按下Fragment1的按鍵時,會從Fragment1送一個字串到Fragment2的EditText。以上就完成了Fragment與Fragment間的資料傳遞,程式中在MainActivity.java中可以試試看有無ft.addToBackStack(null)在按下倒退鍵有何差別。至於其他相關部分如Activity與Fragment間的資料傳遞有空再整理分享了。



參考:
1.FragmentManager
http://developer.android.com/reference/android/app/FragmentManager.html

2.FragmentTransaction
http://developer.android.com/reference/android/app/FragmentTransaction.html

3.Tasks and Back Stack
http://developer.android.com/guide/components/tasks-and-back-stack.html



==============延伸閱讀=====================

1.第一支Android Fragment程式--HelloFragment
http://cheng-min-i-taiwan.blogspot.tw/2012/04/android-fragment-hellofragment.html

2.Android Fragments 的生命週期
http://cheng-min-i-taiwan.blogspot.tw/2012/12/android-fragments.html

3.Fragment間的資料傳遞
http://cheng-min-i-taiwan.blogspot.tw/2013/01/fragment.html

4.Fragment與Activity間的資料傳遞
http://cheng-min-i-taiwan.blogspot.tw/2013/02/fragmentactivity.html

5.Fragment子類別之ListFragment
http://cheng-min-i-taiwan.blogspot.tw/2013/02/fragmentlistfragment.html

6.Fragment子類別之DialogFragment
http://cheng-min-i-taiwan.blogspot.tw/2013/02/fragmentdialogfragment.html

7.Fragment子類別之PreferenceFragment
http://www.cheng-min-i-taiwan.blogspot.tw/2013/02/fragmentpreferencefragment.html

8.Fragment子類別之WebViewFragment
http://cheng-min-i-taiwan.blogspot.tw/2013/02/fragmentwebviewfragment.html

1 則留言: