1.定義
Fragment中文解釋是碎片的意思,主要用在大屏幕設備上,例如平板電腦上,支持更加動態和靈活的UI設計。Fragment在你的應用中相當於是一個模塊化和可重用的組件,因為Fragment定義了它自己的布局,以及通過使用它自己的生命周期回調方法定義了它自己的行為,你可以將Fragment包含到多個Activity中。
2.特點
(1)Fragment可以作為Activity界面的一部分組成出現;
(2)可以在一個Activity中同時出現多個Fragment,並且一個Fragment也可以在多個Activity中使用;
(3)在Activity運行過程中,可以添加、移除或者替換Fragment;
(4)Fragment可以響應自己的輸入事件,並且有自己的生命周期,它們的生命周期會受宿主Activity的生命周期影響。
3.生命周期
Fragment必須是依存於Activity而存在的,因此Activity的生命周期會直接影響到Fragment的生命周期。
生命周期中涉及的方法如上圖所示,具體觸發條件如下所述。4.靜態加載
這是使用Fragment最簡單的一種方式,把Fragment當成普通的控件,直接寫在Activity的布局文件中,用布局文件調用Fragment。
(1)新建Fragment,重寫onCreateView決定Fragment布局
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_static, container, false);
}
(2)在宿主Activity中手動添加Fragment,就把它當做普通的控件一樣,在xml文件中使用。name屬性填寫fragment的包路徑,Activity通過findFragmentById()或者findFragmentByTag()獲取Fragment。
<fragment
Android:name="ant.snail.com.fragmentactapp.StaticFragment"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:tag="newfrag" />
這樣在宿主Activity中就能看到Fragment了。
5.動態加載
上面的靜態加載是最基本的方法,下面解析下動態加載的原理。
(1)原理
動態加載,顧名思義是通過代碼的方式在Activity中加載Fragment。
通過撰寫代碼將Fragment添加到一個Activity layout中,這裡需要采用Fragment的事務處理(FragmentTransaction),有點類似數據庫的事務處理。
(2)具體實現
通過新建兩個Fragment,並在這兩個Fragment的Layout中添加了ImageView,用來放置圖片,而在宿主Activity中將這兩個Fragment動態切換,實現圖片的自由切換。代碼結構如下圖所示。
新建Fragment(Image1Fragment,Image2Fragment),並添加了兩個layout文件(fragment_image1,fragment_image2),其中部分代碼如下:
Image1Fragmet代碼:
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// 獲取Fragment的View
View view=inflater.inflate(R.layout.fragment_image1,container,false);
return view;
}
fragment_image1.xml文件代碼如下:
<LinearLayout 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"
android:orientation="vertical"
android:gravity="center_horizontal"
tools:context="ant.snail.com.fragmentactapp.Image1Fragment"
>
<!-- TODO: Update blank fragment layout -->
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:gravity="center"
>
<TextView
android:id="@+id/text1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="我是jin兔1"/>
<Button
android:layout_marginLeft="10dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="傳遞數據到主窗口"
android:id="@+id/btfr1" />
</LinearLayout>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/imageView1"
android:src="@drawable/jin1"/>
</LinearLayout>
宿主MainActivity的代碼如下,通過FragmentManager得到FragmentTransaction,然後通過replace()方法實現兩個Fragment之間的切換,最後實現了Commit()方法:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//獲取兩個按鈕的View
bt1=(Button)findViewById(R.id.bt1);
bt2=(Button)findViewById(R.id.bt2);
bt1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//主Activity動態加載Fragment
FragmentManager fragmentManager=getFragmentManager();
//處理Fragment事務
FragmentTransaction beginTransaction=fragmentManager.beginTransaction();
//獲取Image1Fragment實例
Image1Fragment image1Fragment=Image1Fragment.newInstance("Activity傳遞圖片1到Fragment中");
//替換操作
beginTransaction.replace(R.id.imageLayout,image1Fragment);
//允許用戶通過按下BACK按鍵返回到前一個Fragment狀態
beginTransaction.addToBackStack(null);
beginTransaction.commit();
}
});
bt2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//主Activity動態加載Fragment
FragmentManager fragmentManager=getFragmentManager();
//處理Fragment事務
FragmentTransaction beginTransaction=fragmentManager.beginTransaction();
//獲取Image1Fragment實例
Image2Fragment image2Fragment=Image2Fragment.newInstance("Activity傳遞圖片2到Fragment中");
//替換操作
beginTransaction.replace(R.id.imageLayout,image2Fragment);
//允許用戶通過按下BACK按鍵返回到前一個Fragment狀態
beginTransaction.addToBackStack(null);
beginTransaction.commit();
}
});
}
其中NewInstance方法是在Fragment中實現的一個實例方法,用於將Fragment實例化,通過參數param1的傳遞能將Activity中的數據傳遞到Fragment中。通過setArguments()以及getArguments()實現數據從Activity向Fragment傳遞的目的,如下圖所示。
public static Image1Fragment newInstance(String param1) {
Image1Fragment fragment = new Image1Fragment();
//在Activity中創建Bundle數據包,並調用Fragment的setArguments(Bundle bundle)方法
Bundle args = new Bundle();
args.putString(ARG_PARAM1, param1);
fragment.setArguments(args);
return fragment;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
//在Fragment中通過getArguments().getString()獲取Activity傳來的值
mParam1 = getArguments().getString(ARG_PARAM1);
}
}
6.Fragment與Activity通信
public interface OnFragmentInteractionListener {
public void onFragmentInteraction(String uri);
}
在Fragment的onAttach()方法中將Activity轉換為OnFragmentInteractionListener接口:
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
mListener = (OnFragmentInteractionListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString()
+ " must implement OnFragmentInteractionListener");
}
}
private OnFragmentInteractionListener mListener;
if (mListener != null) {
mListener.onFragmentInteraction("需要傳遞給Activity的值");
宿主Activity則需要實現此接口,並重寫onFragmentInteraction(String uri)方法,這樣就實現了數據從Fragment到Activity的傳遞:
public class MainActivity extends ActionBarActivity implements Image1Fragment.OnFragmentInteractionListener
@Override
public void onFragmentInteraction(String uri) {
TextView tv=(TextView)findViewById(R.id.tt);
tv.setText(uri);
}
7.效果截圖
本人致力於Web端與移動端的開發與研究,現主要從事GIS相關開發,如WebGIS、移動GIS開發等。更多Android相關信息見Android 專題頁面 http://www.linuxidc.com/topicnews.aspx?tid=11