首页 > 代码库 > Android实习札记(4)---Fragment(碎片)基本概念解析
Android实习札记(4)---Fragment(碎片)基本概念解析
Android实习札记(4)---Fragment(碎片)基本概念解析
转载请注明出处:coder-pig
Fragment相信大家都不会陌生吧,侧滑啦,抽屉效果啦,DialogFragment啊等等,一堆地方都会
用到Fragment,对于Fragment的基本概念在前面的文章中其实已经给出的了,这里回顾一遍,
温故而知新嘛,同时结合Google官方的api进行复习!
1)什么是Fragment以及它的生命周期:
核心要点:
1)3.0版本后引入,即minSdk要大于11
2)Fragment需要嵌套在Activity中使用,当然也可以嵌套到另外一个Fragment中,但这个被嵌套
的Fragment也是需要嵌套在Activity中的,间接地说,Fragment还是需要嵌套在Activity中!!受寄主
Activity的生命周期影响,当然他也有自己的生命周期!另外不建议在Fragment里面嵌套Fragment
因为嵌套在里面的Fragment生命周期不可控!!!
3)官方文档说创建Fragment时至少需要实现三个方法:onCreate( ),onCreateView( ),OnPause( );
不过貌似只写一个onCreateView也是可以的...
4)Fragment的生命周期和Activity有点类似:三种状态:
Resumed:在允许中的Fragment可见 Paused:所在Activity可见,但是得不到焦点
Stoped:
①调用addToBackStack(),Fragment被添加到Bcak栈
②该Activity转向后台,或者该Fragment被替换/删除
ps:停止状态的fragment仍然活着(所有状态和成员信息被系统保持着),然而,它对用户
不再可见,并且如果activity被干掉,他也会被干掉.
5)Fragment的子类有:
对话框:DialogFragment 列表:ListFragment
选项设置:PreferenceFragment WebView界面:WebViewFragment
2)如何去创建一个Fragment?
①静态添加Fragment
step 1:定义Fragment的布局,就是fragment显示内容的
step 2:自定义一个Fragment类,需要继承Fragment或者他的子类,重写onCreateView()方法
在该方法中调用:inflater.inflate()方法加载Fragment的布局文件,接着返回加载的view对象
public class Fragmentone extends Fragment { @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fragment1, container,false); return view; } }
参数依次是:要加载的fragment布局;加载的fragment所在的父ViewGroup;而第三个参数则是:
是否将父ViewGroup添加到布局文件的根视图上,但是这样可能会产生一个多余的ViewGroup
对象;这里不理解的话就算了,写false就可以了
另外inflate方法还有其他的形式,一种典型的就是直接inflate(要显示布局,null),
如果使用这种的话:item布局中的根视图的layout_XX属性会被忽略掉,然后设置成默认的包裹
内容方式,所以还是建议使用三个参数的inflate()吧!详细缘由可参考:
http://www.2cto.com/kf/201407/313054.html
记住,name属性是全限定类名哦,就是要包含Fragment的包名,如:
<fragment android:id="@+id/fragment1" android:name="com.jay.example.fragmentdemo.Fragmentone" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" />step 4:Activity在onCreate( )方法中调用setContentView()加载布局文件即可!
②动态添加Fragment
step 1:调用getFragmentManager获得FragmentManager对象fm
step 2.fm调用beginTransaction( )方法获得Fragment事务对象bt
step 3:bt调用add( )添加或者relpace( )替换Fragment,参数都是一样的
第一个参数是要传入的容器,第二个参数是Fragment对象
step 4:最后还需要调用bt.commit( )提交事务,除了add和replace方法外
还有个remove移除Fragment的方法,同样也是需要commit的!
局部代码:
Fragment1 f1 = new Fragment1(); getFragmentManager().beginTransaction().replace(R.id.LinearLayout1, f1).commit();
ps:这里的代码是app包下的使用fragment,所以导入的与Fragment有关的包都要是app哦!!!
另外为了低版本兼容也可以用v4包,改点东西而已,详细解析请见:
Fragment用app包还是v4包详解
3)Fragment与Activity的交互
①组件获取:
Fragment获得Activity中的组件:
getActivity().findViewById(R.id.list)
Activity获得Fragment中的组件(根据id和tag都可以):
getFragmentManager.findFragmentByid(R.id.fragment1);
②数据传递
1.Activit传递数据给Fragment:
在Activity中创建Bundle数据包,调用Fragment实例的setArguments(bundle)
从而将Bundle数据包传给Fragment,然后Fragment中调用getArguments获得
Bundle对象,然后进行解析就可以了
2.Fragment传递数据给Activity
在Fragment中定义一个内部回调接口,再让包含该Fragment的Activity实现该回调接口,
Fragment就可以通过回调接口传数据了,回调,相信很多人都知道是什么玩意,但是
写不出来啊,网上的一百度"fragment传数据给Activity",全是李刚老师的那个代码,真心无语
算了,这里就写下局部代码吧,相信读者一看就懂的了:
step 1:定义一个回调接口:(Fragment中)
/*接口*/ public interface CallBack{ /*定义一个获取信息的方法*/ public void getResult(String result); }
step 2:接口回调(fragment中)
/*接口回调*/ public void getData(CallBack callBack){ /*获取文本框的信息,当然你也可以传其他类型的参数,看需求咯*/ String msg = editText.getText().toString(); callBack.getResult(msg); }
step 3:使用接口回调方法读数据(Activity中)
/* 使用接口回调的方法获取数据 */ leftFragment.getData(new CallBack() { @Override public void getResult(String result) { /*打印信息*/ Toast.makeText(MainActivity.this, "-->>" + result, 1).show(); } });
总结来说,就是
->在Fragment定义一个接口,接口中定义抽象方法,你要传什么类型的数据
参数就设置为什么类型;
->接着还有写一个调用接口中的抽象方法,把要传递的数据传过去
->再接着就是Activity了,调用Fragment提供的那个方法,然后重写抽象方法的时候进行数据
的读取就可以了!!!
3.Fragment与Fragment传数据
其实这很简单,找到要接受数据的fragment对象,直接调用setArguments传数据进去就可以了
通常的话是replace时,即fragment跳转的时候传数据的,那么只需要在初始化要跳转的Fragment
后调用他的setArguments方法传入数据即可!
大概代码如下:
FragmentManager fManager = getSupportFragmentManager( ); FragmentTransaction fTransaction = fManager.beginTransaction(); Fragmentthree t1 = new Fragmentthree(); Fragmenttwo t2 = new Fragmenttwo(); Bundle bundle = new Bundle(); bundle.putString("key",id); t2.setArguments(bundle); fTransaction.add(R.id.fragmentRoot, t2, "~~~"); fTransaction.addToBackStack(t1); fTransaction.commit();
如果是两个Fragment需要即时传数据,而非跳转的话,就需要先在Activity获得f1传过来的数据,再传
到f2了
4)Fragment管理与Fragment事务:
①管理:
Activity管理Fragment主要依靠FragmentManager可以调用findFragmentById( )获取指定的fragment
也可以调用popBackStack( )方法弹出后台Fragment;也可以调用addToBackStack(null)加入栈
或者监听后台栈的变化:addOnBackStackChangeListener
②事务
如果是增删替换Fragment的话,则需要借助FragmentTransaction对象;
同时执行Fragment的操作后,记得操作完后再使用commit( )方法提交事务哦!
5)最后说几句:
相信上面的生命周期图一时半会你也是记不住的,最后就初略地讲下大概流程吧:
①Activity加载Fragment的时候,依次调用下面的方法:
onAttach -> onCreate -> onCreateView -> onActivityCreated -> onStart ->onResume;
②当我们弄出一个悬浮的对话框风格的Activity,或者其他,就是让Fragment所在的Activity可见,但不获得焦点
onPause
③当对话框关闭,Activity又获得了焦点:
onResume
④当我们替换Fragment,并调用addToBackStack()将他添加到Back栈中
onPause -> onStop -> onDestoryView
注意,此时的Fragment还没有被销毁哦!!!
⑤当我们按下键盘的回退键,Fragment会再次显示出来:
onCreateView -> onActivityCreated -> onStart -> onResume;
⑥如果我们替换后,在事务commit之前没有调用addToBackStack()方法将
Fragment添加到back栈中的话;又或者退出了Activity的话,那么Fragment将会被完全结束,
Fragment会进入销毁状态
onPause -> onStop -> onDestoryView -> onDestory -> onDetach
Android实习札记(4)---Fragment(碎片)基本概念解析