關(guān)于android Fragment那些事

目錄

目錄.png

起源

android 3.0(api11)引入了fragment(碎片)這個概念泊藕,起初主要是為了給大屏幕(如平板電腦)上更加動態(tài)和靈活的 UI 設(shè)計提供支持艰亮。由于平板電腦的屏幕比手機屏幕大得多,因此可用于組合和交換 UI 組件的空間更大(類似于微信橫屏時方咆,朋友圈與好友列表顯示在同一頁,并各占一半蟀架,如下圖)瓣赂,但是實際上雖然因為需要適配平板我們也使用了fragment榆骚,但是更多的時候我們把fragment當做了可復用組件。


fragments.png

不僅僅是平板煌集,fragment在手機端的那些事

啪啦啪啦寫了一大堆妓肢,發(fā)現(xiàn)還是解釋不清fragment是啥,直接上圖吧苫纤,look:
簡書--簡單點.jpg

譬如簡書的app碉钠,下面是5個導航欄,對于5個完全不同的頁面卷拘。那這5個頁面可咋整呢喊废,我要把5個頁面寫到一個activity里面,然后通過點擊下面的導航欄來隱藏其他不需要的布局嗎栗弟?5個還好(其實也不好了)污筷,如果10個20個呢(譬如今日頭條上方的導航欄),這activity里面的代碼怎么頂?shù)米≌Ш眨敲炊鄻I(yè)務邏輯需要處理瓣蛀,這個時候fragment就起到了至關(guān)重要的作用。

你可以把fragment當成activity里的一個ui控件雷厂,每次點擊下方的導航欄都是切換到對應的fragment揪惦,即5個fragment對應著5個頁面 。

fragment的一些信息

  • fragment只能嵌套在activity中罗侯,不能獨立存在
  • fragment也有自己的生命周期器腋,但也正因為fragment依存于activity,所以activity的生命周期可以直接影響到fragment

優(yōu)點

  • fragment的可復用性钩杰,多個activity可以復用同一個fragment
  • fragment切換流暢纫塌,輕量切換,不像activity切換那么笨重
  • fragment在activity也可以動態(tài)的添加讲弄、切換措左、刪除,機動性高
  • 前面也說了避除,fragment一開始是為了適配平板引入的怎披,提供了更加動態(tài)和靈活的 UI
  • 什么?為什么這么吹fragment瓶摆?沒辦法凉逛,畢竟這章講的fragment,人家是主角(XD)

生命周期

是的你沒有看錯群井,又是生命周期状飞,老規(guī)矩,上圖,look:
fragment_lifecycle.png

onAttach:activity與fragment綁定
onCreate:fragment被創(chuàng)建
onCreateView:fragment加載視圖
(其實這里還有個生命周期是onViewCreate诬辈,在onCreateView執(zhí)行后立刻執(zhí)行酵使,看了下源碼,里面沒干啥子東西焙糟,可以在這個方法里面進行一些初始化操作口渔,初始化變量,綁定監(jiān)聽事件之類)
onActivityCreated:當Activity中的onCreate方法執(zhí)行完后調(diào)用穿撮。
onStart:跟activity一樣就不講了搓劫,詳情見上一章的關(guān)于android生命周期那點事
onDestroyView:銷毀fragment中的視圖
onDetach:activity與fragment解除綁定

activity與fragment生命周期對比

activity_fragment_lifecycle.png

當activity啟動時,執(zhí)行順序如下:

MainActivity: onCreate: 
MainActivity: onStart: 
Fragment: onAttach: 
Fragment: onCreate: 
Fragment: onCreateView: 
Fragment: onViewCreated: 
Fragment: onActivityCreated: 
Fragment: onStart: 
MainActivity: onResume: 
Fragment: onResume: 

home鍵按下時混巧,執(zhí)行順序如下:

MainActivity: onPause: 
Fragment: onPause: 
MainActivity: onStop: 
Fragment: onStop: 

再重新返回到該activity頁面時,執(zhí)行順序如下

MainActivity: onRestart: 
MainActivity: onStart: 
Fragment: onStart: 
MainActivity: onResume: 
Fragment: onResume: 

關(guān)閉該activity時勤揩,執(zhí)行順序如下:

