日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

Fragment详解之五——Fragment间参数传递

發布時間:2025/6/15 81 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Fragment详解之五——Fragment间参数传递 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

相關文章:

1、《Fragment詳解之一——概述》
2、《Fragment詳解之二——基本使用方法》
3、《Fragment詳解之三——管理Fragment(1)》
4、《Fragment詳解之四——管理Fragment(2)》
5、《Fragment詳解之五——Fragment間參數傳遞》
6、《Fragment詳解之六——如何監聽fragment中的回退事件與怎樣保存fragment狀態》


在關Fragment間參數的傳遞,有兩種情況:

  • 第一種情況:同一個container中不同fragment間的參數傳遞。這種情況一般發生在fragment跳轉時,上一個Fragment將參數傳遞給下一個Fragment。
  • 第二種情況:是同一個Activity中,不個container間Fragment的參數傳遞。
有關第一種情況,以前寫過一篇文章,詳細說明了上一個Fragment將參數傳遞給下一個Fragment,及數據回傳的方法。詳細參見: 《Fragment跳轉時傳遞參數及結果回傳的方法》

下面詳細看看這兩種參數傳遞方法。

一、同一個container間的參數傳遞。

有關這個問題,請大家移步以前寫的一篇文章:《Fragment跳轉時傳遞參數及結果回傳的方法》,在這篇文章中有關Fragment跳轉時的參數傳遞和結果回傳已經講的很清楚了,這里就沒必要重新再寫一遍,下面是這篇文章的效果圖:

  • 1、在界面開始時,點擊“加載第二個Fragment”按鈕
  • 2、調起Fragment2,并向其傳遞一個參數“從Fragment1傳來的參數”,顯示在Fragment2中
  • 3、點擊Fragment2中的四個小動物中的一個,會向Fragment1回傳用戶點擊的是哪個動物,在Fragment1中顯示出來。
看起來挺有意思?那就移步到這篇文章里看看吧

二、同一個Activity,不同container間的參數傳遞

這里到了這篇文章的重點內容了哦,這可并不是說上一部分不重要哈,其實上一部分要比這部分重要!同一個container中不同Fragment間的參數傳遞一般的工程都會用到的,所以大家一定要看。而我這里不講,是因為以前有講過,這里就沒必要再重復一遍了,好了,廢話說了好多……開整吧。
先看看效果圖:
1、在這個Actiivty中有兩個Fragment;
2、Fragment1中有一個listView,當我們點擊ListView的Item的時候,把Item上的內容更新到Fragment2上


這里有多種實現方法,最可取的是方法三。我們由簡到易慢慢講。
我們想使兩個fragment實例要能通信,那如果我們都能通過findViewById()找到所有的控件,直接操控的話,豈不就實現了。而通過findViewById()能找到所有控件實例的地方就是在Activity中了,所以這就有了方法一。

方法一:直接在Activity中操作

在Activity中找到對應的控件實例,然后直接操控即可。
先看看MainActivity的布局:activity_main.xml

