fragent的使用總結(jié)

前言

fragment自動3.0推出以后再榄,在碎片化處理方面一直很受歡迎蝙叛,平時在項目中也在頻繁使用,自從看了CSDN上郭大神和鴻洋大神對fragment的詳細總結(jié)后绞惦,自己學(xué)習做個筆記逼纸。
  郭大神:http://blog.csdn.net/guolin_blog/article/details/8881711
 鴻洋大神:http://blog.csdn.net/lmj623565791/article/details/42628537

fragment的常用方法

(1) 靜態(tài)使用

在布局文件xml中使用

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  android:layout_width="match_parent"  
  android:layout_height="match_parent"  
  android:baselineAligned="false" >  

  <fragment  
      android:id="@+id/fragmentOne"  
      android:name="com.ydscience.FragmentOne"  
      android:layout_width="0dp"  
      android:layout_height="match_parent"  
      android:layout_weight="1" />  
  <fragment  
      android:id="@+id/fragmentTwo"  
      android:name="com.ydscience.FragmentTwo"  
      android:layout_width="0dp"  
      android:layout_height="match_parent"  
      android:layout_weight="1" />  

</LinearLayout>  

具體的fragmentOne和fragmentTwo的代碼就不粘貼啦,都是繼承Fragment去實現(xiàn)的济蝉。

(2)動態(tài)使用

動態(tài)使用分為四個步驟
  (a)獲取FragmentManager,通過方法getSupportFragmentManager()獲取杰刽。
  (b)開啟一個事物,通過beginTransaction方法開啟王滤。
  (c)向容器內(nèi)加入Fragment贺嫂,默認第一個是通過add()方法添加,后面再替換時通過replace方法實現(xiàn)雁乡,需要傳入容器的id和Fragment的實例第喳。
  (d)提交事務(wù),調(diào)用commit方法提交踱稍。
xml中的代碼為

<RelativeLayout
    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"
    tools:context="com.ydsciernce.studytest.MainActivity">
    <FrameLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/content_fragment"/>
</RelativeLayout>

Activity中的代碼為

public class MainActivity extends AppCompatActivity implements FragementOne.FOneListener{
    FragmentTwo mFragmentTwo;
    FragementOne mFragmentOne;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        if (savedInstanceState == null){
            Log.i("TAG","saveInstanece數(shù)據(jù)為空");
            FragmentManager manager = getSupportFragmentManager();
            FragmentTransaction transaction = manager.beginTransaction();
            mFragmentOne = new FragementOne();
            transaction.add(R.id.content_fragment,mFragmentOne,"ONE");
            transaction.commit();
        }else {
            Log.i("TAG","saveInstanece數(shù)據(jù)為"+savedInstanceState.toString());
        }
    }
    @Override
    public void onOneClick() {
        if (mFragmentTwo == null){
            mFragmentTwo =  new FragmentTwo();
        }
        FragmentManager manager = getSupportFragmentManager();
        FragmentTransaction transaction = manager.beginTransaction();
        //transaction.hide(mFragmentOne);
        //transaction.add(R.id.content_fragment,mFragmentTwo,"TWO");
        transaction.replace(R.id.content_fragment,mFragmentTwo,"TWO");
        transaction.addToBackStack(null);
        transaction.commit();
    }
}

FragmentOne的代碼為

public class FragementOne extends Fragment implements View.OnClickListener{

    private Button mButton;
    EditText test;
    public interface FOneListener{
        void onOneClick();
    }
    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {
        Log.i("TAG"," on createview");
        View view = inflater.inflate(R.layout.content_one_fragment,null);
        mButton = (Button) view.findViewById(R.id.buttonOne);
        mButton.setOnClickListener(this);
        test = (EditText) view.findViewById(R.id.editText);
        Log.i("TAG","edit datda"+test.getText().toString());
        return view;
    }
     @Override
    public void onClick(View v) {
        if(getActivity() instanceof FOneListener){
            ((FOneListener)getActivity()).onOneClick();
        }
    }
}

注意事項:

a.在設(shè)置默認的fragment時曲饱,不能調(diào)用addToBackStack(null)方法,如果添加了在退出應(yīng)用時會在Activity頁面出現(xiàn)一個空白頁面珠月。
  b.在代碼中有兩個Fragment渔工,分別為FrangmentOne和FragmentTwo,FragmentOne為默認的,從FragmentOne中的Button 去啟動FragmentTwo,在鴻洋大神的分析中當我們從FragmentOne啟動到FragmentTwo時使用的是replace方法桥温,replace方法的實現(xiàn)過程是remove方法和add方法的合體,當我們在調(diào)用該方法時梁丘,如果不添加事務(wù)到回退棧侵浸,前一個Fragment實例會被銷毀,調(diào)用了addToBackStack(null);將當前的事務(wù)添加到了回退棧氛谜,所以FragmentOne實例不會被銷毀掏觉,但是視圖層次依然會被銷毀,即會調(diào)用onDestoryView和onCreateView值漫,在這種情況下澳腹,再次返回到FragmentOne時等于新建了一個FragmentOne實例對象,在之前Fragment中保存的數(shù)據(jù)將不會存在,而在真實的案例中當我們從FragmentTwo返回到FragmentOne時希望數(shù)據(jù)還在酱塔,因此此時就不能使用replace方法沥邻,使用hide方法將FragmentOne隱藏起來,當FragmengTwo返回時會調(diào)用show方法顯示羊娃,相應(yīng)的數(shù)據(jù)也會被保存唐全。
  c.當fragment遇到屏幕自動旋轉(zhuǎn)時,會導(dǎo)致Activity和Fragment的重建在這種情況下可能會導(dǎo)致兩個FragmentOne的實例對象存在蕊玷,界面上也會存在重疊效果邮利,導(dǎo)致這種現(xiàn)象的原因是當Activity重建時我們的fragment會被保存下來,但是會創(chuàng)建新的FragmentManager垃帅,新的FragmentManager會首先會去獲取保存下來的fragment隊列延届,重建fragment隊列,從而恢復(fù)之前的狀態(tài)贸诚。解決方法是在創(chuàng)建實例和獲取FragmentManager時判斷saveInstanceState狀態(tài)方庭,當我們第一次啟動Activity時,saveInstanceState為空的赦颇,當因異常情況導(dǎo)致Activity重建時二鳄,自動會調(diào)用saveInstanceState會保存一些信息,因此通過判斷saveInstanceState狀態(tài)可以避免這種情況媒怯。
  d.在參考了大神的博客后自己嘗試技能滿足保存數(shù)據(jù)又可以避免在屏幕旋轉(zhuǎn)后避免創(chuàng)建多個Fragment實例對象订讼,實現(xiàn)方法為創(chuàng)建實例前對saveInstanceState狀態(tài)進行判斷,同時在啟動其他的Fragment時不調(diào)用replace方法使用hide方法扇苞,但是出現(xiàn)nullPointerException,目前還沒解決欺殿。

(3)Activity與Fragment以及Fragment與Fragment之間的通信。

a.Activity與Fragment

實現(xiàn)方式有以下幾種
   ”罘蟆①.handler通信
   〔彼铡②.接口回調(diào) 例如上面代碼中在FragmentTwo 實現(xiàn)方式,在
     FragmentTwo中的點擊事件通過接口回調(diào)交給Activity去處理定踱。

聲明接口
public interface FOneListener{
        void onOneClick();
    }
點擊事件傳遞
 public void onClick(View v) {
        if(getActivity() instanceof FOneListener){
            ((FOneListener)getActivity()).onOneClick();
        }
    }
父類繼承去實現(xiàn)
public class MainActivity extends AppCompatActivity implements FragementOne.FOneListener
@Override
public void onOneClick() {
    //處理點擊事件
}

③.使用EventBus去實現(xiàn)棍潘。
   ④.使用廣播BroadcastReceiver去實現(xiàn)崖媚。

b.同時存在同一個Activity中的頁面中的兩個Fragment之間的通信

在查看郭大神的博客后發(fā)現(xiàn)這種情況適用于存在于同一個頁面之間FragmentA 去獲取FragmentB(或者FragmentB 去獲取FragmentA)中某個組件的信息亦歉。主要都是通過getActivity這個方法實現(xiàn)的,getActivity方法可以讓Fragment獲取到關(guān)聯(lián)的Activity畅哑,然后再調(diào)用Activity的findViewById方法肴楷,就可以獲取到和這個Activity關(guān)聯(lián)的其它Fragment的視圖,從而可以獲取這個視圖的數(shù)據(jù)荠呐。

 @Override  
    public void onActivityCreated(Bundle savedInstanceState) {  
        super.onActivityCreated(savedInstanceState);  
        Button button = (Button) getActivity().findViewById(R.id.button);  
        button.setOnClickListener(new OnClickListener() {  
            @Override  
            public void onClick(View v) {  
                TextView textView = (TextView) getActivity().findViewById(R.id.fragment1_text);  
                Toast.makeText(getActivity(), textView.getText(), Toast.LENGTH_LONG).show();  
            }  
        });  
    }  

(4)Fragment的復(fù)用以及與Activity之間的解耦

