在android开发过程中,如果使用到了导航栏。那么不可避免的就需要使用fragment来处理界面。闲着没事,就详解一下Framgent的使用方法吧。
难得写一次。本人
shoneworn
shonewron
shoneworn
重要事情说三遍。
1.Fragment 的生命周期
场景演示 : 切换到该Fragment
11-29 14:26:35.095: D/AppListFragment(7649): onAttach
11-29 14:26:35.095: D/AppListFragment(7649): onCreate
11-29 14:26:35.095: D/AppListFragment(7649): onCreateView
11-29 14:26:35.100: D/AppListFragment(7649): onActivityCreated
11-29 14:26:35.120: D/AppListFragment(7649): onStart
11-29 14:26:35.120: D/AppListFragment(7649): onResume
屏幕灭掉:
11-29 14:27:35.185: D/AppListFragment(7649): onPause
11-29 14:27:35.205: D/AppListFragment(7649): onSaveInstanceState
11-29 14:27:35.205: D/AppListFragment(7649): onStop
屏幕解锁
11-29 14:33:13.240: D/AppListFragment(7649): onStart
11-29 14:33:13.275: D/AppListFragment(7649): onResume
切换到其他Fragment:
11-29 14:33:33.655: D/AppListFragment(7649): onPause
11-29 14:33:33.655: D/AppListFragment(7649): onStop
11-29 14:33:33.660: D/AppListFragment(7649): onDestroyView
切换回本身的Fragment:
11-29 14:33:55.820: D/AppListFragment(7649): onCreateView
11-29 14:33:55.825: D/AppListFragment(7649): onActivityCreated
11-29 14:33:55.825: D/AppListFragment(7649): onStart
11-29 14:33:55.825: D/AppListFragment(7649): onResume
回到桌面
11-29 14:34:26.590: D/AppListFragment(7649): onPause
11-29 14:34:26.880: D/AppListFragment(7649): onSaveInstanceState
11-29 14:34:26.880: D/AppListFragment(7649): onStop
回到应用
11-29 14:36:51.940: D/AppListFragment(7649): onStart
11-29 14:36:51.940: D/AppListFragment(7649): onResume
退出应用
11-29 14:37:03.020: D/AppListFragment(7649): onPause
11-29 14:37:03.155: D/AppListFragment(7649): onStop
11-29 14:37:03.155: D/AppListFragment(7649): onDestroyView
11-29 14:37:03.165: D/AppListFragment(7649): onDestroy
11-29 14:37:03.165: D/AppListFragment(7649): onDetach
可以看出,和activity还是有差别的。
2.fragment的使用
fragment使用的时候,合理的选择容器是很重要的。如果容器选择不对。那么就可能达不到自己想要的效果。
由于fragment在viewgroup中是作为一个view来显示的。也就是只能作为一部分。所以,如果fragment不能覆盖整个屏幕,就会出现原来的view和新的view一起显示的景象。下面是用我线性布局来做为容器来放fragment。先看看出现的什么效果吧
点击textview1 后创建新的fragment2 。每次点击后,fragment2没有去沾满屏幕。而是不停的向下依次排列。在点击返回键后,又一次的回退,将fragment2 pop出栈。
布局文件:
fragment1.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/container" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <TextView android:id="@+id/textView1" android:layout_width="match_parent" android:layout_height="40dp" android:background="#32dfda" android:gravity="center" android:text="TextView1" android:textSize="18sp" /> <TextView android:id="@+id/textView2" android:layout_width="match_parent" android:layout_height="40dp" android:background="#36df0a" android:gravity="center" android:text="TextView1" android:textSize="18sp" /> <TextView android:id="@+id/textView3" android:layout_width="match_parent" android:layout_height="40dp" android:background="#82dfda" android:gravity="center" android:text="TextView1" android:textSize="18sp" /> </LinearLayout>
fragment1.java 代码:
package com.ailin.accm.activity; import com.ailin.accm.R; import android.content.Context; import android.os.Bundle; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentTransaction; import android.view.LayoutInflater; import android.view.View; import android.view.View.OnClickListener; import android.view.ViewGroup; import android.widget.TextView; public class Fragment1 extends Fragment { private Context context; public Fragment1(Context context) { this.context = context; } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fragment1, null); initView(view); return view; } private void initView(View view) { TextView tv1 = (TextView) view.findViewById(R.id.textView1); tv1.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { Fragment2 fg2 = new Fragment2(context); FragmentTransaction fragmentTrans = getFragmentManager().beginTransaction(); fragmentTrans.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN); fragmentTrans.add(R.id.container, fg2, "fg2"); fragmentTrans.addToBackStack(null); fragmentTrans.commit(); } }); } }
从上面可以看出,在线性布局container中,fragment2作为一个view,被依container依次给addview进去了。那么,如果container换成相对布局呢?又会是什么样子?
可以看出,这个时候,在点击textview1的话,fragment2,就会覆盖fragment1.
PS:补充说明一下,container在添加fragment2 作为view的时候,会进行一次重绘。所以,在设置fragment2.xml的时候,最好使用相对布局RelativeLayout .否则,你的fragment在tab2中能正常显示,但是,拿到fragment1中作为一个view添加上去了,是按照绝对大小来添加的。给大家看看效果吧。
fragment1 使用相对布局作为容器。 fragment2.xml 中使用线性布局。效果看下图。
但是如果fragment2.xml也换成了相对布局,效果就是第二幅图那样了。
鸣谢:http://blog.csdn.net/forever_crying/article/details/8238863/
借用了一下对方的图。文章也写的很好。