Android Fragment 详解 2016 干货
来源:互联网 发布:美橙域名 编辑:程序博客网 时间:2024/06/01 15:42
最近看了很多动画和一些效果很好的自定义控件,发现了一件事,就是Android的View层设计思想和古老的JavaSwing是如此的相似。这是在原来的基础上加入了一些输入移动端的生命周期,使其在使用和性能上更好。但是对核心的理解还是可以借鉴一些的。
如果说Activity就是JavaSwing的JFrame那么Fragment 就是在JPanel
一个是容器顶层控件,一个是显示在容器上的中间层控件。
所以这里插一句话,如果感觉自己android写的不溜那么就多看看java的代码。和设计思想吧。android的东西太多都是继承自java或者说就是java的衍生品。无论是顶层容器还是底层容器都是为了放交互容器的。
Fragment的使用
一、布局
大家完全可以把Fragment看成一个轻量级的Activity.为什么轻量,因为他不用在mainfest.xml文件中添加自己.第二他不能直接启动,必须依附(attach)在activity之上。
所以在这布局这一块,Fragment的使用完全可以和activity的布局划等号,设计图怎么画在这里就怎么设计一个 Fragment .
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#00ff00" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="This is fragment 1" android:textColor="#000000" android:textSize="25sp" /> </LinearLayout>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#ffff00" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="This is fragment 2" android:textColor="#000000" android:textSize="25sp" /> </LinearLayout>
简单的画了两个布局背景不同,文字区分1和2
二、在Activity中使用
使用方法一:静态加载一个Fragment
第一步把这个 fragment实例化
public class Fragment1 extends Fragment { @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { return inflater.inflate(R.layout.fragment1, container, false); } }
二和一 ,一样
在onCreateView() 中实现的是
{ View view=inflater.inflate(R.layout.fragment);//这个View就是父容器在这个布局里的其他控件 好比TextView要依靠他findViewById(); TextView tv=(TextView)view.findViewById(R.id,textview); return view;}
这样一个 Fragment在View层就创建成功了。
然后打开或新建activity_main.xml作为主Activity的布局文件,在里面加入两个Fragment的引用,使用android:name前缀来引用具体的
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:baselineAligned="false" > <fragment android:id="@+id/fragment1" **android:name="com.example.fragmentdemo.Fragment1"** android:layout_width="0dip" android:layout_height="match_parent" android:layout_weight="1" /> <fragment android:id="@+id/fragment2" **android:name="com.example.fragmentdemo.Fragment2"** android:layout_width="0dip" android:layout_height="match_parent" android:layout_weight="1" /> </LinearLayout>
最后打开或新建MainActivity作为程序的主Activity,里面的代码非常简单,都是自动生成的:
public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } }
如我们的设计一样,两个Fragment平分了屏幕
使用方法二:动态添加
这回我们直接在Activity中使用Fragment
public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Display display = getWindowManager().getDefaultDisplay(); if (display.getWidth() > display.getHeight()) { Fragment1 fragment1 = new Fragment1(); //新建Fragment getFragmentManager().beginTransaction().replace(R.id.main_layout, fragment1).commit(); //添加Fragment提交 } else { Fragment2 fragment2 = new Fragment2(); getFragmentManager().beginTransaction().replace(R.id.main_layout, fragment2).commit(); } } }
首先,我们要获取屏幕的宽度和高度,然后进行判断,如果屏幕宽度大于高度就添加fragment1,如果高度大于宽度就添加fragment2。动态添加Fragment主要分为4步:
1.获取到FragmentManager,在Activity中可以直接通过getFragmentManager得到。
2.开启一个事务,通过调用beginTransaction方法开启。
3.向容器内加入Fragment,一般使用replace方法实现,需要传入容器的id和Fragment的实例。
4.提交事务,调用commit方法提交。
现在运行一下程序,效果如下图所示:
竖屏显示结果
横屏显示结果
在实战中主要使用的是第二种方法使用我们的Fragment.
即底部是三个activity切换按钮上面是三个Fragment这里的,这里对Fragment的使用方法就是使用动态加载的方法。
三、Fragment的生命周期 Fragment 就是一个轻量的Activity那么他的声明周期就和Activity非常像了。
生命周期如下:
1.onAttach() 在Fragment和Activity建立关联的时候调用
2.onCreate() 初始化Fragment本身为inflate view做准备
3.onCreateView() 对布局中的所有控件进行初始化 绑定
4.onActivityCreated
5.onStart
6onResume
在按下home之后
1.onPause 程序挂起
2.onStop 当前activity 停止
在返回程序之后
1.onStart 开始
2.onResume 恢复
点击back退出程序
1onPause
2onStop
3onDestoryView Fragment 的View被移除了。
4onDestory
5onDetach Fragment和Activiy解除关联的时候调用
注:此处并没有onRestart()方法!
三、Fragment通信
这里的通信主要分为
fragment->fragment 通过getActivity()为桥梁进行通信
Activity->fragment
fragment-activity 最简单 所有activity 之间的通信方法这种时候都可以用
如在之前Fragment2中添加一个button那么我们需要调用其他相关的Fragment是如何实现的那。
public class Fragment2 extends Fragment { @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { return inflater.inflate(R.layout.fragment2, container, false); } @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); Button button = (Button) getActivity().findViewById(R.id.button); button.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { TextView textView = (TextView) getActivity().findViewById(R.id.fragment1_text); Toast.makeText(getActivity(), textView.getText(), Toast.LENGTH_LONG).show(); } }); } }
当点击按钮的时候就会在Toast中显示Fragment1中的内容。
当然两个Fragment需要使用一个共同的activity父容器。
最后分享一些使用心得
补充知识点:
1、什么是FragmentTransaction?
使用Fragment时,可以通过用户交互来执行一些动作,比如增加、移除、替换等。
所有这些改变构成一个集合,这个集合被叫做一个transaction。
可以调用FragmentTransaction中的方法来处理这个transaction,并且可以将transaction存进由activity管理的back stack中,这样用户就可以进行fragment变化的回退操作。
可以这样得到FragmentTransaction类的实例:
1.FragmentManager mFragmentManager = getSupportFragmentManager();2.FragmentTransaction mFragmentTransaction = mFragmentManager.beginTransaction();
在多个 Fragment 之间进行切换的时候
replace()和hide的区别
首先replace 是代替,之前的Fragment会被清空掉,在再次切换回来的时候会进行重新加载。而hide是将之前的一个fragment 进行隐藏,将新的fragment 叠在上面进行显示.等在次调用的时候进行显示。不需要重新加载。测试这个最简单的方法就是 设计两个fragment 在同一位置上放一个按钮,一个有监听一个没有,但现实没有监听的按钮点击按钮的时候会响应一号按钮的监听事件。
另外一个对于 FragmentTransaction对象在commit之后就会失效。所以建议直接使用fragmentManager.beginTransaction() 这样就不会产生失效的问题了。
commit 于commitAllowingStateLoss();的区别
简单来说就是避免报错。
他们都调用了commitInternal
public int commit() {
return commitInternal(false);
}
public int commitAllowingStateLoss() {
return commitInternal(true);
}
这个两个方法区别就在传参判断后的处理方法checkStateLoss
当使用commit方法时,系统将进行状态判断,如果状态(mStateSaved)已经保存,将发生”Can not perform this action after onSaveInstanceState”错误。
如果mNoTransactionsBecause已经存在,将发生”Can not perform this action inside of ” + mNoTransactionsBecause错误
- Android Fragment 详解 2016 干货
- Android ListView 详解 2016 干货
- Android Gradle 详解 2016 干货
- 2016 Android 动画 详解 干货(一)
- 2016 Android 动画 详解 干货(二)
- Android Fragment使用详解
- Android Fragment使用详解
- android fragment详解
- Android Fragment使用详解
- Android Fragment使用详解
- android的Fragment详解
- Android Fragment详解
- Android Fragment详解
- Android Fragment详解
- Android Fragment 详解
- Android Fragment 详解
- Android - Fragment(碎片) 详解
- Android - ToDoList(fragment) 详解
- JavaScript--全选、全不选、反选、无刷新删除、批量删除、即点即改入库(在yii框架中操作)
- 链表
- SCPPO(十二):SQL误操作如何恢复?
- android的ImageView动画自动播放
- 六、数据库优化(上)——Mysql主从复制搭建
- Android Fragment 详解 2016 干货
- 解决Eclipse发布后到tomcat后目录下没有class文件
- mysql -- 区分apk包中,java包,android包,第三方包的方法
- 阿里___字符从键盘输入到屏幕显示过程
- Android Notification
- XZ_HTML之HTML脚本、实体和URL
- 日期工具 -DateUtils
- hdu5754Life Winner Bo+博弈
- ListView