Fragment的生命周期以及使用技巧

        Fragment是Activity中的一部分,有自己的生命周期,但是受Activity的生命周期的影响。在onResume()之后,onPause()之前,可以单独操作每个Fragment,比如添加删除它们。在执行Fragment的事务时,可以将事务添加到一个栈中,这个栈被Activity管理,栈中每 一条都是fragment的一次事务,有了这个栈就可以反向的执行Fragment的事务,这样Fragment就可以支持返回键了。

        如果Fragment被添加到了回退栈中,在删除或者是替换的时候它将会stop,如果没有添加,就是destroy销毁。

        Fragment类型:DialogFragment、ListFragment、PreferenceFragment。DialogFragment:显示一个浮动的对话框。使用这个类创建对话框是使用Activity类对话框工具方法之外的另一个不错的选择,因为你可以把fragment对话框并入到由activity管理的fragments后台栈中,允许用户返回到一个已经摒弃的fragment。ListFragment:显示一个由适配器管理的条目列表(例如SimpleCursorAdapter),类似于ListActivity。并且提供了许多管理列表视图的函数,例如处理点击事件的onListItemClick()回调函PreferenceFragment:显示一个Preference对象的体系结构列表,类似于preferenceActivity。这在为应用程序创建“设置”activity时是很实用的。
        你还可以使用FragmentManager打开一个FragmentTransaction来执行fragment的事务,比如添加或删除fragment。如果你添加了多个fragment,那么它们的显示顺序跟添加顺序一至(后显示的覆盖前面的)。如果你在执行的事务中有删除fragment的动作,而且没有调用addToBackStack(),那么当事务提交时,那些被删除的fragment就被销毁了。反之,那些fragment就不会被销毁,而是处于停止状态。当用户返回时,它们会被恢复。
        密技:对于fragment事务,你可以应用动画。在commit()之前调用setTransition()就行。但是,调用commit()后,事务并不会马上执行。它会在activity的UI线程(其实就是主线程)中等待直到线程能执行的时候才执行(废话)。如果必要,你可以在UI线程中调用executePendingTransactions()方法来立即执行事务。但一般不需这样做,除非有其它线程在等待事务的执行。
        警告:你只能在activity处于可保存状态的状态时,比如running中,onPause()方法和onStop()方法中提交事务,否则会引发异常。这是因为fragment的状态会丢失。如果要在可能丢失状态的情况下提交事务,请使用commitAllowingStateLoss()。
 Fragment的生命周期

       

Fragment的生命周期与Activity生命周期的比较:

         

Fragment 生命周期代码:

package com.kayak.fragmentstudy;

import android.app.Activity;
import android.graphics.Color;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.text.Spannable;
import android.text.SpannableStringBuilder;
import android.text.style.ForegroundColorSpan;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.Toast;

public class FragmentTest extends Fragment implements OnClickListener,android.support.v4.app.FragmentManager.OnBackStackChangedListener{

	public MainActivity2 activity;

	/* (non-Javadoc)
	 * 当Fragment附加到父窗口Activity上时,也就是成为Activity一部分的时候
	 * 可以获取到父Activity的实例
	 * @see android.support.v4.app.Fragment#onAttach(android.app.Activity)
	 */
	@Override
	public void onAttach(Activity activity) {
		// TODO Auto-generated method stub
		super.onAttach(activity);		
		this.activity = (MainActivity2) activity;
		mCallBack = (onHeadlineSelectedListener) activity;
	}
	
	onHeadlineSelectedListener mCallBack;
	private String mdString;
	private Button bcs;
	private String data;
	//为了实现两个Fragment的交互,可以在fragment中定义一个接口,
	//然后在这个接口中定义一个方法,在Fragment的onAffach()方法中调用这个接口
	//中的方法,然后让Activity实现这个方法来完成Activity和Fragment之间
	//的通信
	public interface onHeadlineSelectedListener{		
		public void onArticleSelected(int position);
	}
	
