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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Fragment初识

發布時間:2025/3/21 编程问答 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Fragment初识 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

概述

官方API


Fragment是什么

Android 在 Android 3.0(API 11 級)中引入了Fragment,主要是為了給大屏幕(如平板電腦)上更加動態和靈活的 UI 設計提供支持。由于平板電腦的屏幕比手機屏幕大得多,因此可用于組合和交換 UI 組件的空間更大。利用片段實現此類設計時,您無需管理對視圖層次結構的復雜更改。 通過將 Activity 布局分成片段,您可以在運行時修改 Activity 的外觀,并在由 Activity 管理的返回棧中保留這些更改。

當然了我們普通手機開發也會加入這個Fragment, 我們可以把它看成一個小型的Activity,又稱Activity片段!

例如:新聞應用可以使用一個片段在左側顯示文章列表,使用另一個片段在右側顯示文章—兩個片段并排顯示在一個 Activity 中,每個片段都具有自己的一套生命周期回調方法,并各自處理自己的用戶輸入事件。 因此,用戶不需要使用一個 Activity 來選擇文章,然后使用另一個 Activity 來閱讀文章,而是可以在同一個 Activity 內選擇文章并進行閱讀,如下圖中的左側平板電腦布局所示。

我們應該將每個片段都設計為可重復使用的模塊化 Activity 組件。也就是說,由于每個片段都會通過各自的生命周期回調來定義其自己的布局和行為,您可以將一個片段加入多個 Activity,因此,您應該采用可復用式設計,避免直接從某個片段直接操縱另一個片段。 這特別重要,因為模塊化片段讓您可以通過更改片段的組合方式來適應不同的屏幕尺寸。 在設計可同時支持平板電腦和手機的應用時,您可以在不同的布局配置中重復使用您的片段,以根據可用的屏幕空間優化用戶體驗。 例如,在手機上,如果不能在同一 Activity 內儲存多個片段,可能必須利用單獨片段來實現單窗格 UI。


下圖是文檔中給出的一個Fragment分別對應手機與平板間不同情況的處理圖:

例如:仍然以新聞應用為例—在平板電腦尺寸的設備上運行時,該應用可以在Activity A 中嵌入兩個片段。不過,在手機尺寸的屏幕上,沒有足以儲存兩個片段的空間,因此Activity A 只包括用于顯示文章列表的片段,當用戶選擇文章時,它會啟動Activity B,其中包括用于閱讀文章的第二個片段。因此,應用可通過重復使用不同組合的片段來同時支持平板電腦和手機,如上圖右側。

如需了解有關通過利用不同片段組合來適應不同屏幕配置這種方法設計應用的詳細信息,請參閱支持平板電腦和手機指南。

Fragment的生命周期圖

  • ①Activity加載Fragment的時候,依次調用下面的方法: onAttach -> onCreate -> onCreateView -> onActivityCreated -> onStart ->onResume
  • ②當我們弄出一個懸浮的對話框風格的Activity,或者其他,就是讓Fragment所在的Activity可見,但不獲得焦點 onPause
  • ③當對話框關閉,Activity又獲得了焦點: onResume
  • ④當我們替換Fragment,并調用addToBackStack()將他添加到Back棧中 onPause -> onStop -> onDestoryView !!注意,此時的Fragment還沒有被銷毀哦!!!
  • ⑤當我們按下鍵盤的回退鍵,Fragment會再次顯示出來: onCreateView -> onActivityCreated -> onStart -> onResume
  • ⑥如果我們替換后,在事務commit之前沒有調用addToBackStack()方法將 Fragment添加到back棧中的話;又或者退出了Activity的話,那么Fragment將會被完全結束, Fragment會進入銷毀狀態 onPause -> onStop -> onDestoryView -> onDestory -> onDetach

核心要點

  • 3.0版本后引入,即minSdk要大于11,使用兼容包v4,可以向下兼容
  • Fragment需要嵌套在Activity中使用,當然也可以嵌套到另外一個Fragment中,但這個被嵌套 的Fragment也是需要嵌套在Activity中的,間接地說,Fragment還是需要嵌套在Activity中!! 受寄主Activity的生命周期影響,當然他也有自己的生命周期!另外不建議在Fragment里面 嵌套Fragment因為嵌套在里面的Fragment生命周期不可控!!!
  • 官方文檔說創建Fragment時至少需要實現三個方法:onCreate( ),onCreateView( ),OnPause( ); 不過貌似只寫一個onCreateView也是可以的…
  • Fragment的生命周期和Activity有點類似:
    三種狀態:
    Resumed:在允許中的Fragment可見
    Paused:所在Activity可見,但是得不到焦點
    Stoped: ①調用addToBackStack(),Fragment被添加到Bcak棧 ②該Activity轉向后臺,或者該Fragment被替換/刪除
    ps:停止狀態的fragment仍然活著(所有狀態和成員信息被系統保持著),然而,它對用戶 不再可見,并且如果activity被干掉,他也會被干掉.

