当我们导入Fragment的时候,一般有两个包可以选择,一个是android.app.Fragment,一个是 android.support.v4.app.Fragment。建议使用v4包中的Fragment,因为它可以在所有 android版本中保持一致。比如Fragment嵌套Fragment这个功能在 android4.2以后才开始支持,所以如果使用内置的Fragment,Android 4.2之前的设备,会崩溃。
四.添加到Viewgroup中
Fragment的生命周期

onAttach()。 当碎片和活动建立关联的时候调用
onCreateView()。 为碎片创建视图(加载布局)时调用
onActivityCreated()。 确保与碎片相关联的活动一定已经创建完毕的时候调用
onDestoryView()。 当与碎皮那关联的视图被移除的时候调用
onDetach()。 当碎片和活动解除关联的时候调用
添加Fragment到Activity中
有两种方法,一种是静态添加,直接将Fragment添加到Activity的布局中,一种是动态添加,添加到Activity的代码中。
新建MyFragment.java和fragment_my.xml文件
MyFragment.java文件如下:
- public class MyFragment extends Fragment {
- @Nullable
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
- View view = inflater.inflate(R.layout.fragment_my, container, false);
- return view;
- }
- }
public class MyFragment extends Fragment {
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_my, container, false);
return view;
}
}fragment_my.xml文件
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:background="#FF0000"
- android:gravity="center"
- android:orientation="vertical">
- <TextView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="这是fragment"/>
- </LinearLayout>
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#FF0000"
android:gravity="center"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="这是fragment"/>
</LinearLayout>
1.静态添加
在Activity的布局中,添加如下标签:
- <fragment
- android:id="@+id/fragment_my"
- android:name="njj.fragment.MyFragment"
- class="njj.fragment.MyFragment1"
- android:layout_width="match_parent"
- android:layout_height="match_parent"/>
<fragment
android:id="@+id/fragment_my"
android:name="njj.fragment.MyFragment"
class="njj.fragment.MyFragment1"
android:layout_width="match_parent"
android:layout_height="match_parent"/>有两种方式,指定name属性,或者class属性,存在一个就可以,将fragment的完整类名写进去。如果class和name属性同时存在,将会以class属性为准。
2.动态添加
首先在Activity布局中,添加一个按钮,一个LinearLayout布局,布局主要是用来存放Fragment的容器,给布局指定id
- <?xml version="1.0" encoding="utf-8"?>
- <RelativeLayout
- 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:paddingBottom="@dimen/activity_vertical_margin"
- android:paddingLeft="@dimen/activity_horizontal_margin"
- android:paddingRight="@dimen/activity_horizontal_margin"
- android:paddingTop="@dimen/activity_vertical_margin"
- tools:context="njj.fragment.MainActivity">
- <Button
- android:id="@+id/addBtn"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:text="add Fragment"/>
- <LinearLayout
- android:id="@+id/fragment_rl"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:layout_below="@+id/addBtn"
- android:orientation="vertical"/>
- </RelativeLayout>
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
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:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="njj.fragment.MainActivity">
<Button
android:id="@+id/addBtn"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="add Fragment"/>
<LinearLayout
android:id="@+id/fragment_rl"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@+id/addBtn"
android:orientation="vertical"/>
</RelativeLayout>然后,点击按钮,调用如下:
- mAddBtn.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View view) {
- // 第一步:通过FragmentManager获得FragmentTransaction实例
- FragmentManager fragmentManager = getSupportFragmentManager();
- FragmentTransaction transaction = fragmentManager.beginTransaction();
- // 第二步:调用add()方法,将Fragment对象添加到指定的布局id上。
- MyFragment myFragment = new MyFragment();
- transaction.add(R.id.fragment_rl, myFragment);
- // 第三步:调用commit()方法,提交,生效
- transaction.commit();
- }
- });
mAddBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
// 第一步:通过FragmentManager获得FragmentTransaction实例
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction transaction = fragmentManager.beginTransaction();
// 第二步:调用add()方法,将Fragment对象添加到指定的布局id上。
MyFragment myFragment = new MyFragment();
transaction.add(R.id.fragment_rl, myFragment);
// 第三步:调用commit()方法,提交,生效
transaction.commit();
}
});
理解了几个类的含义和使用步骤后,完善的写法如下:
- FragmentManager fragmentManager = getSupportFragmentManager();
- myFragment1 = (MyFragment1) fragmentManager.findFragmentById(R.id.fragment_rl2);
- if (myFragment1 == null) {
- myFragment1 = new MyFragment1();
- fragmentManager.beginTransaction().add(R.id.fragment_rl2, myFragment1).commit();
- }
FragmentManager fragmentManager = getSupportFragmentManager();
myFragment1 = (MyFragment1) fragmentManager.findFragmentById(R.id.fragment_rl2);
if (myFragment1 == null) {
myFragment1 = new MyFragment1();
fragmentManager.beginTransaction().add(R.id.fragment_rl2, myFragment1).commit();
}1.为什么需要判null?
是因为当Activity因为配置发生改变(屏幕旋转)或者内存不足被系统杀死,造成重新创建时,我们的fragment会被保存下来,但是会创建新的FragmentManager,新的FragmentManager会首先去获取保存下来的fragment队列,重建fragment队列,从而回复之前的状态。
2.add(id,fragment)中的id有何用
一方面是告诉FragmentManager,此fragment应该放的位置,其次,以后可以通过findFragmentById(id)来查找。
删除、替换、隐藏、显示
Fragment的添加、删除、替换、隐藏,显示,都是借助FragmentTransaction来完成的,所有对Fragment的改动,都需要调用commit()来提交。
- /**
- * 删除Fragment实例
- */
- transaction.remove(myFragment);
- /**
- * 替换Fragment实例。执行更换的布局id,指定将要更换的Fragment实例
- */
- transaction.replace(R.id.fragment_rl, myFragment)
- transaction.replace(R.id.fragment_rl1, myFragment1, "MF1");
- // 当指明了fragment的tag时,可以通过findFragmentByTag来得到Fragment的实例
- MyFragment1 fragment1 = (MyFragment1) fragmentManager.findFragmentByTag("MF1");
- /**
- * 隐藏Fragment实例
- */
- transaction.hide(myFragment);
- /**
- * 显示Fragment实例
- */
- transaction.show(myFragment);
/**
* 删除Fragment实例
*/
transaction.remove(myFragment);
/**
* 替换Fragment实例。执行更换的布局id,指定将要更换的Fragment实例
*/
transaction.replace(R.id.fragment_rl, myFragment)
transaction.replace(R.id.fragment_rl1, myFragment1, "MF1");
// 当指明了fragment的tag时,可以通过findFragmentByTag来得到Fragment的实例
MyFragment1 fragment1 = (MyFragment1) fragmentManager.findFragmentByTag("MF1");
/**
* 隐藏Fragment实例
*/
transaction.hide(myFragment);
/**
* 显示Fragment实例
*/
transaction.show(myFragment);BackStack(回退栈)
调用addToBackStack()保存当前事务,当用户按下返回键,如果回退栈中保存之前的事务,便会执行事务回退,而不是执行activity的finish()。
transaction.addToBackStack(null);
在事务提交之前,调用addToBackStack()方法,就ok了。
获取FragmentManager的方法区别:
getFragmentManager(); // 3.0版本之前没有fragment的api所以要借用v4的getSupportFragmentManager()来使用。
getSupportFragmentManager(); // v4包的使用方式
getChildFragmentManager(); // 前面两个只使用Activity嵌套一级Fragment,如果Fragment里面嵌套二级甚至三级Fragment,就必须使用此方法。
Fragment通讯
1.Activity->Fragment
当我们需要通过Activity向Fragment传递数据时,可以使用Bundle和Arguments来实现,首先,在Activity中创建Fragment的时候,用Bundle绑定数据,
- public MyFragment getFragmentInstance() {
- Bundle bundle = new Bundle();
- bundle.putString("extra", "info");
- if (myFragment == null) {
- myFragment = new MyFragment();
- myFragment.setArguments(bundle);
- }
- return myFragment;
- }
public MyFragment getFragmentInstance() {
Bundle bundle = new Bundle();
bundle.putString("extra", "info");
if (myFragment == null) {
myFragment = new MyFragment();
myFragment.setArguments(bundle);
}
return myFragment;
}然后在Fragment的onCreateView中将数据取出
- public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
- Bundle bundle = getArguments();
- if (bundle != null) {
- Log.i("niejianjian", " -> extra -> " + bundle.getString( "extra"));
- }
- View view = inflater.inflate(R.layout.fragment_my, container, false);
- return view;
- }
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
Bundle bundle = getArguments();
if (bundle != null) {
Log.i("niejianjian", " -> extra -> " + bundle.getString("extra"));
}
View view = inflater.inflate(R.layout.fragment_my, container, false);
return view;
}
2.Fragment->Activity
Fragment的操作想要传递到Activity,一般是使用回调的方式。
首先在Fragment中定义一个接口,用于在Activity回调:
- // 存放该Fragment的Activity必须实现此接口,否则报错。
- public interface OnFragmentBtnClickListener {
- void showToast(String text);
- }
// 存放该Fragment的Activity必须实现此接口,否则报错。
public interface OnFragmentBtnClickListener {
void showToast(String text);
}在Fragment中创建该接口,并且将实现我们接口的Activity,也就是存放该Fragment的Activity,强转为Listener,进行实例化。
- OnFragmentBtnClickListener listener;
- @Override
- public void onAttach(Context context) {
- Log.i("niejianjian", " -> onAttach -> ");
- super.onAttach(context);
- try {
- listener = (OnFragmentBtnClickListener) getActivity();
- } catch (ClassCastException e) {
- Log.i("niejianjian", " -> activity must implement OnFragmentBtnClickListener -> ");
- }
- }
OnFragmentBtnClickListener listener;
@Override
public void onAttach(Context context) {
Log.i("niejianjian", " -> onAttach -> ");
super.onAttach(context);
try {
listener = (OnFragmentBtnClickListener) getActivity();
} catch (ClassCastException e) {
Log.i("niejianjian", " -> activity must implement OnFragmentBtnClickListener -> ");
}
}然后在需要执行操作的地方,调用接口的方法
listener.showToast("Fragment Btn Click!!!");最后在Activity中实现我们的接口,以及方法就OK了
- @Override
- public void showToast(String text) {
- Log.i("niejianjian", "Activity -> showToast -> " + text);
- }
@Override
public void showToast(String text) {
Log.i("niejianjian", "Activity -> showToast -> " + text);
}
3.Fragment <-> Fragment
方法一:首先我们获得宿主Activity的FragmentManager,然后用findFragmentById来根据id获取到另外一Fragment对象,然后调用其方法
- MyFragment1 fragment1 = (MyFragment1) getActivity().getSupportFragmentManager().findFragmentById(R.id.fragment_rl2);
- fragment1.setTextMethod();
MyFragment1 fragment1 = (MyFragment1) getActivity().getSupportFragmentManager().findFragmentById(R.id.fragment_rl2);
fragment1.setTextMethod();方法二:还是通过以宿主Activity为媒介,通过回调的方法,先将Fragment的信息传入到Activity,在从Activity调用另外一个Fragment的方法。
方法三,通过广播或者事件总线来实现。
Fragment常遇到的坑
1.getActivity()空指针
当系统内存不足时,回收了当前的的宿主Activity。如果我们在Fragment中执行异步操作,当执行完毕后,调用getActivity(),必然是会返回null。
解决方法就是在Fragment中定义一个全局变量Activity,然后使用mActivity代替getActivity(),这样就可以保证Fragment即使在onDetach后,还持有Activity的引用,不过这样会造成内存泄漏。
- protected Activity mActivity;
- @Override
- public void onAttach(Activity activity) {
- super.onAttach(activity);
- this.mActivity = activity;
- }
- /**
- * 如果你用了support 23的库,上面的方法会提示过时,有强迫症的小伙伴,可以用下面的方法代替
- */
- @Override
- public void onAttach(Context context) {
- super.onAttach(context);
- this.mActivity = (Activity)context;
protected Activity mActivity;
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
this.mActivity = activity;
}
/**
* 如果你用了support 23的库,上面的方法会提示过时,有强迫症的小伙伴,可以用下面的方法代替
*/
@Override
public void onAttach(Context context) {
super.onAttach(context);
this.mActivity = (Activity)context;
ViewPager + Fragment使用
任意创建一个Fragment
- public class MyFragment0 extends Fragment {
- @Nullable
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
- View view = inflater.inflate(R.layout.fragment_my0, container, false);
- return view;
- }
- }
public class MyFragment0 extends Fragment {
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_my0, container, false);
return view;
}
}然后将其多复制几个,用于添加到ViewPager上。
在Activity的布局中添加Viewpager控件
- <?xml version="1.0" encoding="utf-8"?>
- <RelativeLayout
- 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"
- tools:context="njj.fragment.MainActivity">
- <android.support.v4.view.ViewPager
- android:id="@+id/viewpager"
- android:layout_width="match_parent"
- android:layout_height="match_parent"/>
- </RelativeLayout>
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
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"
tools:context="njj.fragment.MainActivity">
<android.support.v4.view.ViewPager
android:id="@+id/viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</RelativeLayout>
最后在Activity中实现,将Fragment添加到ViewPager中
- package njj.fragment;
- import android.os.Bundle;
- import android.support.v4.app.Fragment;
- import android.support.v4.app.FragmentManager;
- import android.support.v4.app.FragmentPagerAdapter;
- import android.support.v4.view.ViewPager;
- import android.support.v7.app.AppCompatActivity;
- import android.view.ViewGroup;
- import android.view.Window;
- import java.util.ArrayList;
- import java.util.List;
- public class MainActivity extends AppCompatActivity {
- private ViewPager mViewPager;
- private List<Fragment> mFragmentList;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- requestWindowFeature(Window.FEATURE_NO_TITLE);
- setContentView(R.layout.activity_main);
- mFragmentList = new ArrayList<>();
- mFragmentList.add(new MyFragment0());
- mFragmentList.add(new MyFragment1());
- mFragmentList.add(new MyFragment2());
- mFragmentList.add(new MyFragment3());
- mViewPager = (ViewPager) findViewById(R.id.viewpager);
- mViewPager.setAdapter(new MyPagerAdapter(getSupportFragmentManager()));
- // 预加载的页面数,(前后)默认是1,最少也是1,设置0,也是1
- mViewPager.setOffscreenPageLimit(1);
- }
- class MyPagerAdapter extends FragmentPagerAdapter {
- public MyPagerAdapter(FragmentManager fm) {
- super(fm);
- }
- @Override
- public Fragment getItem(int position) {
- return mFragmentList.get(position);
- }
- @Override
- public int getCount() {
- return mFragmentList.size();
- }
- /**
- * 页面更新后调用此方法。可以用于处理tab视图的切换
- * http://blog.csdn.net/harvic880925/article/details/38487149
- */
- @Override
- public void finishUpdate(ViewGroup container) {
- super.finishUpdate(container);
- // Log.i("niejianjian"," -> ->" + mViewPager.getCurrentItem());
- }
- }
- }
package njj.fragment;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.view.ViewGroup;
import android.view.Window;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity {
private ViewPager mViewPager;
private List<Fragment> mFragmentList;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_main);
mFragmentList = new ArrayList<>();
mFragmentList.add(new MyFragment0());
mFragmentList.add(new MyFragment1());
mFragmentList.add(new MyFragment2());
mFragmentList.add(new MyFragment3());
mViewPager = (ViewPager) findViewById(R.id.viewpager);
mViewPager.setAdapter(new MyPagerAdapter(getSupportFragmentManager()));
// 预加载的页面数,(前后)默认是1,最少也是1,设置0,也是1
mViewPager.setOffscreenPageLimit(1);
}
class MyPagerAdapter extends FragmentPagerAdapter {
public MyPagerAdapter(FragmentManager fm) {
super(fm);
}
@Override
public Fragment getItem(int position) {
return mFragmentList.get(position);
}
@Override
public int getCount() {
return mFragmentList.size();
}
/**
* 页面更新后调用此方法。可以用于处理tab视图的切换
* http://blog.csdn.net/harvic880925/article/details/38487149
*/
@Override
public void finishUpdate(ViewGroup container) {
super.finishUpdate(container);
// Log.i("niejianjian"," -> ->" + mViewPager.getCurrentItem());
}
}
}此时,ViewPager + Fragment的简单实用就大功告成了。
ViewPager设置的Adapter有两种,分别是FragmentPagerAdapter和FragmentStatePagerAdapter,这两个的区别如下。
FragmentPagerAdapter:对于不再需要的Fragment,仅仅只会调用onDestoryView方法,也就是至销毁视图不销毁Fragment,所以不会执行onDetach方法。
FragmentStatePagerAdapter:会销毁不再需要的Fragment,一直调用到onDetach方法,将Activity和Fragment解绑。销毁时,会调用onSaveInstanceState(Bundle bundle)方法通过bundle将信息保存下来,当用户切换回来,可以通过bundle恢复生成新的fragment,也就是说,我们可以在onSaveInstanceState方法中保存一些数据,在onCreate中进行恢复创建。
不再需要的Fragment并不是不可见的Fragment,是否需要,要根据ViewPager当前显示哪个Fragment和Viewpager的setOffscreenPageLimit()方法设置的limit来共同决定的。
我们用声明周期来说明这些。我们将四个Fragment都实现声明周期方法:
- public class MyFragment0 extends Fragment {
- @Nullable
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
- Log.i("niejianjian","MyFragment0 -> onCreateView ->");
- View view = inflater.inflate(R.layout.fragment_my0, container, false);
- return view;
- }
- @Override
- public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
- super.onViewCreated(view, savedInstanceState);
- Log.i("niejianjian","MyFragment0 -> onViewCreated ->");
- }
- @Override
- public void onAttach(Context context) {
- super.onAttach(context);
- Log.i("niejianjian","MyFragment0 -> onAttach ->");
- }
- @Override
- public void onCreate(@Nullable Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- Log.i("niejianjian","MyFragment0 -> onCreate ->");
- }
- @Override
- public void onActivityCreated(@Nullable Bundle savedInstanceState) {
- super.onActivityCreated(savedInstanceState);
- Log.i("niejianjian","MyFragment0 -> onActivityCreated ->");
- }
- @Override
- public void onStart() {
- super.onStart();
- Log.i("niejianjian","MyFragment0 -> onStart ->");
- }
- @Override
- public void onResume() {
- super.onResume();
- Log.i("niejianjian","MyFragment0 -> onResume ->");
- }
- @Override
- public void onPause() {
- super.onPause();
- Log.i("niejianjian","MyFragment0 -> onPause ->");
- }
- @Override
- public void onStop() {
- super.onStop();
- Log.i("niejianjian","MyFragment0 -> onStop ->");
- }
- @Override
- public void onDestroyView() {
- super.onDestroyView();
- Log.i("niejianjian","MyFragment0 -> onDestroyView ->");
- }
- @Override
- public void onDetach() {
- super.onDetach();
- Log.i("niejianjian","MyFragment0 -> onDetach ->");
- }
- }
public class MyFragment0 extends Fragment {
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
Log.i("niejianjian","MyFragment0 -> onCreateView ->");
View view = inflater.inflate(R.layout.fragment_my0, container, false);
return view;
}
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
Log.i("niejianjian","MyFragment0 -> onViewCreated ->");
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
Log.i("niejianjian","MyFragment0 -> onAttach ->");
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.i("niejianjian","MyFragment0 -> onCreate ->");
}
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
Log.i("niejianjian","MyFragment0 -> onActivityCreated ->");
}
@Override
public void onStart() {
super.onStart();
Log.i("niejianjian","MyFragment0 -> onStart ->");
}
@Override
public void onResume() {
super.onResume();
Log.i("niejianjian","MyFragment0 -> onResume ->");
}
@Override
public void onPause() {
super.onPause();
Log.i("niejianjian","MyFragment0 -> onPause ->");
}
@Override
public void onStop() {
super.onStop();
Log.i("niejianjian","MyFragment0 -> onStop ->");
}
@Override
public void onDestroyView() {
super.onDestroyView();
Log.i("niejianjian","MyFragment0 -> onDestroyView ->");
}
@Override
public void onDetach() {
super.onDetach();
Log.i("niejianjian","MyFragment0 -> onDetach ->");
}
}
当我们设置setOffscreenPageLimit(1)的值为1的时候,当前页面的前后一个页面都是加载的。
启动应用,默认显示的是MyFragment0,生命周期显示如下:
- 12-29 10:38:46.130 25672-25672/njj.fragmeny I/niejianjian: MyFragment0 -> onAttach ->
- 12-29 10:38:46.130 25672-25672/njj.fragmeny I/niejianjian: MyFragment0 -> onCreate ->
- 12-29 10:38:46.130 25672-25672/njj.fragmeny I/niejianjian: MyFragment0 -> onCreateView ->
- 12-29 10:38:46.130 25672-25672/njj.fragmeny I/niejianjian: MyFragment0 -> onViewCreated ->
- 12-29 10:38:46.130 25672-25672/njj.fragmeny I/niejianjian: MyFragment0 -> onActivityCreated ->
- 12-29 10:38:46.130 25672-25672/njj.fragmeny I/niejianjian: MyFragment0 -> onStart ->
- 12-29 10:38:46.130 25672-25672/njj.fragmeny I/niejianjian: MyFragment0 -> onResume ->
- 12-29 10:38:46.130 25672-25672/njj.fragmeny I/niejianjian: MyFragment1 -> onAttach ->
- 12-29 10:38:46.130 25672-25672/njj.fragmeny I/niejianjian: MyFragment1 -> onCreate ->
- 12-29 10:38:46.130 25672-25672/njj.fragmeny I/niejianjian: MyFragment1 -> onCreateView ->
- 12-29 10:38:46.140 25672-25672/njj.fragmeny I/niejianjian: MyFragment1 -> onActivityCreated ->
- 12-29 10:38:46.140 25672-25672/njj.fragmeny I/niejianjian: MyFragment1 -> onStart ->
- 12-29 10:38:46.140 25672-25672/njj.fragmeny I/niejianjian: MyFragment1 -> onResume ->
12-29 10:38:46.130 25672-25672/njj.fragmeny I/niejianjian: MyFragment0 -> onAttach ->
12-29 10:38:46.130 25672-25672/njj.fragmeny I/niejianjian: MyFragment0 -> onCreate ->
12-29 10:38:46.130 25672-25672/njj.fragmeny I/niejianjian: MyFragment0 -> onCreateView ->
12-29 10:38:46.130 25672-25672/njj.fragmeny I/niejianjian: MyFragment0 -> onViewCreated ->
12-29 10:38:46.130 25672-25672/njj.fragmeny I/niejianjian: MyFragment0 -> onActivityCreated ->
12-29 10:38:46.130 25672-25672/njj.fragmeny I/niejianjian: MyFragment0 -> onStart ->
12-29 10:38:46.130 25672-25672/njj.fragmeny I/niejianjian: MyFragment0 -> onResume ->
12-29 10:38:46.130 25672-25672/njj.fragmeny I/niejianjian: MyFragment1 -> onAttach ->
12-29 10:38:46.130 25672-25672/njj.fragmeny I/niejianjian: MyFragment1 -> onCreate ->
12-29 10:38:46.130 25672-25672/njj.fragmeny I/niejianjian: MyFragment1 -> onCreateView ->
12-29 10:38:46.140 25672-25672/njj.fragmeny I/niejianjian: MyFragment1 -> onActivityCreated ->
12-29 10:38:46.140 25672-25672/njj.fragmeny I/niejianjian: MyFragment1 -> onStart ->
12-29 10:38:46.140 25672-25672/njj.fragmeny I/niejianjian: MyFragment1 -> onResume ->我们看到,此时MyFragment1也加载完了,然后我们滑动到第二个页面,也就是显示MyFragment1页面,
- 12-29 10:41:36.970 25672-25672/njj.fragmeny I/niejianjian: MyFragment2 -> onAttach ->
- 12-29 10:41:36.970 25672-25672/njj.fragmeny I/niejianjian: MyFragment2 -> onCreate ->
- 12-29 10:41:36.970 25672-25672/njj.fragmeny I/niejianjian: MyFragment2 -> onCreateView ->
- 12-29 10:41:36.980 25672-25672/njj.fragmeny I/niejianjian: MyFragment2 -> onActivityCreated ->
- 12-29 10:41:36.980 25672-25672/njj.fragmeny I/niejianjian: MyFragment2 -> onStart ->
- 12-29 10:41:36.980 25672-25672/njj.fragmeny I/niejianjian: MyFragment2 -> onResume ->
12-29 10:41:36.970 25672-25672/njj.fragmeny I/niejianjian: MyFragment2 -> onAttach ->
12-29 10:41:36.970 25672-25672/njj.fragmeny I/niejianjian: MyFragment2 -> onCreate ->
12-29 10:41:36.970 25672-25672/njj.fragmeny I/niejianjian: MyFragment2 -> onCreateView ->
12-29 10:41:36.980 25672-25672/njj.fragmeny I/niejianjian: MyFragment2 -> onActivityCreated ->
12-29 10:41:36.980 25672-25672/njj.fragmeny I/niejianjian: MyFragment2 -> onStart ->
12-29 10:41:36.980 25672-25672/njj.fragmeny I/niejianjian: MyFragment2 -> onResume ->此时,第三个页面MyFragment2加载了。然后我们再滑动到第三个页面,也就是显示MyFragment2页面- 12-29 10:42:42.470 25672-25672/njj.fragmeny I/niejianjian: MyFragment0 -> onPause ->
- 12-29 10:42:42.470 25672-25672/njj.fragmeny I/niejianjian: MyFragment0 -> onStop ->
- 12-29 10:42:42.470 25672-25672/njj.fragmeny I/niejianjian: MyFragment0 -> onDestroyView ->
- 12-29 10:42:42.470 25672-25672/njj.fragmeny I/niejianjian: MyFragment3 -> onAttach ->
- 12-29 10:42:42.470 25672-25672/njj.fragmeny I/niejianjian: MyFragment3 -> onCreate ->
- 12-29 10:42:42.470 25672-25672/njj.fragmeny I/niejianjian: MyFragment3 -> onCreateView ->
- 12-29 10:42:42.480 25672-25672/njj.fragmeny I/niejianjian: MyFragment3 -> onActivityCreated ->
- 12-29 10:42:42.480 25672-25672/njj.fragmeny I/niejianjian: MyFragment3 -> onStart ->
- 12-29 10:42:42.480 25672-25672/njj.fragmeny I/niejianjian: MyFragment3 -> onResume ->
12-29 10:42:42.470 25672-25672/njj.fragmeny I/niejianjian: MyFragment0 -> onPause ->
12-29 10:42:42.470 25672-25672/njj.fragmeny I/niejianjian: MyFragment0 -> onStop ->
12-29 10:42:42.470 25672-25672/njj.fragmeny I/niejianjian: MyFragment0 -> onDestroyView ->
12-29 10:42:42.470 25672-25672/njj.fragmeny I/niejianjian: MyFragment3 -> onAttach ->
12-29 10:42:42.470 25672-25672/njj.fragmeny I/niejianjian: MyFragment3 -> onCreate ->
12-29 10:42:42.470 25672-25672/njj.fragmeny I/niejianjian: MyFragment3 -> onCreateView ->
12-29 10:42:42.480 25672-25672/njj.fragmeny I/niejianjian: MyFragment3 -> onActivityCreated ->
12-29 10:42:42.480 25672-25672/njj.fragmeny I/niejianjian: MyFragment3 -> onStart ->
12-29 10:42:42.480 25672-25672/njj.fragmeny I/niejianjian: MyFragment3 -> onResume ->然后我们发现MyFragment3加载完的同时,MyFragment0销毁了。
因为我们设置的setOffscreenPageLimit为1,也就是当前页面的前后1个页面是需要的,不需要的,会执行销毁视图。当我们滑动到第三个页面也就是MyFragment2显示的时候,它的前面是MyFragment1,后面是MyFragment3,此时,MyFragment0是不需要的,所以,它会销毁视图,当我们在滑动回第二个页面(MyFragment1显示)
- 12-29 10:45:46.970 25672-25672/njj.fragmeny I/niejianjian: MyFragment0 -> onCreateView ->
- 12-29 10:45:46.970 25672-25672/njj.fragmeny I/niejianjian: MyFragment0 -> onViewCreated ->
- 12-29 10:45:46.970 25672-25672/njj.fragmeny I/niejianjian: MyFragment0 -> onActivityCreated ->
- 12-29 10:45:46.970 25672-25672/njj.fragmeny I/niejianjian: MyFragment3 -> onPause ->
- 12-29 10:45:46.970 25672-25672/njj.fragmeny I/niejianjian: MyFragment3 -> onStop ->
- 12-29 10:45:46.970 25672-25672/njj.fragmeny I/niejianjian: MyFragment3 -> onDestroyView ->
- 12-29 10:45:46.970 25672-25672/njj.fragmeny I/niejianjian: MyFragment0 -> onStart ->
- 12-29 10:45:46.970 25672-25672/njj.fragmeny I/niejianjian: MyFragment0 -> onResume ->
12-29 10:45:46.970 25672-25672/njj.fragmeny I/niejianjian: MyFragment0 -> onCreateView ->
12-29 10:45:46.970 25672-25672/njj.fragmeny I/niejianjian: MyFragment0 -> onViewCreated ->
12-29 10:45:46.970 25672-25672/njj.fragmeny I/niejianjian: MyFragment0 -> onActivityCreated ->
12-29 10:45:46.970 25672-25672/njj.fragmeny I/niejianjian: MyFragment3 -> onPause ->
12-29 10:45:46.970 25672-25672/njj.fragmeny I/niejianjian: MyFragment3 -> onStop ->
12-29 10:45:46.970 25672-25672/njj.fragmeny I/niejianjian: MyFragment3 -> onDestroyView ->
12-29 10:45:46.970 25672-25672/njj.fragmeny I/niejianjian: MyFragment0 -> onStart ->
12-29 10:45:46.970 25672-25672/njj.fragmeny I/niejianjian: MyFragment0 -> onResume ->此时,又会重新绑定试图。
我们设置FragmentPageAdapter和FragmentStatePageAdapter的区别就是在于,会多执行onAttach和onDetach。使用哪个,根据自己的需求。
懒加载对setuserVisibleHint()进行处理
- @Override
- public void setUserVisibleHint(boolean isVisibleToUser) {
- super.setUserVisibleHint(isVisibleToUser);
- if (getUserVisibleHint()){
- }
- Log.i("niejianjian","MyFragment0 -> isVisibleToUser -> " + isVisibleToUser);
- }
@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
if (getUserVisibleHint()){
}
Log.i("niejianjian","MyFragment0 -> isVisibleToUser -> " + isVisibleToUser);
}
参考连接:
yifeng.studio/2016/12/15/…http://www.jianshu.com/p/662c46cd3b5f