在我們項目想法中肯定會經(jīng)常遇到ViewPager與Fragment之間的結(jié)合使用赛蔫,使用Viewpager來切換不同的fragment,當?shù)谝淮问褂脮r可能會針對每一個主題都會創(chuàng)建一個Fragment去實現(xiàn)砂客,這種實現(xiàn)方式在網(wǎng)上有很多案例,但是這種實現(xiàn)方式創(chuàng)建了很多的fragment呵恢,代碼有太多的耦合性鞠值,自從Google官網(wǎng)給出了Tablayout這個組件時,它也是結(jié)合fragmen和viewpager去實現(xiàn)的瑰剃。在這個具體實現(xiàn)時很好的復(fù)用了fragment齿诉。具體實現(xiàn)見代碼吧,口頭敘述態(tài)度都是扯淡晌姚,只有代碼才是王道粤剧。

布局代碼(content_history_record.xml)
<LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:layout_centerInParent="true">
    <android.support.design.widget.TabLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:id="@+id/tabLayout"
            app:tabBackground="@color/historyColorAccent"
            app:tabSelectedTextColor="@color/tabSelected"
            app:tabTextColor="@color/tabUnSelected"
            app:tabMode="scrollable"/>
        <android.support.v4.view.ViewPager
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1"
            android:background="@color/label"
            android:id="@+id/viewpager_history"
            />
 </LinearLayout>
MainActivity的代碼
public class HistoryRecordActivity extends AppCompatActivity{
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.content_history_record);
       init();
    }
    private void init(){
        HistoryFragmentPreferenceAdapter adapter = new HistoryFragmentPreferenceAdapter(getSupportFragmentManager(),this);
        ViewPager historyPager = (ViewPager) findViewById(R.id.viewpager_history);
        historyPager.setAdapter(adapter);
        TabLayout historyTabLayout = (TabLayout) findViewById(R.id.tabLayout);
        historyTabLayout.setupWithViewPager(historyPager);
        historyTabLayout.setTabGravity(TabLayout.GRAVITY_FILL);
        historyTabLayout.setTabMode(TabLayout.MODE_FIXED);
    }
}
適配器的代碼(HistoryFragmentPreferenceAdapter.java)
public class HistoryFragmentPreferenceAdapter extends FragmentPagerAdapter {
    private Context mContext;
    private final int coutnt = 5;
    private String [] titles ;
    public HistoryFragmentPreferenceAdapter(FragmentManager fm, Context context) {
        super(fm);
        this.mContext = context;
        titles = context.getResources().getStringArray(R.array.history_title);
    }
    @Override
    public Fragment getItem(int position) {
        return PageFragment.getIntance(position+1);
    }
    @Override
    public int getCount() {
        return coutnt;
    }
    @Override
    public CharSequence getPageTitle(int position) {

        return titles[position];
    }
}
Fragment的代碼(PageFragment.java)
public class PageFragment extends Fragment {
    public static final String TRANSFER_PAGE = "page";
    private int mPage;
    public static Fragment getIntance(int page){
        Bundle bundle = new Bundle();
        bundle.putInt(TRANSFER_PAGE,page);
        PageFragment pageFragment = new PageFragment();
        pageFragment.setArguments(bundle);
        return  pageFragment;
    }
    public void onCreate(Bundle savedInstanceState)  
    {  
        super.onCreate(savedInstanceState); 
        Bundle bundle = getArguments();  
        if (bundle != null)  
            mArgument = bundle.getString(TRANSFER_PAGE);  
    }  

給Fragment添加newInstance方法,將需要的參數(shù)傳入挥唠,設(shè)置到bundle中抵恋,然后setArguments(bundle),最后在onCreate中進行獲取通過getArguments()去獲取一個fragment的實例宝磨,通過這種方式可以實現(xiàn)Fragment的復(fù)用弧关。

最后編輯于
?著作權(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)自己被綠了。 大學(xué)時的朋友給我發(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)容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,180評論 25 707
  • Fragment概述 Fragment是Activity中用戶界面的一個行為或者說是一部分。主要是支持大屏幕上動態(tài)...
    wangling90閱讀 11,542評論 5 75
  • 前言 Fragment想必大家不陌生吧末购,在日常開發(fā)中破喻,對于Fragment的使用也很頻繁,現(xiàn)在主流的APP中盟榴,基本...
    斜杠時光閱讀 2,581評論 4 22
  • 作品簡介: 魏曉天高中開學(xué)沒多久喜歡上了校廣播站的學(xué)姐江欣怡曹质,江欣怡溫柔大方,時常和他發(fā)信息并且一起見面擎场。那時的他...
    溫玉言閱讀 572評論 2 2
  • 如果用一首歌記錄2015迅办,我想會是SkeeterDavis的《the end of the world》宅静,因為這是...
    孟繁錦閱讀 408評論 0 1