	/* (non-Javadoc)
	 * 在创建fragment时系统会调用此方法。在实现代码中,你可以初始化想要在
	 * fragment中保持的那些必要组件(这里的组件是指除了view之外的东西,比如需要进行界面展示的关键数据),
	 * 当fragment处于暂停或者停止状态之后可重新启用它们。
	 * @see android.support.v4.app.Fragment#onCreate(android.os.Bundle)
	 */
	@Override
	public void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		//初始化Fragment
		super.onCreate(savedInstanceState);
		if (getArguments() != null) {
			data = getArguments().getString("data");
		}
	}

	public static FragmentTest newInstance(int id) {
		FragmentTest fragmentTest = new FragmentTest();
		Bundle bundle = new Bundle();
		bundle.putString("data",id+"");
		fragmentTest.setArguments(bundle);
		return fragmentTest;
	}
	
	/* (non-Javadoc)
	 * 在第一次为fragment绘制用户界面时系统会调用此方法。为fragment绘制用户界面,这个函数必须
	 * 要返回所绘出的fragment的根View。如果fragment没有用户界面可以返回空
	 * 注:如果你的fragment是从ListFragment中派生的,就不需要实现onCreateView()方法了,
	 * 因为默认的实现已经为你返回了ListView控件对象。
	 *  onCreateView()参数中的container是存放fragment的layout的ViewGroup对象。
	 * @see android.support.v4.app.Fragment#onCreateView(android.view.LayoutInflater, android.view.ViewGroup, android.os.Bundle)
	 */
	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container,
			Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onCreateView(inflater, container, savedInstanceState);
		
		Bundle bundle = getArguments();
		mdString = bundle.getString("md");
		Toast.makeText(getActivity(), mdString, Toast.LENGTH_SHORT).show();
		return inflater.inflate(R.layout.fragmenttest, null);
	}
	
	/* (non-Javadoc)
	 * 操作fragment的View
	 * @see android.support.v4.app.Fragment#onViewCreated(android.view.View, android.os.Bundle)
	 */
	@Override
	public void onViewCreated(View view, Bundle savedInstanceState) {
		super.onViewCreated(view, savedInstanceState);
		bcs = (Button) view.findViewById(R.id.bcs);
		bcs.setOnClickListener(this);
	}
	
	/* (non-Javadoc)
	 * 当父Activity和当前的Fragment的UI都完整创建完的时候被调用
	 * 初始化那些你需要你的父Activity或者是Fragment的UI已经被完整初始化才能初始化的元素
	 * @see android.support.v4.app.Fragment#onActivityCreated(android.os.Bundle)
	 */
	@Override
	public void onActivityCreated(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onActivityCreated(savedInstanceState);
	}
	
	/* (non-Javadoc)
	 * 开始
	 * @see android.support.v4.app.Fragment#onStart()
	 */
	@Override
	public void onStart() {
		// TODO Auto-generated method stub
		super.onStart();
	}
	
	/* (non-Javadoc)
	 * 重新开始
	 * @see android.support.v4.app.Fragment#onResume()
	 */
	@Override
	public void onResume() {
		// TODO Auto-generated method stub
		super.onResume();
	}
	
	/* (non-Javadoc)
	 * 清除所有资源包括要结束的线程,关闭数据库连接等等
	 * @see android.support.v4.app.Fragment#onDestroy()
	 */
	@Override
	public void onDestroy() {
		// TODO Auto-generated method stub
		super.onDestroy();
	}

	/* (non-Javadoc)
	 * 当你的Fragment的UI被分离的时候、清除所有和视图有关的资源
	 * @see android.support.v4.app.Fragment#onDestroyView()
	 */
	@Override
	public void onDestroyView() {
		// TODO Auto-generated method stub
		super.onDestroyView();
	}

	/* (non-Javadoc)
	 * 当你的Fragment从父activity身上分离的时候
	 * @see android.support.v4.app.Fragment#onDetach()
	 */
	@Override
	public void onDetach() {
		// TODO Auto-generated method stub
		super.onDetach();
	}

	/* (non-Javadoc)
	 * 系统回调用该函数作为用户离开fragment的第一个预兆
	 * (尽管这并不总意味着fragment被销毁)。在当前用户会话结束之前
	 * ,通常要在这里提交任何应该持久化的变化(因为用户可能不再返回)。
	 * @see android.support.v4.app.Fragment#onPause()
	 */
	@Override
	public void onPause() {
		// TODO Auto-generated method stub
		super.onPause();
	}

	@Override
	public void onStop() {
		// TODO Auto-generated method stub
		super.onStop();
	}

	@Override
	public void onSaveInstanceState(Bundle outState) {
		super.onSaveInstanceState(outState);
	}
	
	public void sc() {
		bcs.setText("nishiwode");
	}
	
	@Override
	public void onClick(View v) {
		switch (v.getId()) {
		case R.id.bcs:
			
			SpannableStringBuilder style=new SpannableStringBuilder("CS");   
	        style.setSpan(new ForegroundColorSpan(Color.RED),0,1,Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);   
	        bcs.setText(style);
			
			mCallBack.onArticleSelected(1);
			
			activity.chReplaceFrag(new FragmentTestSecond()	, "", true);
			
			FragmentManager vFragmentManager = getFragmentManager();
			//获取App中Fragment管理器 API最低是11
			//android.app.FragmentManager aFragmentManager = getFragmentManager();
			FragmentTransaction vTransaction = vFragmentManager.beginTransaction();
			FragmentTestSecond fragmentTest = new FragmentTestSecond();
			vTransaction.replace(R.id.flt, fragmentTest);
			//vFragmentManager.popBackStack();
			//设置可以点击返回键、在后退栈中保存被代替的fragment的状态。
			//如果你向事务添加了多个动作,比如多次调用了add(),remove()等之后又调用了addToBackStack()方法,那么所有的在commit()之前调用的方法都被作为一个事务。当用户按返回键时,所有的动作都被反向执行(事务回溯)。
			vTransaction.addToBackStack(null);
			//添加返回键的监听
			vFragmentManager.addOnBackStackChangedListener(this);
			//应用动画
			vTransaction.setTransition(1);			
			//提交事务
			//vTransaction.commit();			
			//提交可以丢失的提交
			//vTransaction.commitAllowingStateLoss();
			
			break;

		default:
			break;
		}
	}

	//点击返回键的监听
	@Override
	public void onBackStackChanged() {
		// TODO Auto-generated method stub
	}
	
}

