詳解Android開發(fā)中Fragment的使用
前言
學習Java和Android將近一年的時間了,期間的成果應該就是獨立完成了一個Android客戶端,并且保證了其在主線版本的穩(wěn)定性。期間遇到了很多坑,也跟著師兄學到了很多Android知識。但是人總是要擁抱變化,不能讓自己太安逸,雖然有不舍,但是我已經(jīng)證明了自己的學習能力,下一步就是開始做Rom Porting了。這里總結(jié)一下之前項目中用到最多的Fragment。
Fragment簡介
Fragment可以理解成Activity中用戶界面的一個行為或者一部分,它必須被嵌套在Activity中。但是一個Fragment有它自己獨立的xml布局文件,并且具有良好的封裝性,因此特殊情況下Fragment可以很容易用Activity來進行替換。
創(chuàng)建Fragment
創(chuàng)建一個Fragment和創(chuàng)建Activity類似,需要實現(xiàn)XML布局文件和Java Class。
XML布局文件和其他布局文件都一樣,例如如下所示的布局文件(fragment_layout.xml):
<?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" > <TextView android:id="@+id/textView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/testview" /> <Button android:id="@+id/button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/button" /> </LinearLayout>
Java代碼中,一般情況下可以根據(jù)需要實現(xiàn)Fragment以下幾個生命周期方法:
1. onAttach():當Fragment依附于activity時被調(diào)用,可以在該方法中獲取activity句柄,從而實現(xiàn)Fragment和activity之間的通信。
2. onCreate():對Fragment做初始化。
3. onCreateView():在第一次為Fragment繪制用戶界面時系統(tǒng)會調(diào)用此方法。
4. onActivityCreated():在宿主Activity onCreate函數(shù)執(zhí)行完成之后被調(diào)用,可以在這個方法里進行Fragment自己的widget實例化和業(yè)務邏輯處理。
5. onDestoryView():當Fragment開始被銷毀時調(diào)用。
6. onStart():當Fragment可見時被調(diào)用。
還有許多其他用以操縱Fragment生命周期中各個階段的回調(diào)函數(shù),大家可自行Google學習。
Fragment生命周期
每一個Fragment都有自己的一套生命周期回調(diào)方法和處理自己的用戶輸入事件。對應的生命周期如下圖所示:
在Activity中加入Fragment
首先,需要確保Acitivity支持Fragment,因此Activity通常需要繼承自FragmentActivity。在Activity中添加Fragment通常有兩種方法:靜態(tài)的和動態(tài)的。
靜態(tài)方法
直接在Activity的XML布局文件中加入Fragment,如下所示:
<?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:baselineAligned="false" android:orientation="horizontal" > <fragment android:id="@+id/first" android:name="com.example.FristFragment" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" /> <fragment android:id="@+id/second" android:name="com.example.SecondFragment" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" /> </LinearLayout>
<fragment>中的android:name 屬性指定了布局中實例化的fragment類
當系統(tǒng)創(chuàng)建Activity布局時,它實例化了布局文件中指定的每一個Fragment,并且為它們調(diào)用onCreateView()函數(shù),以獲取每一個fragment的布局。系統(tǒng)直接在<fragment>元素位置插入fragment返回的view
注意:每個fragment都需要一個唯一的標識,如果重啟activity,系統(tǒng)可用來恢復fragment(并且用來捕捉fragment的事務處理,例如移除)。為了Fragment提供ID有三種方法:
- 用android:id屬性提供一個唯一的標識
- 用android:tag屬性提供一個唯一的字符串
- 如果上述兩個屬性都沒有,系統(tǒng)會使用其容器視圖的ID
動態(tài)方法
使用FragmentTranscation??梢允褂肍ragmentTranscation的API來對Activity的Fragment進行操作(例如添加,移除,或者替換Fragment)。參考代碼如下:
FragmentManager fragmentManager = getFragmentManager() FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); ExampleFragment fragment = new ExampleFragment(); fragmentTransaction.add(R.id.fragment_container, fragment); fragmentTransaction.commit();
傳入add()函數(shù)的第一個參數(shù)是Fragment被放置的ViewGroup,它由資源ID(resource ID)指定,第二個參數(shù)就是要添加的fragment。一旦通過FragmentTranscation做了更改,都應當使用commit()視變化生效。
Fragments通信
Fragments之間不應該直接進行通信,它們之間的交互應該通過宿主Activity進行。有三種Fragment和Acitivity交互的方法:
1. Activity創(chuàng)建帶參數(shù)的Fragment。
2. Activity中保持了Fragment的對象句柄,可通過句柄直接調(diào)用該Fragment的public方法。
3. Fragment可在onAttach函數(shù)中獲取定義的listener句柄。
創(chuàng)建帶參數(shù)的Fragment
在某些特定的情況下,F(xiàn)ragment可能需要特定的參數(shù)來進行初始化。由于Fragment必須只有一個無參構(gòu)造函數(shù),因此可以考慮使用靜態(tài)的newInstance方法來創(chuàng)建帶參數(shù)的Fragment。示例代碼如下:
import android.os.Bundle; import android.support.v4.app.Fragment; public class TestFragment extends Fragment { public static TestFragment newInstance(int num, String title) { TestFragment fragment = new TestFragment(); Bundle args = new Bundle(); args.putInt("num", num); args.putString("title", title); fragment.setArguments(args); return fragment; } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); int num = getArguments().getInt("num", 0); String title = getArguments().getString("title", ""); } }
你可以在Activity里,簡單的加載一個帶參數(shù)的Fragment:
FragmentTransaction ft = getSupportFragmentManager().beginTransaction(); TestFragment fragment = TestFragment.newInstance(5, "fragment title"); ft.replace(R.id.placeholder, fragment); ft.commit();
調(diào)用Fragment的方法
因為Activity可以獲取嵌入的Fragment的句柄,因此可以直接通過Fragment句柄調(diào)用該方法。
public class TestFragment extends Fragment { public void doSomething(String param) { // do something in fragment } }
在Activity中,可以直接通過Fragment的對象句柄調(diào)用該方法:
public class MainActivity extends FragmentActivity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); TestFragment testFragment = new TestFragment(); testFragment.doSomething("some param"); } }
Fragment Listener
如果Fragment需要共享事件給Activity,則需要利用這個方法。Fragment中定義一個接口,并且由Activity來實現(xiàn)這個接口。在onAttach()方法中將實現(xiàn)了這個接口的Activity獲得到。
在Fragment中定義接口代碼如下:
import android.support.v4.app.Fragment; public class MyListFragment extends Fragment { // ... // Define the listener of the interface type // listener is the activity itself private OnItemSelectedListener listener; // Define the events that the fragment will use to communicate public interface OnItemSelectedListener { public void onRssItemSelected(String link); } // Store the listener (activity) that will have events fired once the fragment is attached @Override public void onAttach(Activity activity) { super.onAttach(activity); if (activity instanceof OnItemSelectedListener) { listener = (OnItemSelectedListener) activity; } else { throw new ClassCastException(activity.toString() + " must implement MyListFragment.OnItemSelectedListener"); } } // Now we can fire the event when the user selects something in the fragment public void onSomeClick(View v) { listener.onRssItemSelected("some link"); } }
在Activity中實現(xiàn)這個接口:
import android.support.v4.app.FragmentActivity; public class RssfeedActivity extends FragmentActivity implements MyListFragment.OnItemSelectedListener { DetailFragment fragment; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_rssfeed); fragment = (DetailFragment) getSupportFragmentManager() .findFragmentById(R.id.detailFragment); } // Now we can define the action to take in the activity when the fragment event fires @Override public void onRssItemSelected(String link) { if (fragment != null && fragment.isInLayout()) { fragment.setText(link); } } }
- Android使用Fragment打造萬能頁面切換框架
- FrameLayout和Fragment處理Android應用UI布局實例
- Android的Fragment的生命周期各狀態(tài)和回調(diào)函數(shù)使用
- Android應用開發(fā)中Fragment的靜態(tài)加載與動態(tài)加載實例
- Android程序開發(fā)之Fragment實現(xiàn)底部導航欄實例代碼
- Android編程使用Fragment界面向下跳轉(zhuǎn)并一級級返回的實現(xiàn)方法
- Android基于ViewPager Fragment實現(xiàn)選項卡
- Android中給fragment寫入?yún)?shù)的輕量開發(fā)包FragmentArgs簡介
- Android App開發(fā)中創(chuàng)建Fragment組件的教程
- Android中Fragment子類及其PreferenceFragment的創(chuàng)建過程演示
相關(guān)文章
SpringMVC利用dropzone組件實現(xiàn)圖片上傳
這篇文章主要介紹了SpringMVC利用dropzone組件實現(xiàn)圖片上傳,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2020-02-02springboot創(chuàng)建的web項目整合Quartz框架的項目實踐
本文主要介紹了springboot創(chuàng)建的web項目整合Quartz框架的項目實踐,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2022-06-06SpringBoot中l(wèi)ogback日志保存到mongoDB的方法
這篇文章主要介紹了SpringBoot中l(wèi)ogback日志保存到mongoDB的方法,2017-11-11Spring Boot實戰(zhàn)之netty-socketio實現(xiàn)簡單聊天室(給指定用戶推送消息)
本篇文章主要介紹了Spring Boot實戰(zhàn)之netty-socketio實現(xiàn)簡單聊天室(給指定用戶推送消息),具有一定的參考價值,有興趣的可以了解一下。2017-03-03Java設(shè)計模式之組合模式(Composite模式)介紹
這篇文章主要介紹了Java設(shè)計模式之組合模式(Composite模式)介紹,Composite定義:將對象以樹形結(jié)構(gòu)組織起來,以達成“部分-整體” 的層次結(jié)構(gòu),使得客戶端對單個對象和組合對象的使用具有一致性,需要的朋友可以參考下2015-03-03詳解rabbitmq使用springboot實現(xiàn)fanout模式
這篇文章主要介紹了rabbitmq使用springboot實現(xiàn)fanout模式,Fanout特點是發(fā)布與訂閱模式,是一種廣播機制,它是沒有路由key的模式,需要的朋友可以參考下2023-07-07