Android基础笔记(十八)- Fragment
博客的感悟,终点-开始
这个是基础的最后一篇博客了,学习了很多,也有很多感触。
就在这里大致总结一下。
坚持往往很难,完美的坚持下去更难。这是写这十八篇博客的感悟。
时间流失的很快,总是感觉时间不够用。慢慢的就会让自己博客的质量下降。今天反思了一下,我这样不就是在制造“破窗户”吗?(破窗户理论不知道的可以去看一下)
写到第十八篇,感觉思路乱了很多,果然看“知识点”和组织语言描述 “知识点”还是有很差的差别的。
这是基础的最后一篇博客,即是个结束,也是个开始。结束的是自己不认真的态度,开始的是Android全新的旅程。
学无止境,技术无止境。从今天开始敦促自己,认真、认真、再认真。
机遇可能碰到你,但是如果你没有之前辛勤的汗水,便无法抓住。
什么是Fragment
Fragment它是在Android3.0时被引入的,主要用于在大屏幕设备上,支持动态和更灵活的UI设计(例如平板)。
Fragment是表现Activity中UI的一个行为或者一部分。可以把fragment想象成activity的一个模块化区域,有它自己的生命周期,接收属于它自己的输入事件,并且可以在activity运行期间添加和删除(有点像一个可以在不同的activity中重用的“子Activity”)。
Fragment必须被嵌入到一个activity中。它们的生命周期直接受其宿主activity的生命周期影响。当一个activity正在运行时,就可以独立地操作每一个Fragment,比如添加或删除它们。
Fragment可以定义自己的布局、生命周期回调方法,因此可以将fragment重用到多个activity中,因此可以根据不同的屏幕尺寸或者使用场合改变fragment组合。
添加fragment到Activity的两种方式
- 方式一,插入
<fragmetn>
作为布局的子元素,可以按照以下步骤: -
①在布局文件中添加
<fragment>
标签,并指定android:name
属性为一个继承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:orientation="horizontal" > <fragment android:id="@+id/list" android:name="com.bzh.layout.Fragment1" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" /> </LinearLayout>
-
②创建继承
Fragment
的类,并重写onCreateView()
方法,在其中使用inflate.inflate(R.layout.fragment1,null)
使用XML文件生成一个View对象,作为fragment的根布局public class Fragment1 extends Fragment{ @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fragment1, null); return view; } }
-
③创建名为fragment1的布局文件
<?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:orientation="vertical" > <TextView android:layout_width="match_parent" android:layout_height="match_parent" android:text="我是Fragment1" /> </LinearLayout>
结果如下:
直接在布局文件中使用<fragment>
元素的步骤还是比较简单,但是可以看得出,还是不灵活,同时在实际使用中也使用的不多。
- 另外,每一个fragment都需要一个唯一的标识,如果activity重启,系统可以用来恢复Fragment,并且可以用id来捕获Fragment来处理事务,例如移除它。有3种方法来为一个fragment提供一个ID:
- 使用android:id属性提供一个唯一ID;
- 使用android:tag属性提供一个唯一字符串;
- 如果以上2个你都没有提供,系统将使用容器view的ID;
- 方式二,使用编码的方式把fragment添加或替换到已经存在的
ViewGroup
布局中。 - 和第一种方式一样的地方时,我们依旧需要准备一个继承
Fragment
的类,和为其准备一个布局文件,在onCreateView()
回调中,使用填充器返回它的实例作为布局。 -
不同的地方在于,如果动态的添加或者替换,我们需要使用
FragmentManager
类,并开启事务,当然最后也要提交事务。WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE); int height = wm.getDefaultDisplay().getHeight(); int width = wm.getDefaultDisplay().getWidth(); // 获取Fragment管理器 FragmentManager fragmentManager = getFragmentManager(); // 开启事务 FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); if (height > width) { // 使用Fragment替换指定的布局 fragmentTransaction.replace(android.R.id.content, new Fragment1()); } else { // 使用Fragment替换指定的布局 fragmentTransaction.replace(android.R.id.content, new Fragment2()); } // 提交事务 fragmentTransaction.commit();
Fragment的生命周期
- Fragment的生命周期和activity生命周期很像。
- onAttach:绑定到activity
- onCreate:创建fragment
- onCreateView: 创建fragment的布局
- onActivityCreated: activity创建完成后
- onStart: 可见, 不可交互
- onResume: 可见, 可交互
- onPause: 部分可见, 不可交互
- onStop:不可见
- onDestroyView: 销毁fragment的view对象
- onDestroy: fragment销毁了
- onDetach: 从activity解绑了
- 在实际开发中,当然不会全部重写,Google推荐我们至少要重写一下三个方法:
- onCreate()在fragment被创建时,我们可以初始化一些组件。
- onCreateView()当第一次绘制fragmetn界面时,我们必须返回一个View对象作为fragmetn的根布局。
- onPause()当fragment不可以和用户交互时。
Fragment的向下兼容
- Fragment是在Android 3.0才推出的,若想在3.0的低版本下使用Fragment,则需要执行下面2步:
- 把所有Fragment和FragmentManager改成support-v4包下的类
- 把Activity的继承改为FragmentActivity(support-v4包下的)
Fragment之间的通信
两个Fragment之间的通信主要是借助给Fragment
对象设置一个Tag,和使用FragmentManager.findFragmentByTag()
方法,找到为Tag的Fragment
对象,从而达到交流的目的。
下面通过一个小案例来使用一下。在主布局中,左右有两个LinearLayout
布局,在代码中分别被Fragment1
和Fragment2
填充。其中Fragment1
中包含一个Button
,可以修改Fragment2
的TextView
内容。
首先在MainActivity中把两个Fragment替换到指定的布局中
LinearLayout ll1 = (LinearLayout) findViewById(R.id.ll1);
LinearLayout ll2 = (LinearLayout) findViewById(R.id.ll2);
FragmentManager fm = getFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
// 给Fragment1对象设置tag为fragment1
ft.replace(R.id.ll1, new Fragment1() ,"fragment1");
// 给Fragment1对象设置tag为fragment2
ft.replace(R.id.ll2, new Fragment2(), "fragment2");
ft.commit();
在Fragment2中,我们需要给外界暴露出修改TextView内容的方法,也很简单:
public class Fragment2 extends Fragment {
private TextView tv;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment2, null);
tv = (TextView) view.findViewById(R.id.tv);
return view;
}
// 暴露给外界修改TextView的方法
public void setTextView(String content) {
tv.setText(content);
}
}
接下来的事情就很简单了,在Fragment1中,根据Tag找到Fragment2对象,再修改就OK了。
public class Fragment1 extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment1, null);
Button btn = (Button) view.findViewById(R.id.btn);
btn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// 借助Fragment管理器找到带有tag的对象
Fragment2 f2 = (Fragment2) getFragmentManager().findFragmentByTag("fragment2");
f2.setTextView("我去你妹的");
}
});
return view;
}
}
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。