最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會(huì)員登陸 & 注冊(cè)

Android開發(fā)學(xué)習(xí)教程(26)- Android Fragment(碎片)

2023-01-28 21:30 作者:ChatGPT云炬學(xué)長  | 我要投稿

—— 盡吾志也,而不能至者,所以無悔矣

什么是單窗格或多窗格布局?

面板或窗格代表用戶界面的一部分 。術(shù)語窗格是一個(gè)通用術(shù)語,用于描述根據(jù)實(shí)際可用空間將多個(gè)視圖組合成一個(gè)復(fù)合視圖的概念。

如果沒有足夠的可用空間,則僅顯示一個(gè)面板。這通常稱為單窗格布局。

如果有更多可用空間,可以顯示多個(gè)面板。

什么是Fragment?

Fragment是 Android 中的一個(gè)組件,F(xiàn)ragment依賴于Activity運(yùn)行,但有自己的生命周期,通常有自己的用戶界面。

Android設(shè)備存在各種屏幕尺寸和密度。Fragment簡化了組件在不同布局及其邏輯中的重用。你可以為手機(jī)構(gòu)建單窗格布局,為平板電腦構(gòu)建多窗格布局。你還可以使用Fragment來支持智能手機(jī)上橫向和縱向的不同布局。

因?yàn)榭梢詮腁ctivity中動(dòng)態(tài)添加和刪除Fragment。所以Fragment的使用允許設(shè)計(jì)非常靈活的用戶界面。

典型示例是Activity中的項(xiàng)目列表。在平板電腦上,如果單擊項(xiàng)目,你會(huì)立即在右側(cè)的同一屏幕上看到詳細(xì)信息。而在手機(jī)上,你需要跳轉(zhuǎn)到新的詳細(xì)信息屏幕。這在下圖中進(jìn)行了描述。

Fragment的用法

有兩種方法可以將Fragmtn添加到Activity中:動(dòng)態(tài)添加和靜態(tài)添加。

靜態(tài)添加

要靜態(tài)添加Fragment,只需將Fragment嵌入到活動(dòng)的 xml 布局文件中:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<?xml?version="1.0"?encoding="utf-8"?>
<LinearLayout?xmlns:android="http://schemas.android.com/apk/res/android"
????xmlns:tools="http://schemas.android.com/tools"
????android:layout_width="fill_parent"
????android:layout_height="fill_parent"
????android:baselineAligned="false"
????android:orientation="horizontal">
????<fragment
????????android:id="@+id/listFragment"
????????class="com.example.myapplication1.MyListFragment"
????????android:layout_width="0dp"
????????android:layout_height="match_parent"
????????android:layout_weight="1"
????????android:tag="listFragment"
????????tools:layout="@layout/fragment_rsslist_overview"?/>
????<fragment
????????android:id="@+id/detailFragment"
????????class="com.example.myapplication1.DetailFragment"
????????android:layout_width="0dp"
????????android:layout_height="match_parent"
????????android:layout_weight="2"
????????android:tag="detailFragment"
????????tools:layout="@layout/fragment_rssitem_detail"?/>
</LinearLayout>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import?android.os.Bundle;
import?androidx.appcompat.app.AppCompatActivity;
public?class?MainActivityByXml?extends?AppCompatActivity?implements?MyListFragment.OnItemSelectedListener {
??@Override
??protected?void?onCreate(Bundle savedInstanceState) {
??????super.onCreate(savedInstanceState);
??????setContentView(R.layout.activity_main_byxml);
??}
??@Override
??public?void?onRssItemSelected(String str) {
??????// DetailFragment fragment = (DetailFragment) getSupportFragmentManager().findFragmentById(R.id.detailFragment);
??????DetailFragment fragment = (DetailFragment) getSupportFragmentManager().findFragmentByTag("detailFragment");
??????fragment.setText(str);
??}
}

動(dòng)態(tài)添加

