0
点赞
收藏
分享

微信扫一扫

Android Fragment——详解

一天清晨 2022-12-16 阅读 102


1.Fragment概述

在一个Activity中, Fragment代表UI的一个部分或者一个行为。一个Activity可以结合多个Fragment对象,也可以在多个activity中使用相同Fragment字节码对应的不同对象。一个Fragment对象必须被嵌入在一个主Activity对象中,该Fragment的生命周期与主Activity息息相关。比如,当主Activity处于paused状态,其对应的所有Fragment对象均处于paused状态,只有当主Activity处于resumed状态时,Fragment才能处于自由控制状态。

2.创建Fragment

为了创建一个Fragment,应该去继承Fragment或者其子类,覆写相应的方法。比如onCreate(),OnCreateView(),onPause()等等

实例化一个Fragment对象,除了可以new外,还可以使用Fragment的静态函数Fragment.instantiate(mContext, "class 完整路径", info.args);,利用反射实现,但是性能较低

(1).添加UI界面

为该Fragment展现一个布局,必须去实现onCreateView()回掉方法。
注意:当该Fragment继承了ListFragment时,不需要覆写onCreateView()方法,因为默认返回一个ListView对象



[java]  view plain copy



  1. public View onCreateView(LayoutInflater inflater, ViewGroup container,  
  2.         Bundle savedInstanceState) {  
  3. null);  
  4. return view;  
  5. }  


(2).添加Fragment到Activity

1).通过layout布局文件

android:name属性应该为Fragment对应类的完整路径。



[html]  view plain copy



  1. <fragment  
  2. android:id="@+id/f"  
  3. android:layout_width="wrap_content"  
  4. android:layout_height="wrap_content"  
  5. android:name="com.example.a29fragment.MyFragment"/>  


在兼容低版本时,如果使用 静态注册,而MyFragment是使用了兼容support.v4.app.Fragment,就不能使用Activity了,只能使用 FragmentActivity

静态在xml文件配置,该fragment不能被移除,不可动态被编辑。



[html]  view plain copy



  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="horizontal" >  
  6.   
  7. <fragment  
  8. android:id="@+id/list"  
  9. android:name="com.example.news.ArticleListFragment"  
  10. android:layout_width="0dp"  
  11. android:layout_height="match_parent"  
  12. android:layout_weight="1" />  
  13. <fragment  
  14. android:id="@+id/viewer"  
  15. android:name="com.example.news.ArticleReaderFragment"  
  16. android:layout_width="0dp"  
  17. android:layout_height="match_parent"  
  18. android:layout_weight="2" />  
  19.   
  20. </LinearLayout>  


2).通过Java代码

当Activity运行时,可以自由的在该activity上添加fragment对象,但应该指定一个ViewGroup容器,可以FragmentTransaction完成fragment的添加移除或者替换。



[java]  view plain copy



  1. manager = getFragmentManager();  
  2. if(manager.findFragmentByTag("right") == null){  
  3. new RightFrag(), "right").commit();  
  4. }  


(3).fragment唯一标示符

每个fragment需要定义一个唯一的标识符,如果activity被销毁又重新启动,系统能够恢复该fragment的状态。如果想重新恢复,需满足下面有3种方式之一:

1).定义ID

在布局文件中,定义android:id属性



[html]  view plain copy



  1. <fragment  
  2. android:id="@+id/list"  
  3. android:name="com.example.news.ArticleListFragment"  
  4. android:layout_width="0dp"  
  5. android:layout_height="match_parent"  
  6. android:layout_weight="1" />  


2).指明tag

android:tag 指明 或者 一个fragment对象add()或者replace()时指定tag



[html]  view plain copy



  1. <fragment  
  2. android:id="@+id/list"  
  3. android:tag="first"  
  4. android:name="com.example.news.ArticleListFragment"  
  5. android:layout_width="0dp"  
  6. android:layout_height="match_parent"  
  7. android:layout_weight="1" />  


或者



[java]  view plain copy



  1. manager.beginTransaction()  
  2. new RightFrag(), "right")//在事务中指明该fragment的tag  
  3. .commit();  


3).viewgroup ID

如果该fragment均没有id和tag,系统将使用container view布局的id

3.Fragment的管理

通过getFragmentManager()方法,可以得到FragmentManager对象,主要完成下面的功能



[java]  ​​view plain​​ ​​copy​​



  1. FragmentManager manager = getFragmentManager();  


(1).得到已经存在Fragment对象

如果该fragment在布局文件中指定了id,通过findFragmentById()得到对象,或者指定了tag可以通过findFragmentByTag()得到对象



[java]  view plain copy



  1. Fragment fragment = getFragmentManager().findFragmentByTag("right");  
  2. //or  
  3. Fragment fragment = getFragmentManager().findFragmentById(id);  


(2).注册OnBackStackChangedListener监听器

可以用来监听该任务对应的返回栈信息,当该返回栈状态发生改变时,执行对应的onBackStackChanged() 方法



[java]  view plain copy



  1. manager.addOnBackStackChangedListener(new FragmentManager.OnBackStackChangedListener() {  
  2. @Override  
  3. public void onBackStackChanged() {  
  4. this, "返回堆状态发生改变", 1).show();  
  5.     }  
  6. });  


(3).弹出返回栈

