日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

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

發(fā)布時(shí)間:2025/6/15 编程问答 52 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Fragment详解之五——Fragment间参数传递 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

相關(guān)文章:

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


在關(guān)Fragment間參數(shù)的傳遞,有兩種情況:

  • 第一種情況:同一個(gè)container中不同fragment間的參數(shù)傳遞。這種情況一般發(fā)生在fragment跳轉(zhuǎn)時(shí),上一個(gè)Fragment將參數(shù)傳遞給下一個(gè)Fragment。
  • 第二種情況:是同一個(gè)Activity中,不個(gè)container間Fragment的參數(shù)傳遞。
有關(guān)第一種情況,以前寫過一篇文章,詳細(xì)說明了上一個(gè)Fragment將參數(shù)傳遞給下一個(gè)Fragment,及數(shù)據(jù)回傳的方法。詳細(xì)參見: 《Fragment跳轉(zhuǎn)時(shí)傳遞參數(shù)及結(jié)果回傳的方法》

下面詳細(xì)看看這兩種參數(shù)傳遞方法。

一、同一個(gè)container間的參數(shù)傳遞。

有關(guān)這個(gè)問題,請(qǐng)大家移步以前寫的一篇文章:《Fragment跳轉(zhuǎn)時(shí)傳遞參數(shù)及結(jié)果回傳的方法》,在這篇文章中有關(guān)Fragment跳轉(zhuǎn)時(shí)的參數(shù)傳遞和結(jié)果回傳已經(jīng)講的很清楚了,這里就沒必要重新再寫一遍,下面是這篇文章的效果圖:

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

二、同一個(gè)Activity,不同container間的參數(shù)傳遞

這里到了這篇文章的重點(diǎn)內(nèi)容了哦,這可并不是說上一部分不重要哈,其實(shí)上一部分要比這部分重要!同一個(gè)container中不同F(xiàn)ragment間的參數(shù)傳遞一般的工程都會(huì)用到的,所以大家一定要看。而我這里不講,是因?yàn)橐郧坝兄v過,這里就沒必要再重復(fù)一遍了,好了,廢話說了好多……開整吧。
先看看效果圖:
1、在這個(gè)Actiivty中有兩個(gè)Fragment;
2、Fragment1中有一個(gè)listView,當(dāng)我們點(diǎn)擊ListView的Item的時(shí)候,把Item上的內(nèi)容更新到Fragment2上


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

方法一:直接在Activity中操作