動(dòng)態(tài)添加允許你在Activity中添加、刪除和替換片段。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?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="horizontal">
????<FrameLayout
????????android:id="@+id/listcontainer"
????????android:layout_width="0dp"
????????android:layout_height="match_parent"
????????android:layout_weight="1"?/>
????<FrameLayout
????????android:id="@+id/detailscontainer"
????????android:layout_width="0dp"
????????android:layout_height="match_parent"
????????android:layout_weight="1"?/>
</LinearLayout>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
import?android.os.Bundle;
import?androidx.appcompat.app.AppCompatActivity;
import?androidx.fragment.app.FragmentManager;
import?androidx.fragment.app.FragmentTransaction;
public?class?MainActivityByManager?extends?AppCompatActivity?implements?MyListFragment.OnItemSelectedListener {
????private?FragmentManager fragmentManager;
????@Override
????protected?void?onCreate(Bundle savedInstanceState) {
????????super.onCreate(savedInstanceState);
????????setContentView(R.layout.activity_main_bymanager);
????????instanceFragmentManager();
????}
????private?void?instanceFragmentManager() {
????????// 獲取FragmentManger
????????fragmentManager = getSupportFragmentManager();
????????// 把Fragment add到FrameLayout容器中,并設(shè)置此add進(jìn)來的Fragment的Tag為MyListFragment
????????FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
????????fragmentTransaction.add(R.id.listcontainer,?new?MyListFragment(),?"MyListFragment");
????????fragmentTransaction.add(R.id.detailscontainer,?new?DetailFragment(),?"DetailFragment");
????????fragmentTransaction.commit();
//??????? // replace Fragment
//??????? FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
//??????? fragmentTransaction.replace(R.id.detailscontainer, new DetailFragment());
//??????? fragmentTransaction.commit();
//
//??????? // remove Fragment
//??????? Fragment fragment = fragmentManager.findFragmentById(R.id.detailscontainer);
//??????? FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
//??????? fragmentTransaction.remove(fragment);
//??????? fragmentTransaction.commit();
????}
????@Override
????public?void?onRssItemSelected(String str) {
????????// 使用 findFragmentById 或者 findFragmentByTag都行,建議還是使用 findFragmentByTag,避免邏輯層與視圖層耦合
????????DetailFragment fragment = (DetailFragment) getSupportFragmentManager().findFragmentById(R.id.detailscontainer);
//??????? DetailFragment fragment = (DetailFragment) getSupportFragmentManager().findFragmentByTag("DetailFragment");
????????fragment.setText(str);
????}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
import?android.content.Context;
import?android.os.Bundle;
import?android.view.LayoutInflater;
import?android.view.View;
import?android.view.ViewGroup;
import?android.widget.Button;
import?androidx.fragment.app.Fragment;
public?class?MyListFragment?extends?Fragment?implements?View.OnClickListener {
????private?OnItemSelectedListener listener;
????@Override
????public?View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
????????View view = inflater.inflate(R.layout.fragment_rsslist_overview, container,?false);
????????view.findViewById(R.id.button1).setOnClickListener(this);
????????view.findViewById(R.id.button2).setOnClickListener(this);
????????view.findViewById(R.id.button3).setOnClickListener(this);
????????view.findViewById(R.id.button4).setOnClickListener(this);
????????view.findViewById(R.id.button5).setOnClickListener(this);
????????return?view;
????}
????@Override
????public?void?onClick(View v) {
????????updateDetail(((Button) v).getText().toString());
????}
????public?interface?OnItemSelectedListener {
????????void?onRssItemSelected(String str);
????}
????@Override
????public?void?onAttach(Context context) {
????????super.onAttach(context);
????????if?(context?instanceof?OnItemSelectedListener) {
????????????listener = (OnItemSelectedListener) context;
????????}?else?{
????????????throw?new?ClassCastException(context.toString() +?" must implemenet MyListFragment.OnItemSelectedListener");
????????}
????}
????@Override
????public?void?onDetach() {
????????super.onDetach();
????????listener =?null;
????}
????private?void?updateDetail(String str) {
????????listener.onRssItemSelected(str);
????}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import?android.os.Bundle;
import?android.view.LayoutInflater;
import?android.view.View;
import?android.view.ViewGroup;
import?android.widget.TextView;
import?androidx.fragment.app.Fragment;
public?class?DetailFragment?extends?Fragment {
????@Override
????public?View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
????????View view = inflater.inflate(R.layout.fragment_rssitem_detail, container,?false);
????????return?view;
????}
????public?void?setText(String text) {
????????TextView view = (TextView) getView().findViewById(R.id.detailsText);
????????view.setText(text);
????}
}

查找Fragment實(shí)例

通常我們需要在Activity中查找Fragment實(shí)例用于操作Fragment。有幾種方法可以查找現(xiàn)有的Fragment實(shí)例:

1. 通過ID查找即findFragmentById

2. 通過Tag查找即findFragmentByTag

下面更詳細(xì)地概述了每種方法。

按ID查找即findFragmentById