MainActivity: onPause: 
Fragment: onPause: 
MainActivity: onStop: 
Fragment: onStop: 
MainActivity: onDestroy: 
Fragment: onDestroyView: 
Fragment: onDestroy: 
Fragment: onDetach: 

Fragment的創(chuàng)建

先寫個簡單的fragment吧咧党,fragment的布局如下

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">
    <!--是的沒錯,又是hello world-->
    <TextView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center"
        android:text="hello world" />

</LinearLayout>

Fragment代碼如下:

//你可以這樣寫陨亡,寫法1
public class MyFragment extends Fragment {

    private static final String TAG = "MyFragment";

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
                             @Nullable Bundle savedInstanceState) {
        Log.d(TAG, "onCreateView: ");
        return inflater.inflate(R.layout.fragment,container,false);
    }
}

--------------------------------------------------------------

//當然你也可以這樣寫傍衡,寫法2
public class MyFragment extends Fragment {

    private static final String TAG = "MyFragment";


    public static MyFragment newInstance(String value) {
        Bundle args = new Bundle();
        args.putString("key", value);
        MyFragment fragment = new MyFragment();
        fragment.setArguments(args);
        return fragment;
    }

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container
              , @Nullable Bundle savedInstanceState) {
        Log.d(TAG, "onCreateView: ");
        return inflater.inflate(R.layout.fragment_blank, container, false);
    }


    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        Log.d(TAG, "onViewCreated: ");
        super.onViewCreated(view, savedInstanceState);
        Bundle bundle = getArguments();
        if (getArguments() != null) {
            String value = bundle.getString("key", "");
        }
    }
}

兩種寫法實質(zhì)上沒什么區(qū)別,就是傳參的方式不一樣
寫法一你可以使用以下方式傳參

MyFragment mFragment = new MyFragment ();
Bundle bundle = new Bundle();
bundle.putString("key", "value");
mFragment.setArguments(bundle);

寫法二則可以用 MyFragment .newInstance("value")傳參

  • 兩種寫法都可以用方法二里面onViewCreated()中的方法取值
  • 官方更推薦我們使用寫法二负蠕,我個人的理解是寫法二Activity對Fragment的傳參更好管理了蛙埂,統(tǒng)一了參數(shù)形式,因為項目更多時候不止一個在寫

然后來看看onCreateView的里面的三個參數(shù)

inflater:你可以看做是用來加載布局的一個類遮糖,具體的還是挺繁瑣的绣的,后面某一章講吧
container:用來指定該視圖(Fragment)需要嵌在哪個view下(這里是綁的activity)
savedInstanceState:因為內(nèi)存不足或者按下home鍵(非用戶手動按返回鍵銷毀頁面)等系統(tǒng)主動銷毀頁面時,存儲的一些數(shù)據(jù)欲账,具體的后面某一章會講XD

再看看inflate里面的三個參數(shù)屡江,具體源碼就不看了

public View inflate(@LayoutRes int resource, @Nullable ViewGroup root, boolean attachToRoot) {
         ······
}

resource:布局文件的id
root:這個倒是跟上面onCreateView里面的container差不多,就不重復了
attachToRoot:是否將載入的視圖綁定到根視圖中

現(xiàn)在的只是說了個大概赛不,關(guān)于更加詳細的內(nèi)容惩嘉,譬如inflater,attachToRoot踢故,savedInstanceState這些都有深入的價值在里面文黎,但是這篇是fragment,還是給主角一點面子吧XD


fragment的動態(tài)添加&靜態(tài)添加

靜態(tài)與動態(tài)添加殿较,無論是哪種方式耸峭,都是需要配個fragment滴,只是引入的方式不一樣淋纲,F(xiàn)ragment的創(chuàng)建上面有寫抓艳,這里就不重復了

靜態(tài)添加

activity中的布局 activity_main

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

    <fragment
        android:id="@+id/fragment"
        android:name="com.example.administrator.MyFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
</LinearLayout>

name:就是fragment所在的路徑,用來綁定fragment的
注意:id是必須要的,順帶一提ConstraintLayout使用不了<fragment>標簽

動態(tài)添加

activity中布局 activity_main

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#fff"
    tools:context=".MainActivity">

    <FrameLayout
        android:id="@+id/framelayout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</android.support.constraint.ConstraintLayout>

activity中代碼 activity_main

public class MainActivity extends AppCompatActivity {