Fragment的幾個子類

很多時候我們都是直接重寫Fragment,inflate加載布局完成相應業務了,子類用的不多,等需要的 時候在深入研究!

  • 對話框:DialogFragment
  • 列表:ListFragment
  • 選項設置:PreferenceFragment
  • WebView界面:WebViewFragment

是用App包下的Fragment還是v4包下的

問題概述:
再引入Fragment聲明時,

我們到底是使用android.app下的Fragment還是用的android.support.v4.app包下 的Fragment呢?

其實都可以,前面說過Fragment是Android 3.0(API 11)后引入的,那么如果開發的app需要 在3.0以下的版本運行呢?比如還有一點點市場份額的2.3!于是乎,v4包就這樣應運而生了, 而最低可以兼容到1.6版本!至于使用哪個包看你的需求了,現在3.0下手機市場份額其實已經不多了,隨街都是4.0以上的,7.0都出了,你說呢…所以這個時候,你可以直接使用app包下的Fragment 然后調用相關的方法,通常都是不會有什么問題的;如果你Fragment用了app包的, FragmentManager和FragmentTransaction都需要是app包的!要么用全部用app,要么全部用v4, 不然可是會報錯的哦!當然如果你要自己的app對于低版本的手機也兼容的話,那么就可以選擇用v4包

使用v4包下Fragment要注意的地方:

  • ①如果你使用了v4包下的Fragment,那么所在的那個Activity就要繼承FragmentActivity或者其子類如AppCompatActivity
    案例:今天在xml文件中靜態地載入fragment,然后重寫了Fragment,但是在加載Activity的時候就報錯了, 大概的提示就是Fragment錯誤還是找不到什么的,name屬性改了幾次還是錯!最后才發現是用了 v4的包的緣故,只需讓自己的Activity改成FragmentActivity即可!
  • 如果引用的是V4包中的類,getFragmentManager( )不能使用,需要改成getSupportFragmentManager( )

創建一個Fragment

靜態加載Fragment

操作步驟

  • Step 1:定義Fragment的布局
  • Step 2:自定義一個Fragment類,需要繼承Fragment或者他的子類,重寫onCreateView()方法 在該方法中調用:inflater.inflate()方法加載Fragment的布局文件,接著返回加載的view對象
  • Step 3:在需要加載Fragment的Activity對應的布局文件中添加fragment的標簽, 記住,name屬性是全限定類名,就是要包含Fragment的包名,另外 fragment必須用id或tag作為唯一標識
  • Step 4: Activity在onCreate( )方法中調用setContentView()加載布局文件即可!

Code

Fragment的UI布局fragment_static_load.xml

<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:orientation="vertical" android:layout_width="match_parent"android:layout_height="match_parent"><TextView android:id="@+id/textview"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="我是靜態加載的Fragment"/></LinearLayout>

創建類FragmentOne.java,繼承Fragment或者其之類

package com.turing.base.activity.fragment;import android.os.Bundle; import android.support.annotation.Nullable; import android.support.v4.app.Fragment; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup;import com.turing.base.R;public class FragmentOne extends Fragment {@Nullable@Overridepublic View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {View view = inflater.inflate(R.layout.fragment_static_load,container,false);return view;} }

在Activity的布局文件activity_fragment_static_load.xml中聲明fragment標簽

<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"><fragment android:id="@+id/fragmentStaticLoad"android:name="com.turing.base.activity.fragment.FragmentOne"android:layout_width="wrap_content"android:layout_height="wrap_content" /></RelativeLayout>

加載布局文件,操作UI

package com.turing.base.activity.fragment;import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.widget.TextView;import com.turing.base.R;/*** 靜態加載Fragment的Activity*/ public class FragmentStaticLoadAct extends AppCompatActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_fragment_static_load);//靜態加載時可以直接獲取到 Fragment中的UI控件TextView tv = (TextView) findViewById(R.id.textview);tv.setText("我在Act中獲取到了Fragment中的UI控件");} }

效果圖

操作步驟


動態加載Fragment

實現動態加載,我們需要先了解Fragment事務。