[html] view plaincopy
  • <LinearLayout?xmlns:android="http://schemas.android.com/apk/res/android"??
  • ????android:id="@+id/main_layout"??
  • ????android:layout_width="match_parent"??
  • ????android:layout_height="match_parent"??
  • ????android:orientation="horizontal"??
  • ????android:baselineAligned="false"?>??
  • ??
  • ????<fragment??
  • ????????android:id="@+id/fragment1"??
  • ????????android:name="com.harvic.com.harvicblog5_1.Fragment1"??
  • ????????android:layout_width="0dip"??
  • ????????android:layout_height="match_parent"??
  • ????????android:layout_weight="1"?/>??
  • ??
  • ????<fragment??
  • ????????android:id="@+id/fragment2"??
  • ????????android:name="com.harvic.com.harvicblog5_1.Fragment2"??
  • ????????android:layout_width="0dip"??
  • ????????android:layout_height="match_parent"??
  • ????????android:layout_weight="1"?/>??
  • </LinearLayout>??
  • 在這個布局中,橫向放兩個fragment,由于這里的fragment是靜態添加的,所以每個fragment都是有id值的,所以這時候如果我們要獲取某個fragment的實例,就可以通過FragmentManager::findFragmentById()來找到了。
    然后是這兩個fragment的布局。
    fragment1.xml:

    [html] view plaincopy
  • <LinearLayout?xmlns:android="http://schemas.android.com/apk/res/android"??
  • ????android:layout_width="match_parent"??
  • ????android:layout_height="match_parent"??
  • ????android:background="#ff00ff"??
  • ????android:orientation="vertical"?>??
  • ??????
  • ????<TextView??
  • ????????android:layout_width="wrap_content"??
  • ????????android:layout_height="wrap_content"??
  • ????????android:text="This?is?fragment?1"??
  • ????????android:textColor="#000000"??
  • ????????android:textSize="25sp"?/>??
  • ??
  • ????<ListView??
  • ????????android:id="@+id/list"??
  • ????????android:layout_width="match_parent"??
  • ????????android:layout_height="match_parent"></ListView>??
  • </LinearLayout>??
  • 可以看到fragment1的布局中,除了一個標識當前Fragment的TextView,就是一個listview;
    fragment2.xml:
    [html] view plaincopy
  • <LinearLayout?xmlns:android="http://schemas.android.com/apk/res/android"??
  • ????android:layout_width="match_parent"??
  • ????android:layout_height="match_parent"??
  • ????android:background="#ffff00"??
  • ????android:orientation="vertical"?>??
  • ??????
  • ????<TextView??
  • ????????android:id="@+id/fragment2_tv"??
  • ????????android:layout_width="wrap_content"??
  • ????????android:layout_height="wrap_content"??
  • ????????android:text="This?is?fragment?2"??
  • ????????android:textColor="#000000"??
  • ????????android:textSize="25sp"?/>??
  • ??????
  • </LinearLayout>??
  • 可以看到在fragment2中非常干凈,只有一個TextView來顯示當前用戶在fragment1中的點擊結果。
    下面看看在MainActivity中是如何實現的吧
    [java] view plaincopy
  • protected?void?onCreate(Bundle?savedInstanceState)?{??
  • ????super.onCreate(savedInstanceState);??
  • ????setContentView(R.layout.activity_main);??
  • ??
  • ????ArrayAdapter?arrayAdapter?=?new?ArrayAdapter<String>(this,android.R.layout.simple_list_item_1,mStrings);??
  • ????ListView?listView?=?(ListView)findViewById(R.id.list);??
  • ????listView.setAdapter(arrayAdapter);??
  • ??
  • ????mFragment2_tv?=?(TextView)findViewById(R.id.fragment2_tv);??
  • ??
  • ????listView.setOnItemClickListener(new?AdapterView.OnItemClickListener()?{??
  • ????????@Override??
  • ????????public?void?onItemClick(AdapterView<?>?parent,?View?view,?int?position,?long?id)?{??
  • ????????????mFragment2_tv.setText(mStrings[position]);??
  • ????????}??
  • ????});??
  • }??
  • 其中:
    [java] view plaincopy
  • private?String[]?mStrings?=?{"Abbaye?de?Belloc",?"Abbaye?du?Mont?des?Cats",?"Abertam",?"Abondance",?"Ackawi",??
  • ????????"Acorn",?"Adelost",?"Affidelice?au?Chablis",?"Afuega'l?Pitu",?"Airag",?"Airedale",?"Aisy?Cendre",??
  • ????????"Allgauer?Emmentaler",?"Abbaye?de?Belloc",?"Abbaye?du?Mont?des?Cats",?"Abertam",?"Abondance",?"Ackawi",??
  • ????????"Acorn",?"Adelost",?"Affidelice?au?Chablis",?"Afuega'l?Pitu",?"Airag",?"Airedale",?"Aisy?Cendre",??
  • ????????"Allgauer?Emmentaler"};??
  • 難度不大,通過(ListView)findViewById(R.id.list);找到fragment1中的listview,通過(TextView)findViewById(R.id.fragment2_tv);找到fragment2中的textView,然后直接對他們進行操作。即下面的代碼:
    [java] view plaincopy
  • listView.setOnItemClickListener(new?AdapterView.OnItemClickListener()?{??
  • ????@Override??
  • ????public?void?onItemClick(AdapterView<?>?parent,?View?view,?int?position,?long?id)?{??
  • ????????mFragment2_tv.setText(mStrings[position]);??
  • ????}??
  • });??
  • 當用戶點擊listView的一個item時,將值setText到fragment2的textView中。
    源碼在文章底部給出

    可見,直接在activity中操作各個fragment的控件就可以實現消息互傳。但,這樣真的好嗎?如果每個fragment中的控件都在Activity中操作,那還要fragment干嘛!最最起碼,應該每個fragment負責自己的控件操作才對嘛!
    所以,我們對這種方法進行改進,將點擊Item的賦值操作放到fragment1中去。所以,這就有方法二;

    方法二:直接在fragment中操作

    在這里我們會把所有方法寫在Fragment1中,這里涉及到兩方面的內容:
    第一:在Fragment中如何獲得自己控件的引用,比較這里Fragment1里的listview控件。
    第二:在Fragment中如何獲得其它Fragment頁面中控件的引用,比如這里Fragment2里的TextView控件。

    首先,獲取自己控件引用的方法:
    方法一:在onCreateView()中獲取。
    就比如這里獲取自己的listView控件的引用,代碼如下:

    [java] view plaincopy
  • public?View?onCreateView(LayoutInflater?inflater,?ViewGroup?container,??
  • ????????Bundle?savedInstanceState)?{??
  • ????View?rootView?=?inflater.inflate(R.layout.fragment1,?container,?false);??
  • ????listView?=?(ListView)rootView.findViewById(R.id.list);//獲取自己視圖里的控件引用,方法一??
  • ????return?rootView;??
  • }??
  • 由于在onCreateView()中,還沒有創建視圖,所以在這里如果使用getView()方法將返回空。所以如果要獲取其實圖中指定控件的引用,只用用inflater.inflate()返回的rootView;在這個rootView()中用findViewById來查找。
    方法二:在onActivityCreated()函數中獲取。
    從 《Fragment詳解之一——概述》的流程圖中可以看到,onActivityCreated()回調會在Activity的OnCreate()執行完成后再執行,也就是說,onActivityCreated()會在Activity的OnCreate()工作完成以后才會執行。所以當執行到onActivityCreated()的時候Activity已經創建完成,它其中的各個fragment也視圖等等的也都已經創建完成。所在可以在這里獲取跟Activity相關的各種資源。第二個問題中的獲取其它Fragment頁面中控件的引用也是在onActivityCreated()中來做的。先看看在onActivityCreated()中如何獲得自己視圖中控件的引用吧

    [java] view plaincopy
  • public?void?onActivityCreated(Bundle?savedInstanceState)?{??
  • ????super.onActivityCreated(savedInstanceState);??
  • ??
  • ????listView?=?(ListView)?getView().findViewById(R.id.list);//獲取自己視圖里的控件引用,方法二??
  • }???
  • 然后,獲得其它Fragment頁面中控件的引用的方法
    在上面已經說了,要獲取Activity中的資源,就必須等Acitivity創建完成以后,所以必須放在onActivityCreated()回調函數中。
    其獲取方法為:

    [java] view plaincopy
  • public?void?onActivityCreated(Bundle?savedInstanceState)?{??
  • ????super.onActivityCreated(savedInstanceState);??
  • ??
  • ????mFragment2_tv?=?(TextView)?getActivity().findViewById(R.id.fragment2_tv);//獲取其它fragment中的控件引用的唯一方法!!!??
  • ??
  • }??
  • 上面講了一堆之后,下面就看看在Fragment1中如何實現的吧。
    由上面的講述可知,無論是獲取自己視圖中控件的引用還是獲取其它fragment中控件的引用都可以放在onActivityCreated()函數中,所以我們就把它們全部放在onActivityCreated()中來實現了。
    [java] view plaincopy
  • public?void?onActivityCreated(Bundle?savedInstanceState)?{??
  • ????super.onActivityCreated(savedInstanceState);??
  • ??
  • ????mFragment2_tv?=?(TextView)?getActivity().findViewById(R.id.fragment2_tv);//獲取其它fragment中的控件引用的唯一方法!!!??
  • ????listView?=?(ListView)?getView().findViewById(R.id.list);//獲取自己視圖里的控件引用,方法二??
  • ??
  • ????ArrayAdapter?arrayAdapter?=?new?ArrayAdapter<String>(getActivity(),?android.R.layout.simple_list_item_1,?mStrings);??
  • ????listView.setAdapter(arrayAdapter);??
  • ????listView.setOnItemClickListener(new?AdapterView.OnItemClickListener()?{??
  • ????????@Override??
  • ????????public?void?onItemClick(AdapterView<?>?parent,?View?view,?int?position,?long?id)?{??
  • ????????????String?str?=?mStrings[position];??
  • ????????????mFragment2_tv.setText(str);??
  • ????????}??
  • ????});??
  • }??
  • 難度不大,也是獲取到了每個控件以后,直接對他們進行操作。
    源碼在文章底部給出

    我們這里直接在fragment1中操作了fragment2的控件,這樣就違背了模塊分離的思想,我們應該讓他們各自處理各自的代碼才好。所以,考慮到將他們分離,我們這里就出現了方法三。

    方法三:在各自的fragment中操作

    好,我們先想想要怎么解決這個問題,首先,我們把各自的事件放在各自的fragment中處理,即在fragment1中能得到當前用戶點擊的ITEM的String字符串,在fragment2中可以設置textview的值。那問題來了,各自獲得了各自的東東,那通過什么讓他們交互呢?
    答案顯然是activity。
    很顯然,在activity中可以直接通過FragmentManager::findFragmentById()來獲取fragment2的實例。進而調用fragment2中的任意方法,這就實現了與fragment2的通信。
    那fragment1又怎么把結果回傳給Activity呢?大家如果在看到這里之前先看了《Fragment跳轉時傳遞參數及結果回傳的方法》就很容易想到,用回調!請記住。在不同頁面中回傳結果,回調是萬能的解決方案。
    1、Fragment2設置textView函數:
    先看個簡單的,fragment2中的處理代碼:

    [java] view plaincopy
  • public?class?Fragment2?extends?Fragment?{??
  • ????private?TextView?mTv;??
  • ????…………??
  • ????public?void?setText(String?text)?{??
  • ????????mTv.setText(text);??
  • ????}??
  • }??
  • 2、Fragment1中的處理方式:
    (1)、定義接口及變量
    由于是用回調,所以要先定義一個接口及對應的變量:
    [java] view plaincopy
  • private?titleSelectInterface?mSelectInterface;??
  • ???
  • public?interface?titleSelectInterface{??
  • ????public?void?onTitleSelect(String?title);??
  • }??
  • (2)、接口變量賦值
    接口是給activity用的,所以要在activity中給這里的接口變量賦值,可以有很多方法,當然可以選擇寫一個setXXX()函數來賦值,但如果用戶忘了怎么辦?所以我們要強制用戶賦值。所以采用強轉的方式,在fragment與activity相關聯時,進行強轉賦值:
    [java] view plaincopy
  • public?void?onAttach(Activity?activity)?{??
  • ????super.onAttach(activity);??
  • ??
  • ????try?{??
  • ????????mSelectInterface?=?(titleSelectInterface)?activity;??
  • ????}?catch?(Exception?e)?{??
  • ????????throw?new?ClassCastException(activity.toString()?+?"must?implement?OnArticleSelectedListener");??
  • ????}??
  • }??
  • 采用強轉的方式的問題在于,如果用戶的activity沒有implements titleSelectInterface,就會拋出錯誤,所以在調試過程中就會發現。
    (3)、調用接口變量
    下一步就是在fragment1中在用戶點擊listView的item的時候,將結果回傳給Activity了,代碼如下:
    [java] view plaincopy
  • public?void?onActivityCreated(Bundle?savedInstanceState)?{??
  • ????super.onActivityCreated(savedInstanceState);??
  • ??
  • ????listView?=?(ListView)?getView().findViewById(R.id.list);//獲取自己視圖里的控件引用,方法二??
  • ????ArrayAdapter?arrayAdapter?=?new?ArrayAdapter<String>(getActivity(),?android.R.layout.simple_list_item_1,?mStrings);??
  • ????listView.setAdapter(arrayAdapter);??
  • ????listView.setOnItemClickListener(new?AdapterView.OnItemClickListener()?{??
  • ????????@Override??
  • ????????public?void?onItemClick(AdapterView<?>?parent,?View?view,?int?position,?long?id)?{??
  • ????????????String?str?=?mStrings[position];??
  • ????????????mSelectInterface.onTitleSelect(str);??
  • ????????}??
  • ????});??
  • }??
  • (4)、在Activity中實現titleSelectInterface接口
    首先是MainActivity必須實現titleSelectInterface接口,然后結果會在onTitleSelect(String title)中返回,在結果返回后利用fragment2.setText()操作textView;代碼如下:
    [java] view plaincopy
  • public?class?MainActivity?extends?FragmentActivity?implements?Fragment1.titleSelectInterface?{??
  • ??
  • ????……??
  • ??????
  • ????@Override??
  • ????public?void?onTitleSelect(String?title)?{??
  • ????????FragmentManager?manager?=?getSupportFragmentManager();??
  • ????????Fragment2?fragment2?=?(Fragment2)manager.findFragmentById(R.id.fragment2);??
  • ????????fragment2.setText(title);??
  • ????}??
  • }??
  • 在上面代碼中可以看出,在結果返回后,通過findFragmentById()來獲得fragment2的實例,這里首次出現了findFragmentById()函數的用法,這個函數主要用來靜態添加的fragment中,通過fragment的ID值來獲取它的實例。在獲得fragment2的實例以后,通過調用我們寫好了setText()方法來將結果顯示在textView中。
    [java] view plaincopy
  • Fragment2?fragment2?=?(Fragment2)manager.findFragmentById(R.id.fragment2);??
  • OK啦,到這里這篇文章就結束啦,源碼過來啦。

    參考文章:

    1、《android Fragments詳解五:與activity通訊》?

    2、《Inter-Fragment Communication》

    總結

    以上是生活随笔為你收集整理的Fragment详解之五——Fragment间参数传递的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。