    private static final String TAG = "MainActivity";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        Log.d(TAG, "onCreate: ");
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //寫法一
        MyFragment fragment = new MyFragment();
        FragmentManager fragmentManager = getSupportFragmentManager();
        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
        fragmentTransaction.add(R.id.framelayout,fragment);
        fragmentTransaction.commit();

        //當然你也可以寫成一步玷或,例如這個寫法二:
        getSupportFragmentManager()
                .beginTransaction()
                .add(R.id.framelayout,new Fragment())
                .commit();
    }
}

這里只寫了add方法儡首,其實FragmentTransaction還提供了remove(),replace()偏友,hide()蔬胯,show()等方法,這里就先只說上面提到的位他。

remove():移除指定的fragment悄蕾,并銷毀(如果沒有回退棧的話)
add():添加指定fragment
replace():移除當前fragment敌买,并添加指定fragment,等同于remove()+add()
hide():隱藏指定的fragment
show():顯示指定的fragment

    @NonNull
    public abstract FragmentTransaction add(@NonNull Fragment var1, @Nullable String var2);
    //var1:Fragment實例
    //var2:tag標簽,可以根據(jù)這個標簽獲取到該Fragment實例
    //該方法一般可用于創(chuàng)建無UI的Fragment蝉绷,用來存儲數(shù)據(jù)之類的操作

    @NonNull
    public abstract FragmentTransaction add(@IdRes int var1, @NonNull Fragment var2);
    //var1:你可以看做是Activity布局中用來放置Fragment的<FrameLayout>標簽

    @NonNull
    public abstract FragmentTransaction add(@IdRes int var1, @NonNull Fragment var2, @Nullable String var3);
   

    @NonNull
    public abstract FragmentTransaction replace(@IdRes int var1, @NonNull Fragment var2);

    @NonNull
    public abstract FragmentTransaction replace(@IdRes int var1, @NonNull Fragment var2, @Nullable String var3);

    @NonNull
    public abstract FragmentTransaction remove(@NonNull Fragment var1);

    @NonNull
    public abstract FragmentTransaction hide(@NonNull Fragment var1);

    @NonNull
    public abstract FragmentTransaction show(@NonNull Fragment var1);

我們可以看到這幾個方所需要的參數(shù)基本都是大同小異
FragmentManager ,F(xiàn)ragmentTransaction 詳見后面幾章


fragment回退棧

什么是回退棧

眾所周知多望,我們從頁面A進入到頁面B都是通過控制activity的入棧與出棧實現(xiàn)的剧蹂,啟動頁面B時候,將activity B壓入棧醒串,此時activity B處于棧頂执桌,即用戶此時看到的頁面是activity B;返回上一個頁面時候芜赌,B移出棧仰挣,此時處于棧頂?shù)臑锳,即用戶此時看到的頁面是A(這里留個位置給activity的啟動模式與任務棧缠沈,后面某一章會講到XD)

什么時候用到回退棧 && 什么時候使用多個activity膘壶,什么時候使用單個activity+多個fragment

歸根到底,都是需求的問題

誠然洲愤,以上我們討論的都是類似于簡書app那樣香椎,底部導航欄+fragment,這種時候確實不大需要到回退棧禽篱,因為直接使用hide()畜伐,show()隱藏顯示需要的fragment就可以了,但是需求總是千變?nèi)f化滴躺率。

譬如一個購買商品的頁面玛界,需要填寫收貨人的基本信息=>選擇商品=>付款成功,這樣3步的流程悼吱,對應3個activity頁面慎框。3個頁面都是上面是1/3的logo布局(logo都是一樣的)加下面的2/3業(yè)務邏輯。這個時候我們可以使用以下兩種方法

  • 3個Activity+xml布局復用
  • 1個Activity+3個fragment+fragment回退棧

我想了半天后添,沒有想到好的應用場景笨枯,必須使用到Fragment回退棧而不使用多個Activity。嗯,這個問題其實也可以等同于什么時候使用多個activity馅精,什么時候使用單個activity+多個fragment严嗜。關(guān)于這一點我個人的看法是,根據(jù)自己的習慣以及需求等因素來考慮洲敢。

上面這段話有點標題黨的嫌疑XD

回退棧的使用
  • 篇幅的問題漫玄,就不貼布局文件的代碼了
  • 以上討論的都是不包括viewpager的,viewpager+fragment會在后面某一章講
  • 以下代碼只是用來講解的測試代碼

