Fragment深层解析与传值

碎片(Fragment)Android 3.0发布出来

简单理解

简单地将它理解为一个控件。

碎片的特点

     1)在其内部维护了自身的生命周期;
     2)只有一个宿主(Activity),离开了宿主就不能生存了;
     3)用于显示页面的一部分内容;

为什么要引入Fragment?

     1)因为Fragment拥有自己的生命周期,可以在其实例中完成这部分的显示与隐藏,因此使得操  作逻辑与Activity分离,降低了 程序之间的耦合性;
     2)Fragment实际上是为了解决平板电脑屏幕过宽,左边出现菜单栏,右边出现内容栏的布局效  果的;

Fragment的使用方式

     [ 1 ]Fragment的静态应用:
            <1>创建一个类继承于Fragment;
    		public class FirstFragment extends Fragment{
}
            <2>编写Fragment的布局文件;
	<?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="#f07"
   		 android:gravity="center"
   		 >
   		 <Button
      		  android:id="@+id/mBtnClick"
      		  android:layout_width="wrap_content"
        	  android:layout_height="wrap_content"
                  android:text="我是Fragment里面的Button"
        	 />
</LinearLayout>
             <3>重写Fragment中的onCreateView方法,通过inflateer来加载布局文件,三个参数分别是  布局id,根,false;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View view=inflater.inflate(R.layout.first_fragment,container,false);
    Log.e("B----------------","我被执行了.......");
    return view;
}
             <4>在需要碎片的布局文件中,可以直接声明一个Fragment,定义name和id。
	<?xml version="1.0" encoding="utf-8"?>
 	 <LinearLayout
   		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:orientation="vertical">
 	  <fragment
    		android:layout_width="match_parent"
   	 	android:layout_height="300dp"
   	 	android:name="com.com.qf.fragment.FirstFragment"
    		android:id="@+id/firstFragment"
   		 >
	</fragment>
	</LinearLayout>
           Fragment中的控件的事件的处理:
          1)可以在Activity中直接通过findViewById来找到并使用;
          2)可以在onCreateView方法中通过view.findViewById()来找到控件并使用;
          3)可以在Fragment中通过获取其上下文然后找到id并使用。

          注意:
         1)Fragment当空间来使用的时候要定义id,否则会报错;
         2)Fragment是在Activity上的,所以在Activity中可以找到Fragment中的控件;
         3)在Fragment中是不包含有宿主的上下文的,我们要是想要获取那个宿主的上下文的话用  getActivity方法;

         生命周期的11个方法:
         1)public void onAttach(Activity activity);这个方法在低版本和高版本都可以用
         2)public void onCreate( Bundle savedInstanceState);用于创建Fragment
         3)public void onStart();可见不能获取焦点
         4)public void onResume();获取焦点,此时碎片是可以进行交互的
         5)public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle  savedInstanceState);绑定 View到Fragment
         6)public void onActivityCreated(Bundle savedInstanceState);当宿主创建完成的时候调用  用来处理碎片的逻辑
         7)public void onPause();不能获取焦点
         8)public void onStop();不可见的方法回调
         9)public void onDestroyView();销毁宿主上的Fragment的View
        10)public void onDestroy();回收Fragment占用的资源
        11)public void onDetach();清除Activity中资源
     [ 2 ]Fragment的动态应用:
	//1、通过上下文获取Fragment的管理者
		FragmentManager manager = getFragmentManager();//app包
	//        getSupportFragmentManager();//v4包
	//2、开启事务
		FragmentTransaction fragmentTransaction = manager.beginTransaction();
	//3、添加Fragment到这个容器中
		fragmentTransaction.replace(R.id.contentPanel,fragment);
	//4、提交事务
	fragmentTransaction.commit();
           .replace方法的作用实际上是先清除容器中的Fragment(remove),然后再添加当前的  Fragment(add)。
           如果每次都是用.replace方法的话,就是每次都要将前一个Fragment删除,再将后一个Fragment  添加上,会造成每次都需 要重新CreateView,那么如果我们连续的切换Fragment的话就会出现卡顿的现  象,因此需要进行优化。
          优化步骤:
          1)判断当前对象是否已经添加到ViewTree里面,如果已经添加了,将当前显示的Fragment给  hide掉,然后在显示已经添 加了的Fragment;如果还没有添加,可以直接通过事务的add方法添加  Fragment。
		private void addContent(Fragment from,Fragment to) {
    	     	FragmentTransaction ft = getFragmentManager().beginTransaction();
            	    if(!to.isAdded()){   //判定那个Fragment是否已经被加载到了那个任务栈里面
              	        ft.add(R.id.contentPanel,to);
           	    }else{
            	        ft.hide(from).show(to);
           	    }
             	        ft.commit();
		    }
          注意:当我们添加进一个Fragment,再向container中添加Fragment的话,前一个Fragment并不  会被kill掉,只是没有显 示。