Fragment事務:對Fragment進行添加、移除、替換或執行其它動作,提交給Activity的每一個變化。

Fragment是UI模塊,自然在一個Activity中可以不只有一個模塊,所以Android提供了FragmentManage類來管理FragmentFragmentTransaction類來管理事務

我們對Fragment的動態加載就是先將添加、移除等操作提交到事務,然后通過FragmentManage完成的。

通過FragmentManager.beginTransaction()我們可以開始一個事務。在事務中,我們可以對Fragment進行的操作以及對應的方法如下:

  • 添加:add()
  • 移除:remove()
  • 替換:replace()
  • 提交事務:commit()
  • 上面幾個是比較常用的,還有attach()、detach()、hide()、addToBackStack()等方法。

如果允許用戶通過back鍵退回到前一個Fragment狀態,調用commit()之前可以加入addToBackStack()方法

我們需要注意的是,Fragment以ID或Tag作為唯一標識,所以remove和replace的參數是Fragment,這個Fragment目標Fragment一致

注意:Activity動態的添加Fragment必需有一個容器View來容納Fragment的layout布局

操作步驟

Code

activity_fragment_dynamic_load

<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"><!--Activity動態的添加Fragment必需有一個容器View來容納Fragment的layout布局--><LinearLayout android:id="@+id/fragmentDynamicLoad"android:layout_width="wrap_content"android:layout_height="wrap_content"android:orientation="horizontal"/> </RelativeLayout>

FragmentDynamicLoadAct.java

