Fragment的常用功能
通過getFragmentManager()方法,可以得到FragmentManager對象,主要完成下面的功能
(1).得到已經存在Fragment對象
如果該fragment在布局檔案中指定了id,通過findFragmentById()得到對象,或者指定了tag可以通過findFragmentByTag()得到對象
Fragment fragment = getFragmentManager().findFragmentByTag("one");
Fragment fragment = getFragmentManager().findFragmentById(id);
(2).注冊OnBackStackChangedListener監聽器
可以用來監聽該任務對應的傳回棧資訊,當該傳回棧狀态發生改變時,執行對應的onBackStackChanged()方法
manager.addOnBackStackChangedListener(new FragmentManager.OnBackStackChangedListener() {
@Override
public void onBackStackChanged() {
Toast.makeText(MainActivity.this, "傳回棧狀态發生改變", Toast.LENGTH_SHORT).show();
}
});
(3).彈出傳回棧
模拟使用者點選傳回鍵,将指定的fragment從傳回棧中彈出,該操作為異步的。前提是該fragment對象使用beginTransaction().addToBackStack("right")添加進傳回棧
//Pop the top state off the back stack
manager.popBackStack();
(4).FragmentTransaction事務
事務主要包含一些操作的集合,比如增加移除替換,動畫設定等等
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction transaction = fragmentManager.beginTransaction();
transaction.add(R.id.framelayout_fragment_main, new FragmentOne(), "ONE");
transaction.commit();
(5).Fragment狀态管理
/*
* 管理Fragment的狀态
* 如果在一個主activityViewGroup中添加一個fragment,
* 如果手機螢幕旋轉了,目前activity被銷毀重建,fragment也被activityManager建立
* 故在onCreate中,需要判斷一下
*/
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
FragmentManager manager = getFragmentManager();
if (manager.findFragmentByTag("TWO") == null) {
// if(savedInstanceState == null)也可判斷該fragment是否已經加載
manager.beginTransaction()
.replace(R.id.framelayout_fragment_main, fragmentTwo, "TWO")
.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN)// 設定動畫
.addToBackStack("TWO") // 将該fragment加入傳回堆
// 送出事務
.commit();
}
fragment辨別符
每個fragment需要定義一個唯一的辨別符,如果activity被銷毀又重新啟動,系統能夠恢複該fragment的狀态。如果想重新恢複,需滿足下面有3種方式之一:
1. 定義ID
在布局檔案中,通過定義android:id屬性定義,例如
<fragment
android:id="@+id/fragment_title_main"
android:name="com.example.activity.TitleFragment"
android:layout_width="match_parent"
android:layout_height="45dp" />
2.指明tag
也可以在布局檔案中,通過定義android:id屬性定義,例如
android:tag="title"
或者使用FragmentTransaction對象的add()和replace()時指定tag,例如
FragmentTransaction transaction = fragmentManager.beginTransaction();
transaction.commit();
或者
transaction.replace(R.id.framelayout_fragment_main, fragmentTwo, "TWO");
transaction.addToBackStack(null);
transaction.commit();
3.viewgroup ID
如果該fragment既沒有id也沒有tag,系統将使用container view布局的id
下面是一個舉例說明,demo有一個主界面,三個fragment,點選第一個按鈕,切換到第二個界面,點選第二個按鈕,切換到第三個界面,然後點選Back鍵依次回退。這很類似Android的 Activity跳轉,當然這裡是Fragment實作的,使用者點選Back鍵,實際是Fragment回退棧不斷的彈棧。調用FragmentTransaction.addToBackStack(String)添加一個Fragment事務到回退棧
MainActivity.java代碼如下
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
// getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
// WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.activity_main);
FragmentManager fragmentManager = getFragmentManager();
//直接将FragmentOne添加到布局檔案中的FrameLayout中
}
}
布局如下
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="
http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<FrameLayout
android:id="@+id/framelayout_fragment_main"
android:layout_height="match_parent" />
</RelativeLayout>
FragmentOne.java如下
public class FragmentOne extends Fragment {
private Button mButton;
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// return inflater.inflate(R.layout.fragment_one, container, false);
View view = inflater.inflate(R.layout.fragment_one, container, false);
mButton = (Button) view.findViewById(R.id.btn_fragment_one);
mButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
FragmentTwo fragmentTwo = new FragmentTwo();
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction transaction = fragmentManager.beginTransaction();
transaction.replace(R.id.framelayout_fragment_main, fragmentTwo, "TWO");
transaction.addToBackStack(null);
transaction.commit();
}
});
return view;
replace()方法,實際是remove和add的合體, 并且如果不添加事務到回退棧,前一個Fragment執行個體會被銷毀。這裡我們調用transaction.addToBackStack(null);将目前的事務添加到了回退棧,是以FragmentOne執行個體不會被銷毀,但是視圖層次依然會被銷毀,即會調用onDestoryView和
onCreateView,從效果上看就是我們在跳轉前在文本框輸入的内容,在使用者Back得到第一個界面的時候不見了。
FragmentTwo.java代碼如下
public class FragmentTwo extends Fragment {
View view = inflater.inflate(R.layout.fragment_two, container, false);
mButton = (Button) view.findViewById(R.id.btn_fragment_two);
FragmentThree fragmentThree = new FragmentThree();
transaction.hide(FragmentTwo.this);
transaction.add(R.id.framelayout_fragment_main, fragmentThree, "THREE");
在FragmentTwo中我們沒有使用replace,而是先隐藏了目前的Fragment,然後添加了FragmentThree的執行個體,最後将事務添加到回退棧。這樣做的目的就是視圖不會重繪,也就是我們在FragmentTwo的EditText填寫的内容,使用者Back
回來時,資料還儲存着。
源代碼參考文章:
http://blog.csdn.net/zimo2013/article/details/12239349 http://blog.csdn.net/lmj623565791/article/details/37992017