Fragment 生命周期测试例子:

1.切换到Fragment是调用的6个方法: onAttach、onCreate、onCreateView、onActivityCreated、onStart、onResume
2.屏幕灭掉Fragment调用的3个方法:onPause、onSaveInstanceState、onStop(调用生命周期的2个方法)
3.屏幕解锁Fragment调用的2个方法:onStart、onResume
4.切换到其他Fragment调用的3个方法:onPause、onStop、onDestroyView
5.切换回本身的Fragment调用的4个方法:onCreateView、onActivityCreated、onStart、onResume
6.回到桌面调用的3个方法:onPause、onSaveInstanceState、onStop(调用生命周期的2个方法)
7.回到应用:onStart、onResume
8.退出应用: onPause、onStop、onDestroyView、onDestroy、onDetach

 FragmentManager整理:
1.findFragmentById()或findFragmentByTag(),获取activity中已存在的fragment
2.将fragment从后台堆栈中弹出, 使用 popBackStack() (模拟用户按下BACK 命令).
3.通过addOnBackStackChangedListerner()注册一个侦听器以监视后退栈的变化

 FragmentTransaction整理:每一个事务都是要同时执行的一套变化
1.addToBackStack() 添加回滚,这里回滚的是一套变化
2.commit 并不是马上执行,可以从你的UI线程(主线程)调用 vFragmentManager.executePendingTransactions();来立即执行, 需要在用户离开Activity之前执行事务。这 是因为如果activity需要被恢复, 提交之后的状态可能会丢失. 对于你觉得可以丢失提交的状况, 使用 commitAllowingStateLoss().