package com.turing.base.activity.fragment.dynamicload;import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.util.DisplayMetrics; import android.widget.TextView;import com.turing.base.R;public class FragmentDynamicLoadAct extends AppCompatActivity {// 屏幕寬高int width, height;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_fragment_dynamic_load);// 獲取屏幕的寬高DisplayMetrics displayMetrics = new DisplayMetrics();getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);width = displayMetrics.widthPixels;height = displayMetrics.heightPixels;// 根據寬高,加載不同的Fragmentif (width < height) {FragementFirst fragementFirst = new FragementFirst();// 使用V4的包就使用getSupportFragmentManager ,使用app下的,就使用getFragmentManagergetSupportFragmentManager().beginTransaction().add(R.id.fragmentDynamicLoad, fragementFirst).commit();} else {FragmentSecond fragmentSecond = new FragmentSecond();getSupportFragmentManager().beginTransaction().add(R.id.fragmentDynamicLoad, fragmentSecond).commit();}//當fragment被提交之后,【fragmentTransaction.commit()提交fragment是異步處理的,所以獲取fragment時要注意】// 可通過以下兩種方法獲取fragment:findFragmentByTag()、findFragmentById()}/*** 重寫onStart()方法,* 因為從fragment的生命周期可以知道當Activity的onCreate(Bundle savedInstanceState)中* 還無法獲取fragment的布局的組件*/@Overrideprotected void onStart() {super.onStart();/*** 可以直接通過findViewById()獲取fragment的組件,* 因為fragment本身就是Activity的一部分(“碎片”/“片段”);* 因為Activity和fragment要從fragment的onActivityCreate()生命周期方法之后* 才能相互獲取對方布局中的組件,* 所以在fragment中獲取Activity的組件最早只能在onActivityCreate()中獲取,* 而Activity最早只能在onStart()中獲取;*/// 獲取Fragment中的UI組件if (width < height) {TextView textView = (TextView) findViewById(R.id.fragmentFirst);textView.setText("~~~~~First");} else {TextView textView = (TextView) findViewById(R.id.fragmentSecond);textView.setText("~~~~~Second");}} }

FragementFirst.java

package com.turing.base.activity.fragment.dynamicload;import android.os.Bundle; import android.support.v4.app.Fragment; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup;import com.turing.base.R;/*** A simple {@link Fragment} subclass.*/ public class FragementFirst extends Fragment {public FragementFirst() {// Required empty public constructor}@Overridepublic View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {// Inflate the layout for this fragmentreturn inflater.inflate(R.layout.fragment_fragement_first, container, false);}}

fragment_fragement_first.xml

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"tools:context="com.turing.base.activity.fragment.dynamicload.FragementFirst"><!-- TODO: Update blank fragment layout --><TextView android:id="@+id/fragmentFirst"android:layout_width="match_parent"android:layout_height="match_parent"android:text="fragment first" /></FrameLayout>

FragmentSecond.java

package com.turing.base.activity.fragment.dynamicload;import android.os.Bundle; import android.support.v4.app.Fragment; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup;import com.turing.base.R;/*** A simple {@link Fragment} subclass.*/ public class FragmentSecond extends Fragment {public FragmentSecond() {// Required empty public constructor}@Overridepublic View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {// Inflate the layout for this fragmentreturn inflater.inflate(R.layout.fragment_fragment_second, container, false);}}

fragment_fragment_second.xml

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"tools:context="com.turing.base.activity.fragment.dynamicload.FragmentSecond"><!-- TODO: Update blank fragment layout --><TextView android:id="@+id/fragmentSecond"android:layout_width="match_parent"android:layout_height="match_parent"android:text="fragment second" /></FrameLayout>

效果圖


Fragment管理與Fragment事務


Fragment與Activity的交互

組件獲取

Activity中獲取Fragment,以及Fragment中的組件

獲取Fragment

當fragment被提交之后,【fragmentTransaction.commit()提交fragment是異步處理的,所以獲取fragment時要注意】
可通過以下兩種方法獲取fragment:findFragmentByTag()、findFragmentById()

Fragment中的組件

/*** 重寫onStart()方法,* 因為從fragment的生命周期可以知道當Activity的onCreate(Bundle savedInstanceState)中* 還無法獲取fragment的布局的組件*/@Overrideprotected void onStart() {super.onStart();/*** 可以直接通過findViewById()獲取fragment的組件,* 因為fragment本身就是Activity的一部分(“碎片”/“片段”);* 因為Activity和fragment要從fragment的onActivityCreate()生命周期方法之后* 才能相互獲取對方布局中的組件,* 所以在fragment中獲取Activity的組件最早只能在onActivityCreate()中獲取,* 而Activity最早只能在onStart()中獲取;*/// 獲取Fragment中的UI組件if (width < height) {TextView textView = (TextView) findViewById(R.id.fragmentFirst);textView.setText("~~~~~First");} else {TextView textView = (TextView) findViewById(R.id.fragmentSecond);textView.setText("~~~~~Second");}}

Fragment中獲取Activity中的組件

public class FragementFirst extends Fragment {public FragementFirst() {// Required empty public constructor}@Overridepublic View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {// Inflate the layout for this fragmentreturn inflater.inflate(R.layout.fragment_fragement_first, container, false);}@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);// 在Fragment中獲取Activity的組件TextView textView = (TextView) getActivity().findViewById(R.id.id_tv_actUI);textView.setText("FFFF");} }

數據傳遞

①Activit傳遞數據給Fragment:

在Activity中創建Bundle數據包,調用Fragment實例的setArguments(bundle) 從而將Bundle數據包傳給Fragment,然后Fragment中調用getArguments獲得 Bundle對象,然后進行解析就可以了

fragementFirst = new FragementFirst();// 使用V4的包就使用getSupportFragmentManager ,如果使用app下的Fragment,就使用getFragmentManagergetSupportFragmentManager().beginTransaction().add(R.id.fragmentDynamicLoad, fragementFirst).commit();// Activity傳遞數據給FragmentBundle bundle = new Bundle();bundle.putString("key", "這是Activity傳遞給Fragment的數據");// setArgumentsfragementFirst.setArguments(bundle);

在Fragment中接收解析數據

// 接收Activity傳遞過來的數據Bundle bundle = getArguments();Toast.makeText(getActivity(), bundle.getString("key"), Toast.LENGTH_SHORT).show();


②Fragment傳遞數據給Activity:

在Fragment中定義一個內部回調接口,再讓包含該Fragment的Activity實現該回調接口, Fragment就可以通過回調接口傳數據了。

Step 1:定義一個回調接口:(Fragment中)

FragementFirst.java

/*** 定義一個回調接口:(Fragment中)*/public interface FragmentCallBack {//定義一個接口方法void getResult(String result);}

Step 2:接口回調(Fragment中)

FragementFirst.java
getData改方法持有接口對象

/*** 接口回調(Fragment中)*/public void getData(FragmentCallBack callBack){// 模擬獲取的數據String msg = "小工匠";// 接口回調callBack.getResult(msg);}

Step 3:使用接口回調方法讀數據(Activity中)

//使用接口回調方法讀數據(Activity中)fragementFirst.getData(new FragementFirst.FragmentCallBack() {@Overridepublic void getResult(String result) {Toast.makeText(FragmentDynamicLoadAct.this, result, Toast.LENGTH_SHORT).show();}});

總結

->在Fragment定義一個接口,接口中定義抽象方法,你要傳什么類型的數據參數就設置為什么類型;
->接著還有寫一個調用接口中的抽象方法,把要傳遞的數據傳過去
->再接著就是Activity了,調用Fragment提供的那個方法,然后重寫抽象方法的時候進行數據 的讀取就可以了~

運行圖


③Fragment與Fragment之間的數據互傳

找到要接受數據的fragment對象,直接調用setArguments傳數據進去就可以了
通常的話是replace時,即fragment跳轉的時候傳數據的,那么只需要在初始化要跳轉的Fragment
后調用他的setArguments方法傳入數據即可!
如果是兩個Fragment需要即時傳數據,而非跳轉的話,就需要先在Activity獲得f1傳過來的數據,
再傳到f2了,就是以Activity為媒介~

FragmentManager fManager = getSupportFragmentManager( ); FragmentTransaction fTransaction = fManager.beginTransaction(); Fragmentthree t1 = new Fragmentthree(); Fragmenttwo t2 = new Fragmenttwo(); Bundle bundle = new Bundle(); bundle.putString("key",id); t2.setArguments(bundle); fTransaction.add(R.id.fragmentRoot, t2, "~~~"); fTransaction.addToBackStack(t1); fTransaction.commit();

還有一片簡書上的文章 可以學習下~

總結

以上是生活随笔為你收集整理的Fragment初识的全部內容,希望文章能夠幫你解決所遇到的問題。

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

主站蜘蛛池模板: 久久久久国产精 | 视频免费在线观看 | 午夜久久久久久久 | 国产精品羞羞答答在线 | 91网站免费| 蜜臀久久99精品久久一区二区 | 在线观看免费国产 | 东北少妇高潮抽搐 | 亚洲视频在线免费观看 | 高潮网| 在线的av| 91porny九色 | 国产丝袜一区二区三区 | 人人看人人草 | 看免费毛片 | 一区二区三区精 | 台湾佬综合网 | 国产免费一区二区 | 黄色视屏在线免费观看 | 国产伦精品一区二区三区妓女 | 三级a毛片 | 免费观看的av网站 | 国产天堂第一区 | 亚洲一区高清 | 日韩偷拍一区 | 日本一二三不卡 | 在线精品播放 | 麻豆亚洲av熟女国产一区二 | 日本不卡免费 | 亚洲精品中文字幕在线播放 | 九九久久国产视频 | 无码播放一区二区三区 | 成人av片在线观看 | 香蕉视频亚洲一级 | 国产麻豆剧传媒精品国产 | 欧美日韩国产一区二区在线观看 | 二区国产 | 茄子av| 亚洲精品大全 | 午夜精品一区二区三区三上悠亚 | 国产青青草在线 | 久久综合亚洲色hezyo国产 | 91精品国产欧美一区二区成人 | 久久综合五月婷婷 | 青青草视频播放 | 制服诱惑一区 | 国产麻豆成人传媒免费观看 | 好男人在线视频www 亚洲福利国产 | 黑人性视频 | 国产精品久久久久久久久免费相片 | 另类二区 | 色屁屁www影院免费观看入口 | 日本视频免费在线播放 | 92精品 | 人妻视频一区二区三区 | 欧美激情视频一区二区三区不卡 | 天堂视频中文在线 | 嫩草av在线 | 操你啦影院 | 国产男女猛烈无遮挡免费视频动漫 | 免费色站| 天天射天天干天天舔 | 欧美videos另类精品 | 成人免费xxxxxx视频 | 精品一区二区在线观看 | 国产免费一区二区三区 | 完美搭档在线观看 | eeuss鲁片一区二区三区在线观看 | 国产草草浮力影院 | 99超碰在线观看 | 极品少妇在线 | 深夜福利网站在线观看 | 婷婷色在线视频 | 怡红院一区二区三区 | 欧美a一级片| 男人操女人的视频 | 欧美精品三级 | 国产精品毛片一区二区在线看舒淇 | 美国一级大黄一片免费中文 | 国产精品一区二区免费看 | 色悠久久综合 | 永久免费视频网站 | 手机电影在线观看 | 懂色av懂色av粉嫩av分享吧 | 免费av一级 | 蜜桃视频在线播放 | 先锋资源在线视频 | 丰满人妻翻云覆雨呻吟视频 | 欧美精品一区二区蜜桃 | av在线你懂的 | 亚洲男同视频 | 精品一区二区久久久久久久网站 | 中文在线а√天堂官网 | 久久99国产精品一区 | 日韩一区二区三区不卡视频 | 777久久| 泰坦尼克号3小时49分的观看方法 | 亚洲精品国产精品乱码视色 | 四虎av在线 |