android學習之Fragment與Activity的綁定

來源:互聯網
上載者:User

android學習之Fragment與Activity的綁定
最近項目忙完了,老大又不讓我做android了,總之快速開發接觸的東西會很多,只要能解決問題的都是好方法,但從個人的角度而言,快速的開發讓人無法深入瞭解一些技術,雖然現在在項目中可能不會做android了,但是既然開始學習了就不要放棄,繼續自己的學習。

Fragment在android中被稱為片段,該技術的引入主要是解決android開源的多種螢幕適配問題,在平板、手機、電視都在使用android的情況下,單純的採用activity會導致UI的單一,Fragment為瞭解決這種問題在android sdk11中引入。fragment需要綁定到activity中才能運行。

Fragment和Activity在某種程度有一定的相似性,也有類似的生命週期。但是Fragment必須依附於Activity,同時Activity不能被替換、刪除等操作,而Fragment允許被替換和刪除。

Fragment可以通過UI控制項fragment綁定對應的Fragment也可以採用動態添加方式。兩種方式,第一種相對比較簡單,而第二種則更加的靈活,通常是實際使用中合理的選擇其中的一種方式。Fragment的靈活性大於Activity,因此目前android的設計中推崇AUF,就是所有的都使用Fragment。

第一種方式的實現通常在XML的布局檔案中顯示的定義對應的Fragmet的資訊。

  1. <fragment xmlns:android="http://schemas.android.com/apk/res/android"
  2. android:id="@+id/helloFragment"
  3. android:layout_width="match_parent"
  4. android:layout_height="match_parent"
  5. android:name="com.example.hell.HelloFragment">
  6. </fragment>
其中的android就是對應的Fragment的類名,這種方式不能方便的進行擴充和取消。

在最近的學習中,較好的體驗了android設計的MCV思想,M通常是指資料相關的模型,也就是設計相關的資料模組,這種將設計的會使得資料是獨立於其他組件的,C是指控制模組,這個模組會實現UI顯示與資料的關聯,實現具體的控制關聯,V是指顯示功能,將相關的資料資訊通過控制顯示出來。因此在android的功能設計的過程中最好將相關的資料資訊作為單獨的類,並提供管理這些資料的單一執行個體工具類,通過這個工具類,控制相關的組件能夠訪問到這些資料資訊。

這些也是在看了一些代碼之後的感想而已。AUF的思想通常使得在建立一個activity的過程中都需建立一個對應的Fragment的對象,對應的activity的layout只是提供簡單的Fragment容器。
  1. <?xml version="1.0" encoding='utf-8'?>
  2. <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. android:id="@+id/fragmentContainer"
  4. android:layout_width="match_parent"
  5. android:layout_height="match_parent"
  6. />
而關於fragment的布局則是實際需要顯示的相關ui布局。
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. android:layout_width="match_parent"
  4. android:layout_height="match_parent"
  5. android:orientation="vertical" >

  6. <TextView
  7. android:layout_width="match_parent"
  8. android:layout_height="wrap_content"
  9. android:text="@string/crime_title_label"
  10. style="?android:listSeparatorTextViewStyle"
  11. />

  12. <EditText
  13. android:id="@+id/crime_title"
  14. android:layout_width="match_parent"
  15. android:layout_height="wrap_content"
  16. android:hint="@string/crime_title_hint"
  17. />

  18. <TextView
  19. android:layout_width="match_parent"
  20. android:layout_height="wrap_content"
  21. android:text="@string/crime_details_label"
  22. style="?android:listSeparatorTextViewStyle"
  23. />

  24. <Button
  25. android:id="@+id/crime_date"
  26. android:layout_width="match_parent"
  27. android:layout_height="wrap_content"
  28. android:layout_marginLeft="16dp"
  29. android:layout_marginRight="16dp"
  30. />

  31. <CheckBox
  32. android:id="@+id/crime_solved"
  33. android:layout_width="match_parent"
  34. android:layout_height="wrap_content"
  35. android:layout_marginLeft="16dp"
  36. android:layout_marginRight="16dp"
  37. android:text="@string/crime_solved_label"
  38. />

  39. </LinearLayout>
這樣設計的好處是activity不需要針對特定的ui布局,更像是一個通用的布局,所有的fragment都可以再其中添加。而Fragment則需要實現具體的UI布局,這樣也從實現上將activity和具體的UI顯示獨立開來,實現了Fragment的動態添加和UI切換。因此activity更多的是管理Fragment。

Fragment的綁定實現
在AUF的實現中有一種比較常用的方式就是單Fragment的Activity。也就是只有一個Fragment和Activity進行綁定,因此可以提供一個通用的方法用於實現fragment與activity的綁定關係,也就是實現一個單Fragment綁定的Activity類。這樣所有的Fragment需要綁定到一個具體的Activity的過程中只需要建立對應的Fragment對象,關於綁定的操作就有該抽象類別完成。在代碼中添加Fragment的實現會使用到一個Fragment的管理器FragmentManager,這個管理器的操作有點兒類似資料庫的事物處理操作過程。具體的實現過程如下所示:
  1. public abstract class SingleFragmentActivity extends FragmentActivity {
  2. protected abstract Fragment createFragment(); <<----該方法用於建立不同的Fragment對象

  3. @Override
  4. protected void onCreate(Bundle arg0) {
  5. super.onCreate(arg0);
  6. setContentView(R.layout.activity_fragment);
  7. /* 擷取管理器*/
  8. FragmentManager fm = getSupportFragmentManager();
  9. Fragment fragment = fm.findFragmentById(R.id.fragmentContainer); //R.id.fragmentContainer就是容器

  10. if (fragment == null) {
  11. /* 在activity中添加對應的Fragment的過程*/
  12. fragment = createFragment();
  13. fm.beginTransaction() //具體的操作類似資料庫的交易處理過程
  14. .add(R.id.fragmentContainer, fragment)
  15. .commit();
  16. }
  17. }
  18. }