Activity代碼:

public class MainActivity extends AppCompatActivity {

    private static final String TAG = "MainActivity";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        Log.d(TAG, "onCreate: ");
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //首頁直接默認添加了一個fragment
        //如果savedInstanceState為空說明是首次創(chuàng)建压彭,則不需要重新添加fragment
        // 否則說明已經(jīng)被創(chuàng)建過睦优,但是Activity被銷毀重建,例橫豎屏切換
        if (savedInstanceState == null) {
            getSupportFragmentManager()
                    .beginTransaction()
                    .add(R.id.framelayout, new UserInfoFragment())
                    .commit();
        }
    }
}

頁面1 UserInfoFragment代碼:

public class UserInfoFragment extends Fragment {
    private static final String TAG = "UserInfoFragment";

    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        Log.d(TAG, "onCreateView: ");
        return inflater.inflate(R.layout.fragment_user_info, container, false);
    }

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        Log.d(TAG, "onViewCreated: ");
        super.onViewCreated(view, savedInstanceState);
        TextView tv122 = view.findViewById(R.id.tv_122);
        //lambda表達式
        tv122.setOnClickListener(v -> getActivity().getSupportFragmentManager()
                .beginTransaction()
                .replace(R.id.framelayout, new ShopQueryFragment())
                .addToBackStack("1to2")
                .commit());
    }
}

頁面2 ShopQueryFragment的代碼:

public class ShopQueryFragment extends Fragment {


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

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        TextView tv221 = view.findViewById(R.id.tv_221);
        TextView tv223 = view.findViewById(R.id.tv_223);
        tv221.setOnClickListener(v -> getActivity().getSupportFragmentManager().popBackStack());

        tv223.setOnClickListener(v -> getActivity().getSupportFragmentManager()
                .beginTransaction()
                .replace(R.id.framelayout, new Pay4ShopFragment())
                .addToBackStack("2to3")
                .commit());
    }
}

頁面3 Pay4ShopFragment的代碼:

public class Pay4ShopFragment extends Fragment {

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

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        TextView tv321 = view.findViewById(R.id.tv_321);
        TextView tv320 = view.findViewById(R.id.tv_320);

        tv321.setOnClickListener(v -> getActivity().getSupportFragmentManager()
                .popBackStack("2to3", FragmentManager.POP_BACK_STACK_INCLUSIVE));

        tv320.setOnClickListener(v -> getActivity().finish());

    }

}
demo.gif

畫質(zhì)有點渣壮不,大家將就著看下吧汗盘,大致還是說下上面代碼的功能

Fragment 1 ? Fragment 2 兩個Fragment可以相互跳轉(zhuǎn)
Fragment 2 => Fragment 3
Fragment 3 => Fragment 1

跳轉(zhuǎn)就不說了replace,回退都是使用的回退棧询一,主要涉及到addToBackStackpopBackStack這兩個方法

addToBackStack

public FragmentTransaction addToBackStack(@Nullable String name) {
       ······
}

//官網(wǎng)是這么介紹的
Add this transaction to the back stack. This means that the transaction will be remembered after
it is committed, and will reverse its operation when later popped off the stack.

 name :String: An optional name for this back stack state, or null. This value may be null.

大致意思是:將該事務添加到返回棧中(入棧)隐孽,將在commit操作后生效,出棧后會回退到該操作之前家凯。
參數(shù)name:回退棧狀態(tài)的名稱,或者為null 如失。這個值可能為null

也就是說Fragment的回退棧不像Activity那樣绊诲,入棧的是Activity,而是transaction操作

popBackStack

再來看看官網(wǎng)給的popBackStack()方法

public abstract void popBackStack ()

Pop the top state off the back stack. This function is asynchronous -- it enqueues 
the request to pop, but the action will not be performed until the application returns to its event loop.

大致意思是:返回棧中移除棧頂元素褪贵。該方法是異步的--它將以隊列的形式請求出棧掂之,直到循環(huán)到該操作才會被執(zhí)行。
有點拗口脆丁,意思就是將最近那一次transaction干的事情回退回去世舰,即移除棧頂?shù)脑亍5沁@個方法又是異步的槽卫,類似于handler跟压,looper那樣存于消息隊列中,需要等到looper拿完了前面的才能輪到你(handler歼培,looper會在后面某一章講)