在Activity中找到對(duì)應(yīng)的控件實(shí)例,然后直接操控即可。
先看看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>??
  • 在這個(gè)布局中,橫向放兩個(gè)fragment,由于這里的fragment是靜態(tài)添加的,所以每個(gè)fragment都是有id值的,所以這時(shí)候如果我們要獲取某個(gè)fragment的實(shí)例,就可以通過FragmentManager::findFragmentById()來找到了。
    然后是這兩個(gè)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的布局中,除了一個(gè)標(biāo)識(shí)當(dāng)前Fragment的TextView,就是一個(gè)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中非常干凈,只有一個(gè)TextView來顯示當(dāng)前用戶在fragment1中的點(diǎn)擊結(jié)果。
    下面看看在MainActivity中是如何實(shí)現(xiàn)的吧
    [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,然后直接對(duì)他們進(jìn)行操作。即下面的代碼:
    [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]);??
  • ????}??
  • });??
  • 當(dāng)用戶點(diǎn)擊listView的一個(gè)item時(shí),將值setText到fragment2的textView中。
    源碼在文章底部給出

    可見,直接在activity中操作各個(gè)fragment的控件就可以實(shí)現(xiàn)消息互傳。但,這樣真的好嗎?如果每個(gè)fragment中的控件都在Activity中操作,那還要fragment干嘛!最最起碼,應(yīng)該每個(gè)fragment負(fù)責(zé)自己的控件操作才對(duì)嘛!
    所以,我們對(duì)這種方法進(jìn)行改進(jìn),將點(diǎn)擊Item的賦值操作放到fragment1中去。所以,這就有方法二;

    方法二:直接在fragment中操作

    在這里我們會(huì)把所有方法寫在Fragment1中,這里涉及到兩方面的內(nèi)容:
    第一:在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()中,還沒有創(chuàng)建視圖,所以在這里如果使用getView()方法將返回空。所以如果要獲取其實(shí)圖中指定控件的引用,只用用inflater.inflate()返回的rootView;在這個(gè)rootView()中用findViewById來查找。
    方法二:在onActivityCreated()函數(shù)中獲取。
    從 《Fragment詳解之一——概述》的流程圖中可以看到,onActivityCreated()回調(diào)會(huì)在Activity的OnCreate()執(zhí)行完成后再執(zhí)行,也就是說,onActivityCreated()會(huì)在Activity的OnCreate()工作完成以后才會(huì)執(zhí)行。所以當(dāng)執(zhí)行到onActivityCreated()的時(shí)候Activity已經(jīng)創(chuàng)建完成,它其中的各個(gè)fragment也視圖等等的也都已經(jīng)創(chuàng)建完成。所在可以在這里獲取跟Activity相關(guān)的各種資源。第二個(gè)問題中的獲取其它Fragment頁面中控件的引用也是在onActivityCreated()中來做的。先看看在onActivityCreated()中如何獲得自己視圖中控件的引用吧

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

    [java] view plaincopy
  • public?void?onActivityCreated(Bundle?savedInstanceState)?{??
  • ????super.onActivityCreated(savedInstanceState);??
  • ??
  • ????mFragment2_tv?=?(TextView)?getActivity().findViewById(R.id.fragment2_tv);//獲取其它fragment中的控件引用的唯一方法!!!??
  • ??
  • }??
  • 上面講了一堆之后,下面就看看在Fragment1中如何實(shí)現(xiàn)的吧。
    由上面的講述可知,無論是獲取自己視圖中控件的引用還是獲取其它fragment中控件的引用都可以放在onActivityCreated()函數(shù)中,所以我們就把它們?nèi)糠旁趏nActivityCreated()中來實(shí)現(xiàn)了。
    [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);??
  • ????????}??
  • ????});??
  • }??
  • 難度不大,也是獲取到了每個(gè)控件以后,直接對(duì)他們進(jìn)行操作。
    源碼在文章底部給出

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

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

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

    [java] view plaincopy
  • public?class?Fragment2?extends?Fragment?{??
  • ????private?TextView?mTv;??
  • ????…………??
  • ????public?void?setText(String?text)?{??
  • ????????mTv.setText(text);??
  • ????}??
  • }??
  • 2、Fragment1中的處理方式:
    (1)、定義接口及變量
    由于是用回調(diào),所以要先定義一個(gè)接口及對(duì)應(yīng)的變量:
    [java] view plaincopy
  • private?titleSelectInterface?mSelectInterface;??
  • ???
  • public?interface?titleSelectInterface{??
  • ????public?void?onTitleSelect(String?title);??
  • }??
  • (2)、接口變量賦值
    接口是給activity用的,所以要在activity中給這里的接口變量賦值,可以有很多方法,當(dāng)然可以選擇寫一個(gè)setXXX()函數(shù)來賦值,但如果用戶忘了怎么辦?所以我們要強(qiáng)制用戶賦值。所以采用強(qiáng)轉(zhuǎn)的方式,在fragment與activity相關(guān)聯(lián)時(shí),進(jìn)行強(qiáng)轉(zhuǎn)賦值:
    [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");??
  • ????}??
  • }??
  • 采用強(qiáng)轉(zhuǎn)的方式的問題在于,如果用戶的activity沒有implements titleSelectInterface,就會(huì)拋出錯(cuò)誤,所以在調(diào)試過程中就會(huì)發(fā)現(xiàn)。
    (3)、調(diào)用接口變量
    下一步就是在fragment1中在用戶點(diǎn)擊listView的item的時(shí)候,將結(jié)果回傳給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中實(shí)現(xiàn)titleSelectInterface接口
    首先是MainActivity必須實(shí)現(xiàn)titleSelectInterface接口,然后結(jié)果會(huì)在onTitleSelect(String title)中返回,在結(jié)果返回后利用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);??
  • ????}??
  • }??
  • 在上面代碼中可以看出,在結(jié)果返回后,通過findFragmentById()來獲得fragment2的實(shí)例,這里首次出現(xiàn)了findFragmentById()函數(shù)的用法,這個(gè)函數(shù)主要用來靜態(tài)添加的fragment中,通過fragment的ID值來獲取它的實(shí)例。在獲得fragment2的實(shí)例以后,通過調(diào)用我們寫好了setText()方法來將結(jié)果顯示在textView中。
    [java] view plaincopy
  • Fragment2?fragment2?=?(Fragment2)manager.findFragmentById(R.id.fragment2);??
  • OK啦,到這里這篇文章就結(jié)束啦,源碼過來啦。

    參考文章:

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

    2、《Inter-Fragment Communication》

    總結(jié)

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

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。