如果是通過靜態(tài)添加的,這里的ID就表示靜態(tài)xml中fragment標(biāo)簽的id,例如上面示例中的findFragmentById(R.id.detailFragment)。如果是通過動(dòng)態(tài)添加的(大部分時(shí)候都是此方式),ID則表示Fragment被add上去的那個(gè)布局的ID,例如上面示例中的findFragmentById(R.id.detailscontainer)。

按Tag查找即findFragmentById

Tag可以理解為每一個(gè)Fragment的唯一標(biāo)識(shí)符。如果是通過靜態(tài)添加的,這里的Tag就表示靜態(tài)xml中fragment標(biāo)簽的android:tag值,例如上面示例中的findFragmentByTag(“detailFragment”)。如果是通過動(dòng)態(tài)添加的(大部分時(shí)候都是此方式),ID則表示Fragment被add上去時(shí)指定的Tag字符串,例如上面示例中的fragmentTransaction.add(R.id.detailscontainer, new DetailFragment(), “DetailFragment”)、findFragmentByTag(“DetailFragment”)。

Activity Fragment通信

Fragment通常應(yīng)該只與它們的父Activity通信。通過父Activity來管理與其他Fragment的交互。Activity可以看做是每個(gè)Fragment之間交互的控制器。

Fragment和Activity可以通過三種方式進(jìn)行通信:

1. 通過Bundle傳參 – Activity 可以構(gòu)造一個(gè)片段并設(shè)置參數(shù)

2. 通過調(diào)用Fragment成員方法 – Activity 可以調(diào)用Fragment實(shí)例上的方法

3. 通過接口回調(diào) – Fragment可以通過接口在Activity上觸發(fā)偵聽器事件

1. 通過Bundle傳參

在某些情況下,F(xiàn)ragment可能希望接受某些參數(shù)。一種常見的模式是創(chuàng)建一個(gè)靜態(tài)newInstance方法來創(chuàng)建帶有參數(shù)的Fragment:

1
2
3
4
5
6
7
8
9
10
11
12
13
public?class?DemoFragment?extends?Fragment {
????public?static?DemoFragment newInstance(int?someInt, String someTitle) {
????????DemoFragment fragmentDemo =?new?DemoFragment();
????????Bundle args =?new?Bundle();
????????args.putInt("someInt", someInt);
????????args.putString("someTitle", someTitle);
????????fragmentDemo.setArguments(args);
????????return?fragmentDemo;
????}
????
}

這會(huì)將某些參數(shù)設(shè)置到 Fragment 中,之后可以在 onCreate 中使用以下方法訪問參數(shù):

1
2
3
4
5
6
7
8
9
10
11
public?class?DemoFragment?extends?Fragment {
???@Override
???public?void?onCreate(Bundle savedInstanceState) {
???????super.onCreate(savedInstanceState);
???????int?SomeInt = getArguments().getInt("someInt",?0);??
???????String someTitle = getArguments().getString("someTitle",?"");???
???}
???
}

在 Activity 中動(dòng)態(tài)加載片段:

1
2
3
4
5
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
DemoFragment fragmentDemo = DemoFragment.newInstance(5,?"my title");
ft.replace(R.id.your_placeholder, fragmentDemo);
ft.commit();

2. 通過調(diào)用Fragment成員方法

如上面示例中的fragment.setText(str)

3. 通過接口回調(diào)

如上面示例中的onRssItemSelected回調(diào)

了解FragmentManager

FragmentManager負(fù)責(zé)Fragment的所有運(yùn)行時(shí)管理,包括添加、刪除、隱藏、顯示或以其他方式在Fragment之間導(dǎo)航。重要的可用方法概述如下:

1
2
3
4
5
6
7
addOnBackStackChangedListener:為片段返回堆棧的更改添加一個(gè)新的偵聽器。
beginTransaction():創(chuàng)建一個(gè)新事務(wù)以在運(yùn)行時(shí)更改片段。
findFragmentById(int?id):通過通常從活動(dòng) XML 布局中擴(kuò)展的 id 查找片段。
findFragmentByTag(String tag):通常為運(yùn)行時(shí)添加的片段按標(biāo)簽查找片段。
popBackStack():從 backstack 中刪除一個(gè)片段。
executePendingTransactions():強(qiáng)制應(yīng)用已提交的事務(wù)。

Fragment生命周期

上面我們說過,F(xiàn)ragment雖然依賴于Activity運(yùn)行,但是Fragment有它自己的生命周期