下面看看帶參數(shù)的那幾個

public abstract void popBackStack(@Nullable String var1, int var2);
Pop the last fragment transition from the manager's fragment back stack. If there is nothing to pop
, false is returned. This function is asynchronous -- it enqueues the request to pop, 
but the action will not be performed until the application returns to its event loop.
//參數(shù)
var1:String: If non-null, this is the name of a previous back state to look for; if found, 
all states up to that state will be popped. The POP_BACK_STACK_INCLUSIVE flag can be used t
o control whether the named state itself is popped. If null, only the top state is popped. 
var2:int: Either 0 or POP_BACK_STACK_INCLUSIVE 
//結(jié)合參數(shù)+自身實踐來看震蒋,大致意思是,如果第2個參數(shù)var2為POP_BACK_STACK_INCLUSIVE 躲庄,則移除該var1上方(包括var1)的所有棧元素查剖。

----------------------------------------------------------------------------------------------------------------

public abstract void popBackStack(int var1, int var2);
Pop all back stack states up to the one with the given identifier. This function is asynchronous 
-- it enqueues the request to pop, but the action will not be performed until the application returns to its event loop.
//彈出指定id上所有的棧元素
//int var1 :指的是transaction.commit()返回的id值
//int var2 :默認值為0或FragmentManager.POP_BACK_STACK_INCLUSIVE

----------------------------------------------------------------------------------------------------------------

public abstract boolean popBackStackImmediate()

public abstract boolean popBackStackImmediate(@Nullable String var1, int var2);

public abstract boolean popBackStackImmediate(int var1, int var2);
//這三個方法倒是跟上面的差不多,只不過好像是同步的

總結(jié)下上面的方法

  • 當var2為0時噪窘,給我更多的感覺是笋庄,出棧=回退到該transition操作后
  • 當var2為1時,給我更多的感覺是,出棧=回退到該transition操作前
  • popBackStack(String var1,int var2)直砂,當var1為null菌仁,var2為0時,移除棧頂元素哆键;
    var1為null掘托,var2為1時,清空回退棧所有元素
  • popBackStackImmediate()系列的方法沒有使用過籍嘹,大家可以自己試試

以上總結(jié)自闪盔,3個Fragment,大家可以試試更多的Fragment看看效果如何


Fragment通訊

  • Fragment與Fragment之間通訊
  • Fragment與Activity之間通訊
  • Activity與Fragment之間通訊

先來說幾種通用的方式吧

  • Broadcast (廣播)
  • EventBus辱士、RxBus等
  • (這兩種方式打算另外開一章單獨來講泪掀,這里就不細談了)
Fragment與Activity通訊
  1. 直接調(diào)用 ((MainActivity)getActivity).callback(value)
    在MainActivity中定義一個callback的函數(shù),F(xiàn)ragment中通過((MainActivity)getActivity)轉(zhuǎn)成MainActivity類型颂碘,直接調(diào)用callback方法就可以了异赫,不過這樣的寫法也就相當于這個Fragment與這個Activity綁死了,很難復用了头岔。
  2. 定義接口(也是最常用的一種方法)塔拳,寫法也挺簡單的大家看看就好
public class MyFragment extends Fragment {

    private static final String TAG = "MyFragment";

    private MyFragmentCallBack myFragmentCallBack;

    public interface MyFragmentCallBack {
        void callBack();
    }

    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        if (context instanceof MyFragmentCallBack) {
            myFragmentCallBack = (MyFragmentCallBack) context;
            //在需要的時候調(diào)用  myFragmentCallBack.callBack(),Activity就會執(zhí)行對應的代碼了
            myFragmentCallBack.callBack();
        }else {
            throw new RuntimeException(context.toString()
                    + " must implement MyFragmentCallBack");
        }
    }
}

Activity中:

public class MainActivity extends AppCompatActivity implements MyFragment.MyFragmentCallBack{

    private static final String TAG = "MainActivity";

    @Override
    public void callBack() {
        Log.d(TAG, "callBack: 開始執(zhí)行");
    }
Activity與Fragment通訊
  1. 可以在Activity中保存Fragment實例峡竣,直接調(diào)用Fragment的方法
  2. 使用getSupportFragmentManager() .findFragmentByTaggetSupportFragmentManager().findFragmentById可以獲取到Fragment實例

findFragmentById:只適用于靜態(tài)加載Fragment
關(guān)于findFragmentByTag獲取到Fragment為null的可能性:

  1. transaction commit以后不可立刻使用findFragmentByTag靠抑,此時transaction操作不一定立即被執(zhí)行,find出來的Fragment有可能為null
  2. v4包與app包需要導對
 public class MainActivity extends AppCompatActivity  {

    private static final String TAG = "MainActivity";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        Log.d(TAG, "onCreate: ");
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        if (savedInstanceState == null) {
            getSupportFragmentManager()
                    .beginTransaction()
                    .add(R.id.framelayout, UserInfoFragment.newInstance("value"), "UserInfoFragment")
                    .commit();
            //這行代碼會報NullPointerException适掰,輸出的Fragment為null
            Log.d(TAG, "onCreate: " + getSupportFragmentManager()
                    .findFragmentByTag("UserInfoFragment")
                    .getClass()
                    .getName());
        }

    }

Fragment之間通訊

這個其實就是上面兩種通訊方式結(jié)合一下颂碧,F(xiàn)ragment調(diào)Activity,然后Activity再調(diào)Fragment就可以了

總結(jié)

  • 由于Fragment是3.0以后導入的
    3.0之前想使用的需要用android.support.v4.app.Fragment這個包类浪,對應getSupportFragmentManager
    3.0之后也可使用android.app.Fragment载城,對應getFragmentManager(本文就沒使用這個包了)
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市费就,隨后出現(xiàn)的幾起案子诉瓦,更是在濱河造成了極大的恐慌,老刑警劉巖力细,帶你破解...
    沈念sama閱讀 219,270評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件垦搬,死亡現(xiàn)場離奇詭異,居然都是意外死亡艳汽,警方通過查閱死者的電腦和手機猴贰,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,489評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來河狐,“玉大人米绕,你說我怎么就攤上這事瑟捣。” “怎么了栅干?”我有些...
    開封第一講書人閱讀 165,630評論 0 356
  • 文/不壞的土叔 我叫張陵迈套,是天一觀的道長。 經(jīng)常有香客問我碱鳞,道長桑李,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,906評論 1 295
  • 正文 為了忘掉前任窿给,我火速辦了婚禮贵白,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘崩泡。我一直安慰自己禁荒,他們只是感情好,可當我...
    茶點故事閱讀 67,928評論 6 392
  • 文/花漫 我一把揭開白布角撞。 她就那樣靜靜地躺著呛伴,像睡著了一般。 火紅的嫁衣襯著肌膚如雪谒所。 梳的紋絲不亂的頭發(fā)上热康,一...
    開封第一講書人閱讀 51,718評論 1 305
  • 那天,我揣著相機與錄音劣领,去河邊找鬼姐军。 笑死,一個胖子當著我的面吹牛剖踊,可吹牛的內(nèi)容都是我干的庶弃。 我是一名探鬼主播衫贬,決...
    沈念sama閱讀 40,442評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼德澈,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了固惯?” 一聲冷哼從身側(cè)響起梆造,我...
    開封第一講書人閱讀 39,345評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎葬毫,沒想到半個月后镇辉,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,802評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡贴捡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,984評論 3 337
  • 正文 我和宋清朗相戀三年忽肛,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片烂斋。...
    茶點故事閱讀 40,117評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡屹逛,死狀恐怖础废,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情罕模,我是刑警寧澤评腺,帶...
    沈念sama閱讀 35,810評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站淑掌,受9級特大地震影響蒿讥,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜抛腕,卻給世界環(huán)境...
    茶點故事閱讀 41,462評論 3 331
  • 文/蒙蒙 一芋绸、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧兽埃,春花似錦侥钳、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,011評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至售貌,卻和暖如春给猾,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背颂跨。 一陣腳步聲響...
    開封第一講書人閱讀 33,139評論 1 272
  • 我被黑心中介騙來泰國打工敢伸, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人恒削。 一個月前我還...
    沈念sama閱讀 48,377評論 3 373
  • 正文 我出身青樓池颈,卻偏偏與公主長得像,于是被迫代替她去往敵國和親钓丰。 傳聞我的和親對象是個殘疾皇子躯砰,可洞房花燭夜當晚...
    茶點故事閱讀 45,060評論 2 355

推薦閱讀更多精彩內(nèi)容