回退栈

      栈的存储模式:先进后出的存储模式

弹出栈

      ft.popBackStack( );  弹出栈内栈顶的Fragment;
      ft.popBackStack("abc",mod);  弹出栈名为abc的Fragment以上或包含Fragment对象及以上的对  象
      mod=1( );Fragment以上的对象
      mod=0;包含Fragment及以上的对象
      ft.popBackStack(commitId,0);指的是弹出的是指定id以上或者包含Fragment对象及以上的对象
id:ft.commit的返回值
      ft.popBackStackImmediate();实际上弹栈的操作书写后并没有立刻执行,而是放在了Fragment的  队列中,此时调用这个方法就可以立即执行弹栈;
      ft.popBackStackImmediate(commitId,0);立即执行弹栈中指定id的对象
      ft.popBackStackImmediate("",0);立即执行指定tag的对象做弹栈操作

事务

      一系列指令的集合,这一系列的指令要么全部执行,要么都不执行。

传值

      Fragment向Activity传递数据,或项另外一个不相关的Fragment传递对象
     1)定义一个接口回调;
     2)在接口回调中声明一个回调方法;
		public interface MyCallBack{
    		public void click(Fragment fragment,String data);
		}
     3)将接口对象至空;
		MyCallBack mMyCallBack=null;
     4)让Activity实现定义的接口;
		public class FragmentToFragmentActivity extends AppCompatActivity implements FirstFragment.MyCallBack{
    
}
     5)在Fragment的onActivityCreate方法中获取当前实现接口的对象getActivity();

		@Override
		public void onActivityCreated(Bundle savedInstanceState) {
 		   super.onActivityCreated(savedInstanceState);
 		   mMyCallBack= (MyCallBack) getActivity();
 		   getActivity().findViewById(R.id.mBtnClick).setOnClickListener(new View.OnClickListener() {
 	      		  @Override
  	       		  public void onClick(View v) {
 	          	  String result=((TextView)getActivity().findViewById(R.id.text)).getText().toString();
 	         	  Log.e("----------------",result);
	
  			      }
 			   });
		}
     6)在需要回调的位置进行回调。
		@Override
		public void click(Fragment fragment, String data) {
		    FragmentTransaction ft = getFragmentManager().beginTransaction();
		    //第三个参数表示的是一个Tag
		    Bundle mBundle=new Bundle();
		    mBundle.putString("key",data);
		    fragment.setArguments(mBundle);
 		    ft.add(R.id.content,fragment,"second");
    		    ft.commit();
		   }

Fragment向点击之后跳转的Fragment传值

		 public void onActivityCreated(Bundle savedInstanceState) {
    		 super.onActivityCreated(savedInstanceState);
   		 mMyCallBack= (MyCallBack) getActivity();
   		 getActivity().findViewById(R.id.mBtnClick).setOnClickListener(new View.OnClickListener() {
    		    @Override
     		   public void onClick(View v) {
      		      Fragment mFragment=FragmentFactory.getFragment(1);
       		      final FragmentTransaction ft =  getActivity().getFragmentManager().beginTransaction();
         		    Bundle mBundle=new Bundle();
        		    mBundle.putString("key","传递过来了");
        		    mFragment.setArguments(mBundle);
         		    ft.add(R.id.content,mFragment);
        		    ft.commit();

     		   }
    });
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值