在具體的實現某一個activity的過程中只需要實現對應的抽象函數Fragment createFragment(),同時所有的activity可以通用同一個布局檔案。以上的代碼實現了一個Fragment和activity的綁定過程,也就是需要使用FragmentManager進行控制。
  1. public class CrimeActivity extends SingleFragmentActivity {

  2. @Override
  3. protected Fragment createFragment() {
  4. //實現具體的建立過程
  5. }
  6. }
這樣的對於activity就非常的通用,因此在這種單一fragment的情況下可以採用通用的activity。

關於createFragment的實現方式,其實可以針對不同的activity分別實現代碼,但是在實際使用過程中都是採用其中一個activity中的Fragment啟動另一個activity的方式,因此可能會傳遞一些參數,而這些參數時針對activity的,而為了實現AUF的思想,在其實activity的過程中就應該啟動對應的Fragment。

有時候Fragment有一些歸屬於當前對象的參數資訊需要儲存,當然可以儲存到歸屬的activity中,但是考慮到統一性,通常會考慮添加Fragment的Bundle參數,關於Fragment的Bundle參數有點兒類似Activity的Bundle參數,用於儲存一些重要的資訊,但是Fragment的Bundle參數需要在添加到Acitvity之前綁定,考慮到Fragment的通用性,可以為每一個建立的Fragment都添加一個對應的Bundle argement。具體如下所示:
  1. publicclassCrimeFragment extends Fragment{
  2. ...
  3. /* 這是fragment實現bundle的基本規則,在建立fragment的過程中不要調用建構函式 */
  4. /* 該函數必須為static方法,不然必須先建立對應的對象才能建立fragmet*/
  5. public static CrimeFragment newInstance(UUID crimeId) {
  6. Bundle args = new Bundle(); //建立bundle參數對象
  7. args.putSerializable(EXTRA_CRIME_ID, crimeId); //填充對應的key-word對

  8. CrimeFragment fragment = new CrimeFragment(); //建立對應的Fragment類
  9. fragment.setArguments(args); //邦對對應的bundle參數

  10. return fragment;
  11. }
  12. ...
  13. }
這樣就可以在對應的activity中去實現對應的createfragment方法了,具體實現如下所示:
  1. public class CrimeActivity extends SingleFragmentActivity {

  2. @Override
  3. protected Fragment createFragment() {
  4. UUID crimeId = (UUID) getIntent()
  5. .getSerializableExtra(CrimeFragment.EXTRA_CRIME_ID);
  6. //該參數來自activity,通過newInstance將參數傳遞給了Fragment
  7. return CrimeFragment.newInstance(crimeId);
  8. }
  9. }
雖然newInstance()的實現方法也可以在Activity的createFragment函數實現中完成,但是考慮到可重用性,將Fragment的綁定關係由Fragment實現更加的通用。

通過這種方式,就可以在其中的一個Activity的Fragment中啟動另一個Activity中的Fragment。因此基本的實現過程如下所示.

SinalFragmentActivity(完成Fragment與Activity的綁定操作)
|
V
XXXActivity (實現具體Fragment的建立操作)
|
V
擷取activity的參數,然後調用Fragment的綁定Bundle的建立函數


XXXFragment
|
V
定義靜態建立執行個體方法,該方法中實現bundle和Fragment的綁定關係

因此Activity的類的實現方法如下所示:
  1. public class CrimeActivity extends SingleFragmentActivity {

  2. @Override
  3. protected Fragment createFragment() {
  4. UUID crimeId = (UUID) getIntent()
  5. .getSerializableExtra(CrimeFragment.EXTRA_CRIME_ID);
  6. //擷取activity的參數,並通過newInstance函數將對應的參數與、Fragment進行綁定
  7. return CrimeFragment.newInstance(crimeId);
  8. }
  9. }
這種實現方法較好的實現了AUF中單Activity和Fragment的綁定實現,這種綁定實現對於Activity的布局非常通用,定義的抽象類別也實現了Fragment和Activity的綁定關係。只需要實現對應Fragment的建立操作,為了進一步的實現,要求Fragment提供一種綁定Bundle的靜態方法實現一個對象的建立,並綁定了一個bundle的對象。

這種實現方法主要是為了遵循AUF的實現,其實並不需要實現的這麼複雜,但是從可重用性的角度分析,這樣的實現方法是非常不錯的。

有一些優秀的分析可以去拜讀一下。
http://www.cnblogs.com/xinye/archive/2012/08/28/2659712.html
http://blog.csdn.net/guolin_blog/article/details/8881711

參考文獻:
Android Programming: The Big Nerd Ranch Guide 第10章


聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.