模拟用户点击返回键,将指定的fragment从返回栈中弹出,该操作为异步的。前提是该fragment对象使用.beginTransaction().addToBackStack("right")添加了进返回栈



[java]  view plain copy



  1. manager.popBackStack(); //Pop the top state off the back stack  


(4).FragmentTransaction事务

事务主要包含一些操作的集合,比如增加移除替换,动画设置等等



[html]  view plain copy



  1. /*  
  2.  * 通过manager开启一个事务,该事务包含一些操作的集合,通事务可以 add(), remove(), replace()  
  3.  * 完成对Fragment的操作,并使用commit()提交  
  4.  */  
  5. FragmentTransaction transaction = manager.beginTransaction();  
  6.   
  7. transaction.replace(R.id.right, new RightFrag(), "right");  
  8. transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);//设置动画  
  9. transaction.addToBackStack("right"); // 将该fragment加入返回堆  
  10. // 提交事务  
  11. transaction.commit();  


(5).Fragment状态管理



[java]  view plain copy



  1. /*
  2.  * 管理Fragment的状态
  3.  *  如果在一个主activityViewGroup中添加一个fragment,
  4.  *  如果手机屏幕旋转了,当前activity被销毁重建,fragment也被activityManager创建
  5.  *  故在onCreate中,需要判断一下
  6.  */  
  7. @Override  
  8. protected void onCreate(Bundle savedInstanceState) {  
  9. super.onCreate(savedInstanceState);  
  10.     setContentView(R.layout.activity_main);  
  11.     manager = getFragmentManager();  
  12. if (manager.findFragmentByTag("right") == null) {  
  13. // if(savedInstanceState == null)也可判断该fragment是否已经加载  
  14.   
  15.         manager.beginTransaction()  
  16. new RightFrag(), "right")  
  17. // 设置动画  
  18. "right") // 将该fragment加入返回堆  
  19. // 提交事务  
  20.         .commit();  
  21.     }  
  22. }  


4.向下兼容

可参阅 ​​CursorLoader的兼容​​~~,特别注意:如果使用 静态注册,在布局文件配置<fragment>标签时,指定了name的class由于兼容support.v4.app.Fragment,加载布局文件的Class就不能继承Activity了,只能继承 FragmentActivity

5.Fragment间信息交互

(1).取得对象



[java]  view plain copy



  1. /*
  2.  * 点击该Fragment的button按钮,将该button的text设置为另一个fragment中Edittext的文本值
  3.  */  
  4. public View onCreateView(LayoutInflater inflater, ViewGroup container,  
  5.         Bundle savedInstanceState) {  
  6. null);  
  7. final Button button = (Button) view.findViewById(R.id.confirm);  
  8. new View.OnClickListener() {  
  9.           
  10. @Override  
  11. public void onClick(View v) {  
  12. //通过FragmentManager找到另一个fragment中的edittext对象,并取得text内容  
  13. "left").getView().findViewById(R.id.name));  
  14.             button.setText(editText.getText().toString());  
  15.         }  
  16.     });  
  17. return view;  
  18. }  


 (2).通回掉函数



[java]  view plain copy



  1. public class MainActivity extends Activity {  
  2. private FragmentManager manager;  
  3. private Button button;  
  4.   
  5. @Override  
  6. protected void onCreate(Bundle savedInstanceState) {  
  7. super.onCreate(savedInstanceState);  
  8.         setContentView(R.layout.activity_main);  
  9.           
  10. new View.OnClickListener() {  
  11. @Override  
  12. public void onClick(View v) {  
  13. "right"));  
  14. /*
  15.                  * 通过set方法,向其传递一个实例化对象,由于rightFrag.set()方法内部执行RightFragment.CallBack.get()方法,完成了参数的传递
  16.                  */  
  17. new RightFragment.CallBack() {  
  18. @Override  
  19. public void get(String str) {  
  20.                         button.setText(str);  
  21.                     }  
  22.                 });  
  23.             }  
  24.         });  
  25.     }  
  26.   
  27. }  




[java]  view plain copy



  1. public class RightFragment extends ListFragment {  
  2. private LoaderManager manager;  
  3.   
  4. @Override  
  5. public void onCreate(Bundle savedInstanceState) {  
  6. super.onCreate(savedInstanceState);  
  7.         manager = getLoaderManager();  
  8.     }  
  9.   
  10. /*
  11.      * 点击该Fragment的button按钮,将该button的text设置为另一个fragment中Edittext的文本值
  12.      */  
  13. public View onCreateView(LayoutInflater inflater, ViewGroup container,  
  14.             Bundle savedInstanceState) {  
  15. null);  
  16. return view;  
  17.     }  
  18.   
  19. /**
  20.      * 通过调用该方法,接收一个回掉函数对象,callBack.get(str);
  21.      * @param callBack
  22.      */  
  23. public void set(CallBack callBack) {  
  24.         EditText editText = (EditText) getView().findViewById(R.id.name);  
  25.         callBack.get(editText.getText().toString());  
  26.     }  
  27.   
  28. /*
  29.      * 回掉接口
  30.      */  
  31. interface CallBack {  
  32. public void get(String str);  
  33.     }  
  34. }  


6.Fragment的生命周期

(1).生命周期路线图

生命状态

周期过程

 

foreground lifetime

onResume(A)

onResume(F)

onPause(F)

onPause(A)

举报

相关推荐

0 条评论