Android基础笔记(十八)- Fragment

  • 博客的感悟终点-开始
  • 什么是Fragment
  • 添加fragment到Activity的两种方式
  • Fragment的生命周期
  • Fragment的向下兼容
  • 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布局,在代码中分别被Fragment1Fragment2填充。其中Fragment1中包含一个Button,可以修改Fragment2TextView内容。

首先在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;
    }
}
时间: 2024-08-27 01:47:01

Android基础笔记(十八)- Fragment的相关文章

Android基础笔记(八)- Activity生命周期与任务栈

Activity的生命周期 横竖屏切换问题 任务栈的概念 Activity的4种启动模式 Activity的生命周期 Activity整个的生命周期如下所示,这张图是从Android API上扒下来了,我觉得API上关于生命周期已经讲解的很详细了,我也就不啰嗦了,就简要的说下自己的一些总结: 做工作中,你可能感兴趣的三个关键环 ① 完整生命周期 ② 可见生命周期 ③ 可交互生命周期 如图所示,图中的周期都是大的包括小的: 在实际工作中的使用 ①onResume可见, 可交互..把动态刷新的操作启

Android开发笔记(八十八)同步与加锁

同步synchronized 同步方法 synchronized可用来给方法或者代码块加锁,当它修饰一个方法或者一个代码块的时候,同一时刻最多只有一个线程执行这段代码.这就意味着,当两个并发线程同时访问synchronized代码块时,两个线程只能是排队做串行处理,另一个线程要等待前一个线程执行完该代码块后,才能再次执行synchronized代码块. 使用synchronized修饰某个方法,该方法便成为一个同步方法,在同一时刻只能有一个线程执行该方法.可是,synchronized的锁机制太

Bootstrap &lt;基础二十八&gt;列表组

列表组.列表组件用于以列表形式呈现复杂的和自定义的内容.创建一个基本的列表组的步骤如下: 向元素 <ul> 添加 class .list-group. 向 <li> 添加 class .list-group-item. 下面的实例演示了这点: <!DOCTYPE html> <html> <head> <title>Bootstrap 实例 - 基本的列表组</title> <link href="/boo

Java for Android 基础笔记-数据类型

Java的基本数据类型 布尔类型 boolean true | false java是一个强类型的语言,与JS中的布尔类型的自由转换相比,JAVA的Boolean类型只有两种true和false,JS中相应的只可以自行转换. 字符类型 char 可以存储一个汉字,和其他语言非常类似不再赘述. 整型 byte, 占用一个字节 -128`-127 short 2字节 -2^15~2^15-1 int 4字节 -2^31~2^31-1 long 8字节  -2^63~2^63-1 整型常量默认为int

Android基础之十四数据存储 之 SQLite数据库详解

Android基础之十四数据存储 之 SQLite数据库详解 SQLite 是一款 轻量级的关系型数据库,它的运算速度非常快,占用资源很少,通常只需要几百 K 的内存就足够了,因而特别适合在移动设备上使用. SQLite 不仅支持标准的 SQL 语法,还遵循了数据库的 ACID( 原子性(Atomicity) .一致性(Consistency) . 隔离性(Isolation) . 持久性(Durability))事务,所以只要你以前使用过其他的关系型数据库,就可以很快地上手 SQLite.而

Android笔记(六十八) Fragment总结

Fragment的产生: 为了适应各种尺寸的屏幕,谷歌推出Fragment,可以把Fragment成Activity的一个组成部分,它拥有自己的生命周期.可以接收并处理用户的各种事件,还可以动态的增删改某个Fragment Fragment的使用 可以把Fragment当成普通的控件使用,直接写在布局文件中,然后新建一个继承自Fragment的类加载这个布局,然后在Activity的布局文件中直接引用这个Fragment,就是这么简单: MainActivity.java package com

Android学习笔记十四.深入理解fragment(二) 之《图书详情》实战

深入理解fragment(二) 之<图书详情>实战 通过上一篇博文<深入理解fragment一>,我们学习了Android-Fragment的核心知识点.现在在此基础上,利用Fragment技术开发一款适用于大屏幕手机/平板的查找图书详情的应用软件.该项目主要在于两方面,一是Activity.Fragment的源码实现:二是,布局界面资源文件的实现. 1.res/../BookListFragment.java: 自定义类,继承于ListFragment,无需实现OnCreateV

Android进阶(二十八)上下文菜单ContextMenu使用案例

上下文菜单ContextMenu使用案例 前言 回顾之前的应用程序,发现之前创建的选项菜单无法显示了.按照正常逻辑来说,左图中在"商品信息"一栏中应该存在选项菜单,用户可进行分享等操作,但是现在此操作莫名其妙的消失了.写了个测试Demo,如中图所示,一切按照逻辑显示正常.怪就怪在项目中无法显示,起初设想是因为Android系统版本太高问题,但是在别的手机上测试之后发现问题依旧存在.难道是因为顶部Tab标题栏遮挡住了选项菜单的显示?继续测试,通过在别的没有Tab标题栏的页面测试选项菜单,

【转】 Pro Android学习笔记(八二):了解Package(1):包和进程

文章转载只能用于非商业性质,且不能带有虚拟货币.积分.注册等附加条件.转载须注明出处:http://blog.csdn.net/flowingflying/ 在之前,我们已经学习了如何签发apk,见Pro Android学习笔记(六四):安全和权限(1):签发apk,我们将对package做进一步了解. 每个apk都有一个唯一的根包名,在AndroidManifest.xml中定义,如下.开发者为包进行签发,前面和包名绑定,其他开发者不能对这个包进行更新. <?xml version="1