1.add (多层)是把fragment 添加到container容器
2.replace (单层)是先remove掉相同id的所有fragment,然后在add当前的这个fragment。
3.一般是使用FrameLayout来做容器的
4.使用hide()方法只是隐藏了fragment的view并没有将view从viewtree中删除,随后可用show()方法将view设置为显示

Fragment与Activity的交互,通过接口回调的方式实现

package com.example.jh;

import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.widget.Toast;

import com.example.jh.FragmentTest.onHeadlineSelectedListener;

public class MainActivity extends FragmentActivity implements onHeadlineSelectedListener{

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		FragmentManager manager = getSupportFragmentManager();
		FragmentTransaction transaction = manager.beginTransaction();
		transaction.replace(R.id.fl, new FragmentTest());
		transaction.commit();
	}

	@Override
	public void onArticleSelected(int position) {
		//这里的position就是FragmentTest传过来的数据
		//可以用来交互
		int num = position;
		Toast.makeText(this, ""+num, 0).show();
	}
	
}

package com.example.jh;

import android.app.Activity;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

public class FragmentTest extends Fragment{
	
	onHeadlineSelectedListener mhsl;
	@Override
	public void onAttach(Activity activity) {
		// TODO Auto-generated method stub
		super.onAttach(activity);
		mhsl = (onHeadlineSelectedListener) activity;
	}

	@Override
	public void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);
		//这里可以传递数据到activity
		mhsl.onArticleSelected(10);
	}
	
	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container,
			Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		View view = inflater.inflate(R.layout.fragment_test, null);		
		return view;
	}
	
	//为了实现两个Fragment的交互,可以在fragment中定义一个接口,
	//然后在这个接口中定义一个方法,在Fragment的onAttach()方法中调用这个接口
	//中的方法,然后让Activity实现这个方法来完成Activity和Fragment之间
	//的通信
	public interface onHeadlineSelectedListener{		
		public void onArticleSelected(int position);
	}
	
}

源码下载地址
           

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
是的,使用`lifecycle`库可以更方便地管理`fragment`的生命周期。通过`lifecycle`库,我们可以将`fragment`的生命周期与宿主`Activity`的生命周期进行绑定,这样就可以在`Activity`的生命周期发生变化时,自动调用`fragment`的对应生命周期方法,从而更好地管理`fragment`的状态。 具体来说,我们可以通过以下步骤来使用`lifecycle`库进行`fragment`的生命周期管理: 1. 在`build.gradle`文件中添加`lifecycle`库的依赖: ``` implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0' ``` 2. 在`fragment`中实现`LifecycleOwner`接口,并将`getLifecycle()`方法返回`Lifecycle`对象: ``` public class MyFragment extends Fragment implements LifecycleOwner { private LifecycleRegistry mLifecycleRegistry = new LifecycleRegistry(this); @NonNull @Override public Lifecycle getLifecycle() { return mLifecycleRegistry; } // ... } ``` 3. 在`fragment`中使用`LifecycleRegistry`对象来管理生命周期状态的变化: ``` public class MyFragment extends Fragment implements LifecycleOwner { private LifecycleRegistry mLifecycleRegistry = new LifecycleRegistry(this); @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_CREATE); } @Override public void onStart() { super.onStart(); mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_START); } @Override public void onResume() { super.onResume(); mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_RESUME); } // ... @Override public void onDestroy() { super.onDestroy(); mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_DESTROY); } } ``` 通过这样的方式,我们就可以更方便地管理`fragment`的生命周期,避免出现一些生命周期相关的问题。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值