Android入門(6)| 碎片
碎片是一種可以鑲嵌在活動中的UI片段,它可以讓程式簡單合理的利用螢幕的大空間。所以碎片經常用於HD應用的開發。這次我們就來看看碎片的簡單用法吧。

本節目錄
靜態新增碎片
首先還是新建一個空專案,然後新增兩個佈局,分別叫做right_layout和left_layout,在這裡面修改程式碼:
<?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"> <Button android:id="@+id/button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="button"/> </LinearLayout>
<?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/text_view" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Hello fragment"/> </LinearLayout>
然後我們需要新建LeftFragment和RightFragment類,並且讓它們繼承自Fragment類,注意在這裡我們選擇的Fragment類是support-v4庫中的Fragment,接著修改程式碼:
package com.example.yzbkaka.fragmenttest; import android.os.Bundle; import android.support.v4.app.Fragment; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; //LeftFragment public class LeftFragment extends Fragment { @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle saveInstanceState){ View view = inflater.inflate(R.layout.left_layout,container,false); return view; } }
package com.example.yzbkaka.fragmenttest; import android.app.Fragment; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; //RightFragment public class RightFragment extends Fragment { public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle saveInstanceState){ View view = inflater.inflate(R.layout.right_layout,container,false); return view; } }
在新建類時我們直接是呼叫inflater的inflate()方法來將佈局調入。
最後我們就可以將碎片加入到主佈局當中了:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="horizontal" android:layout_width="match_parent" android:layout_height="match_parent"> <fragment android:id="@+id/left_fragment" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:name="com.example.yzbkaka.fragmenttest.LeftFragment"/> <fragment android:id="@+id/right_fragment" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:name="com.example.yzbkaka.fragmenttest.RightFragment"/> </LinearLayout>
注意我們使用 android:name
這個屬性是為了將之前寫好的碎片的類匯入,但是這裡必須要將類的包名也加上才行。
最後就是啟動程式了,因為碎片主要是給平板這樣的大螢幕裝置使用的,所以這裡我們再建立一個新的平板虛擬裝置,裝置下載完成之後我們就可以啟動了。
動態新增碎片
碎片不僅僅可以靜態的新增,還可以很高階的動態新增進活動當中,我們就一起來看一看吧。
接著使用上面的專案,我們要新建一個佈局,叫做another_right_layout,同樣我們也需要為這個佈局新建一個類,叫做AnotherRightFragment:
<?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:layout_width="match_parent" android:layout_height="match_parent" android:layout_gravity="center_horizontal" android:text="This is another rightfragment"/> </LinearLayout>
package com.example.yzbkaka.fragmenttest; import android.os.Bundle; import android.support.v4.app.Fragment; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; public class AnotherRightFragment extends Fragment { public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle saveInstanceState){ View view = inflater.inflate(R.layout.another_right_layout,container,false); return view; } }
接著我們就來修改主佈局當中的程式碼:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="horizontal" android:layout_width="match_parent" android:layout_height="match_parent"> <fragment android:id="@+id/left_fragment" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:name="com.example.yzbkaka.fragmenttest.LeftFragment"/> <FrameLayout android:id="@+id/right_layout" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1"> </FrameLayout> </LinearLayout>
由於我們這裡是要動態的新增碎片,所以我們就先不在佈局中將碎片加上,而是先新增一個幀佈局,這個佈局就是預設將控制元件放在左上角。接著我們修改主程式碼:
package com.example.yzbkaka.fragmenttest; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentManager; import android.support.v4.app.FragmentTransaction; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.widget.Button; public class MainActivity extends AppCompatActivity implements View.OnClickListener { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Button button = (Button) findViewById(R.id.button); button.setOnClickListener(this); replaceFragment(new RightFragment()); } @Override public void onClick(View v) { switch (v.getId()) { case R.id.button: replaceFragment(new AnotherRightFragment()); break; default: break; } } private void replaceFragment(Fragment fragment) { FragmentManager fragmentManager = getSupportFragmentManager(); FragmentTransaction transaction = fragmentManager.beginTransaction(); transaction.replace(R.id.right_layout, fragment); transaction.addToBackStack(null); transaction.commit(); } }
可以看到我們使用的是replaceFragment()的方法來動態的新增碎片的,這裡新增碎片主要是分為3步:
第一步:先用getSupportFragmentManager()方法獲取一個FragmentManager物件,再通過它的beginTransaction()獲取一個FragmentTransaction的例項,開啟一個事務。
第二步:向容器內部新增或者替換碎片,這裡使用的是replace()方法來實現,它需要傳入兩個引數,第一個引數是要要傳入容器的id,這裡我們傳入的是之前定義好的FrameLayout的id;第二個引數是等待新增的碎片的例項。
第三步:使用commit()的方法來提交事務,完成新增。
這裡我們多使用了一個addToBackStack()的方法,它的作用就是當我們在手機上按下back鍵的時候,就會回到上一個碎片當中,如果不使用,則會直接退出程式。這個方法一般是傳入null來當引數就可以了。
碎片與活動之間通訊
1.在活動中獲取碎片
在活動中可以通過呼叫FragmentManager的findFragmentById()方法來得到相應碎片的例項,繼而可以呼叫碎片裡的方法。
RightFragment rightFragment = (RightFragment) getSupportFragmentManager().findFragmentById()(R.id.right_fragment);
2.在碎片中獲取活動
每一個碎片都可以通過呼叫getActivity()方法來得到和當前活動相關聯的活動例項:
MainActivity activity = (MainActivity) getActivity();
3.碎片與碎片之間的通訊
碎片之間交流的主要思路就是在一個碎片中先獲取到與它相關聯的活動,然後再通過這個活動來或的其他的碎片即可。
碎片的生命週期
由於碎片是依附於活動生存的,所以碎片的生命週期是和活動的生命週期相似的,也是分為了4種狀態: 執行狀態、暫停狀態、停止狀態和銷燬狀態 ,但是在一些細小的地方碎片和活動會有一些不同。

碎片的生命週期
,下面來具體介紹這5個回撥方法:
- onAttach()
當碎片與活動相關聯的時候呼叫。 - onCreateView()
當為碎片建立檢視的時候呼叫。 - onActivityCreated()
當與碎片相關聯的活動建立的時候呼叫。 - onDestroyView()
當與碎片相關聯的檢視銷燬的時候呼叫。 - onDetach()
當碎片與其相關聯的活動解除關聯的時候呼叫。
所以我們簡單的將圖片概括出來就是:
1.當開啟介面時:onAttach()->onCreate()->onCreateView()->onActivityCreated() ->onStart()->onResume() 2.當按下主螢幕鍵時:onPause()->onStop() 3.當重新回到介面時:onStart()->onResume() 4.當按下back鍵時:onPause()->onStop()->onDestroyView()->onDestroy()->onDetach()