1
2
3
4
5
6
7
8
9
10
11
12
onAttach():當(dāng)片段連接到活動(dòng)時(shí)調(diào)用。
onCreate():被調(diào)用來進(jìn)行片段的初始創(chuàng)建。
onCreateView():一旦 Fragment 應(yīng)該膨脹視圖,Android 就會(huì)調(diào)用它。
onViewCreated():在之后調(diào)用onCreateView()并確保片段的根視圖是non-null. 任何視圖設(shè)置都應(yīng)該在這里進(jìn)行。例如,查看查找、附加偵聽器。
onActivityCreated():當(dāng)宿主活動(dòng)完成其onCreate()方法時(shí)調(diào)用。
onStart():一旦片段準(zhǔn)備好顯示在屏幕上,就會(huì)被調(diào)用。
onResume():分配“昂貴”的資源,例如注冊(cè)位置、傳感器更新等。
onPause():釋放“昂貴”的資源。提交任何更改。
onDestroyView():當(dāng)片段的視圖被銷毀時(shí)調(diào)用,但片段仍然保留在周圍。
onDestroy():當(dāng)片段不再使用時(shí)調(diào)用。
onDetach():當(dāng)片段不再連接到活動(dòng)時(shí)調(diào)用。

通常在onCreateView中設(shè)置視圖,onCreate用于任何數(shù)據(jù)初始化,onActivityCreated用于設(shè)置只有在 Activity 完全創(chuàng)建后才能發(fā)生的事情。

這是一個(gè)如何使用各種片段生命周期事件的示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
public?class?SomeFragment?extends?Fragment {
????ThingsAdapter adapter;
????FragmentActivity listener;
????????
????// 此事件在創(chuàng)建Fragment或任何視圖之前最先觸發(fā),當(dāng)Fragment與Activity關(guān)聯(lián)時(shí),將調(diào)用onAttach方法。
????@Override
????public?void?onAttach(Context context) {
????????super.onAttach(context);
????????if?(context?instanceof?Activity){
????????????this.listener = (FragmentActivity) context;
????????}
????}
???????
????// 此事件在為Fragment創(chuàng)建視圖之前觸發(fā),在創(chuàng)建或重新創(chuàng)建Fragment時(shí),會(huì)調(diào)用onCreate方法。
????@Override
????public?void?onCreate(Bundle savedInstanceState) {
????????super.onCreate(savedInstanceState);
????????ArrayList<Thing> things =?new?ArrayList<Thing>();
????????adapter =?new?ThingsAdapter(getActivity(), things);
????}
????// 當(dāng)Fragment應(yīng)該動(dòng)態(tài)地或通過XML布局創(chuàng)建其視圖對(duì)象層次結(jié)構(gòu)時(shí),調(diào)用onCreateView方法。
????@Override
????public?View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState) {
????????return?inflater.inflate(R.layout.fragment_some, parent,?false);
????}
????
????// 此事件在onCreateView()之后不久觸發(fā)。只有從onCreateView()返回的視圖非空時(shí),才會(huì)調(diào)用onViewCreated()。任何視圖設(shè)置都建議在這里進(jìn)行。
????@Override
????public?void?onViewCreated(View view, Bundle savedInstanceState) {
????????super.onViewCreated(view, savedInstanceState);
????????ListView lv = (ListView) view.findViewById(R.id.lvSome);
????????lv.setAdapter(adapter);
????}
????????
????// 此方法在父Activity的onCreate()方法完成后調(diào)用。
????@Override
????public?void?onActivityCreated(Bundle savedInstanceState) {
????????super.onActivityCreated(savedInstanceState);
????}
????// 當(dāng)Fragment與Activity失去關(guān)聯(lián)時(shí),將調(diào)用此方法。保存在onAttach中的任何引用都應(yīng)在此處為null,以防止內(nèi)存泄漏。
????@Override
????public?void?onDetach() {
????????super.onDetach();
????????this.listener =?null;
????}
}

源碼鏈接:https://yunjunet.cn/876809.html

Android開發(fā)學(xué)習(xí)教程(26)- Android Fragment(碎片)的評(píng)論 (共 條)

分享到微博請(qǐng)遵守國家法律
潢川县| 库尔勒市| 新蔡县| 磐安县| 襄城县| 沭阳县| 双辽市| 涟源市| 宜黄县| 石嘴山市| 全州县| 云南省| 鸡泽县| 汶上县| 凌云县| 张家川| 和林格尔县| 南部县| 自治县| 桃园市| 寻乌县| 比如县| 宿松县| 宾阳县| 建宁县| 东台市| 宜丰县| 三都| 绥宁县| 龙江县| 夏津县| 克山县| 广昌县| 建湖县| 达拉特旗| 汉寿县| 山东| 鱼台县| 左权县| 弥勒县| 黑河市|