Android Fragment完全解析,关于碎片你所需知道的一切

  我们都知道,Android上的界面展示都是通过Activity实现的,Activity实在是太常用了,我相信大家都已经非常熟悉了,这里就不再赘述。

  但是Activity也有它的局限性,同样的界面在手机上显示可能很好看,在平板上就未必了,因为平板的屏幕非常大,手机的界面放在平板上可能会有过分被拉长、控件间距过大等情况。这个时候更好的体验效果是在Activity中嵌入”小Activity”,然后每个”小Activity”又可以拥有自己的布局。因此,我们今天的主角Fragment登场了。

Fragment初探
  为了让界面可以在平板上更好的展示,Android在3.0版本引入了Fragment(碎片)功能,它非常类似于Activity,可以像Activity一样包含布局。Fragment通常是嵌套在Activity中使用的,现在想象这种场景:有两个Fragment,Fragment 1包含了一个ListView,每行显示一本书的标题。Fragment 2包含了TextView和ImageView,来显示书的详细内容和图片。
   如果现在程序运行竖屏模式的平板或手机上,Fragment1可能嵌入在一个Activity钟,而Fragment2可能嵌入在另一个Activity中,如下图所示
   这里写图片描述
   而如果现在程序运行在横屏模式的平板上,两个Fragment就可以嵌入在同一个Activity中了,如下图所示:
这里写图片描述
  由此可以看出,使用Fragment可以让我们更加充分地利用平板的屏幕空间,下面我们一起来探究下如何使用Fragment。
  新建一个项目叫做Fragments,然后在layout文件夹下新建一个名为fragment1.xml的布局文件:

<?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="#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>

fragment2.xml

<?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="#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>

然后新建一个类Fragment1,这个类是继承自Fragment的:

public class Fragment1 extends Fragment{@Overridepublic View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {return inflater.inflate(R.layout.fragment1,container,false);}
}

我们可以看到,这个类也非常简单,主要就是加载了我们刚刚写好的fragment1.xml布局文件并返回。同样的方法,我们再写好Fragment2 :

public class Fragment2 extends Fragment{@Nullable@Overridepublic View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {return inflater.inflate(R.layout.fragment2,container,false);}
}

然后打开或新建activity_main.xml作为主Activity的布局文件,在里面加入两个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:background="#00ff00"><fragment
        android:id="@+id/fragment1"android:name="com.example.wu.myapplication.Fragment1"android:layout_width="0dip"android:layout_height="match_parent"android:layout_weight="1"/><fragment
        android:id="@+id/fragment2"android:name="com.example.wu.myapplication.Fragment2"android:layout_width="0dip"android:layout_height="match_parent"android:layout_weight="1"/></LinearLayout>

最后打开或新建MainActivity作为程序的主Activity,里面的代码非常简单,都是自动生成的:

public class MainActivity extends AppCompatActivity {@Overridepublic void onCreate( Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);}
}

现在我们来运行一次程序,就会看到,一个Activity很融洽地包含了两个Fragment,这两个Fragment平分了整个屏幕,效果图如下:
这里写图片描述

动态添加Fragment
  你已经学会了如何在XML中使用Fragment,但是这仅仅是Fragment最简单的功能而已。Fragment真正的强大之处在于可以动态地添加到Activity当中,因此这也是你必须要掌握的东西。当你学会了在程序运行时向Activity添加Fragment,程序的界面就可以定制的更加多样化。下面我们立刻来看看,如何动态添加Fragment。
  还是在上一节代码的基础上修改,打开activity_main.xml,将其中对Fragment的引用都删除,只保留最外层的LinearLayout,并给它添加一个id,因为我们要动态添加Fragment,不用在XML里添加了,删除后代码如下:  

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:id="@+id/main_layout"android:layout_width="match_parent"android:layout_height="match_parent"android:baselineAligned="false">
</LinearLayout>

然后打开MainActivity,修改其中的代码如下所示:

public class MainActivity extends AppCompatActivity {@Overridepublic 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();getFragmentManager().beginTransaction().replace(R.id.main_layout,fragment1).commit();}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的生命周期是什么样的:

public class Fragment1 extends Fragment {  public static final String TAG = "Fragment1";  @Override  public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {  Log.d(TAG, "onCreateView");  return inflater.inflate(R.layout.fragment1, container, false);  }  @Override  public void onAttach(Activity activity) {  super.onAttach(activity);  Log.d(TAG, "onAttach");  }  @Override  public void onCreate(Bundle savedInstanceState) {  super.onCreate(savedInstanceState);  Log.d(TAG, "onCreate");  }  @Override  public void onActivityCreated(Bundle savedInstanceState) {  super.onActivityCreated(savedInstanceState);  Log.d(TAG, "onActivityCreated");  }  @Override  public void onStart() {  super.onStart();  Log.d(TAG, "onStart");  }  @Override  public void onResume() {  super.onResume();  Log.d(TAG, "onResume");  }  @Override  public void onPause() {  super.onPause();  Log.d(TAG, "onPause");  }  @Override  public void onStop() {  super.onStop();  Log.d(TAG, "onStop");  }  @Override  public void onDestroyView() {  super.onDestroyView();  Log.d(TAG, "onDestroyView");  }  @Override  public void onDestroy() {  super.onDestroy();  Log.d(TAG, "onDestroy");  }  @Override  public void onDetach() {  super.onDetach();  Log.d(TAG, "onDetach");  }  }  

可以看到,上面的代码在每个生命周期的方法里都打印了日志,然后我们来运行一下程序,可以看到打印日志如下:
这里写图片描述
这时点击一下home键,打印日志如下:
这里写图片描述
如果你再重新进入进入程序,打印日志如下:
这里写图片描述
然后点击back键退出程序,打印日志如下:
这里写图片描述

看到这里,我相信大多数朋友已经非常明白了,因为这和Activity的生命周期太相似了。只是有几个Activity中没有的新方法,这里需要重点介绍一下:
onAttach方法:Fragment和Activity建立关联的时候调用。
onCreateView方法:为Fragment加载布局时调用。
onActivityCreated方法:当Activity中的onCreate方法执行完后调用。
onDestroyView方法:Fragment中的布局被移除时调用。
onDetach方法:Fragment和Activity解除关联的时候调用。

Fragment之间进行通信
通常情况下,Activity都会包含多个Fragment,这时多个Fragment之间如何进行通信就是个非常重要的问题了。我们通过一个例子来看一下,如何在一个Fragment中去访问另一个Fragment的视图。

还是在第一节代码的基础上修改,首先打开fragment2.xml,在这个布局里面添加一个按钮:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  android:layout_width="match_parent"  android:layout_height="match_parent"  android:orientation="vertical"  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" />  <Button   android:id="@+id/button"  android:layout_width="wrap_content"  android:layout_height="wrap_content"  android:text="Get fragment1 text"  />  </LinearLayout>  

然后打开fragment1.xml,为TextView添加一个id:

<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:id="@+id/fragment1_text"  android:layout_width="wrap_content"  android:layout_height="wrap_content"  android:text="This is fragment 1"  android:textColor="#000000"  android:textSize="25sp" />  </LinearLayout>  

接着打开Fragment2.java,添加onActivityCreated方法,并处理按钮的点击事件:

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();  }  });  }  }  

这里写图片描述
我们可以看到,在fragment2中成功获取到了fragment1中的视图,并弹出Toast。这是怎么实现的呢?主要都是通过getActivity这个方法实现的。getActivity方法可以让Fragment获取到关联的Activity,然后再调用Activity的findViewById方法,就可以获取到和这个Activity关联的其它Fragment的视图了。

转自:http://blog.csdn.net/guolin_blog/article/details/8881711

转载于:https://www.cnblogs.com/Mayny/p/9374192.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/253196.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

图像--摄像头组成与基本参数

基本组成 Sensor: 图象传感器 FPC: 电路板 IR:红外滤波片 Holder:基座 Lens:镜头 其他 核心部件&#xff1a;1- SENSOR 2- LENS Sensor参数 类别 指标 参考 备注 Sensor 厂家 sony 三星 OV 格科微由原厂提供完整规格书和型号 低像素需要注意 分辨率 0.3MP (VGA)模组…

1.I2C协议

1.I2C协议2条双向串行线&#xff0c;一条数据线SDA&#xff0c;一条时钟线SCL。SDA传输数据是大端传输&#xff0c;每次传输8bit&#xff0c;即一字节。支持多主控(multimastering)&#xff0c;任何时间点只能有一个主控。总线上每个设备都有自己的一个addr&#xff0c;共7个bi…

联想启天M715E安装硬盘保护系统和网络同传

现还是学生&#xff0c;虽然大四课上的少&#xff0c;实验室去的也不勤了&#xff0c;但指导老师有事吩咐&#xff0c;还是要办好的。 沈老师荣升软件实验室主任&#xff0c;学校给了2个机房&#xff0c;一个70台联想启天M715E&#xff0c;一个30台新的70台新主机&#xff08;配…

图像--摄像头数据输出格式与传输接口

一、 数据输出格式 RAW data 格式: CMOS 在将光信号转换为电信号时的电平高低的原始记录&#xff0c;单纯地将没有进行任何处理的图像数据&#xff0c;即摄像元件直接得到的电信号进行数字化处理而得到的。 每个pixel只能感光R光或者B光或者G光&am…

计算机入门与学习回忆(一)

这个回忆&#xff0c;不是记录什么成功&#xff0c;而记录一些失败的经历。 大约初中还是高中的时候&#xff0c;就玩过计算机。那是一个很冷的冬天的晚上&#xff0c;一台华南计算机所造的仿APPLE II的计算机。 这台计算机很简陋&#xff0c;只有一个主机&#xff0c;没有屏幕…

怎么建立微信生态用户增长模型?

微信最新数据及中国网民最新数据概述截止到2018年&#xff0c;移动网民用户增长放缓&#xff0c;接近人口大盘。微信作为全国移动网民的一款超级应用&#xff0c;在移动网民的***率超过90%。微信最近一年的新增用户主要来自中老年用户群体和乡镇用户群体***。易观最新发布的8月…

数据库设计的三大范式

三大范式是为了了更好的设计数据库 1. 所谓第一范式&#xff08;1NF&#xff09;是指在关系模型中&#xff0c;对列添加的一个规范要求&#xff0c;所有的列都应该是原子性的&#xff0c;即数据库表的每一列都是不可分割的原子数据项&#xff0c;而不能是集合&#xff0c;数组&…

图像-摄像头驱动流程

驱动架构 在Kernel层用camera的驱动将其驱动起来以后&#xff0c;将硬件驱动接口交给Hal&#xff1b; 上层的camera应用程序在andriod实时系统的虚拟机中&#xff0c;加载留给camera公用的库文 件&#xff0c;调用Hal层的接口来控制camera硬件来实现功能。 驱动流程 打开came…

第四章

选择结构&#xff08;二&#xff09; 学习本章会用到的单词&#xff1a; case&#xff1a;实例&#xff0c;情形&#xff0c;情况 switch&#xff1a;转换&#xff0c;切换&#xff0c;开关 default&#xff1a;系统默认值&#xff0c;违约&#xff0c;预设。缺省 exit&#xf…

tensorflow的一些函数

1.tf.constant(value,dtypeNone,shapeNone,nameConst) 注意这个函数创造的是一个常数tensor&#xff0c;而不是一个具体的常数 value:即可以是list&#xff0c;也可以是value dtype:对应生成的tensor里的元素的类型 # Constant 1-D Tensor populated with value list.tensor t…

生活小常识

1、面试时说三个月试用期可以缩短的不要相信&#xff0c;可以谈谈别的条件 2、在饭店吃饭满几桌送下次吃饭的卷的不要信。可能你会没时间&#xff0c;或饭店没地方。&#xff08;谈谈当时可以送的其他优惠。或者根据自己的需求定桌数&#xff0c;不要被他诱惑凑桌&#xff09;转…

IP、TCP、UDP数据包长度问题

IP数据包长度问题总结 首先要看TCP/IP协议&#xff0c;涉及到四层&#xff1a;链路层&#xff0c;网络层&#xff0c;传输层&#xff0c;应用层。   其中以太网&#xff08;Ethernet&#xff09;的数据帧在链路层    IP包在网络层   TCP或UDP包在传输层    TCP或UDP中的…

RK瑞芯微WIFI模组2020最新支持列表,放心使用!

如下所示为RK瑞芯微2020最新支持的WIFIBT模组列表&#xff0c;请参考&#xff01; 标题希望对选型有所帮助&#xff0c;避免踩坑&#xff0c;坑驱动工程师&#xff01; 有事要搞&#xff0c;请私聊&#xff01;

数据类型进阶

----------siwuxie095 1、整数类型 如果去掉注释&#xff0c;报错&#xff1a;Type mismatch: cannot convert from into byte 即 不能把 int 类型转换成 byte 类型 如果选择 Add cast to byte&#xff1a; 即 把 b13 的结果&#xff08;默认为 int 类型&#xff09;强制转换成…

区块链教程Fabric1.0源代码分析流言算法Gossip服务端二

区块链教程Fabric1.0源代码分析流言算法Gossip服务端二 Fabric 1.0源代码笔记 之 gossip&#xff08;流言算法&#xff09; #GossipServer&#xff08;Gossip服务端&#xff09; 5.2、commImpl结构体方法 //conn.serviceConnection()&#xff0c;启动连接服务 func (c *commImp…

一段H264数据的分析

&#xfeff;&#xfeff;目录(?)[-] 分析00 00 00 01 67 42 00 1E 99 A0 B1 31 00 00 00 01分析00 00 00 01 68 CE 38 80 00 00 00 01 分析00 00 00 01 67 42 00 1E 99 A0 B1 31 00 00 00 01 H264的数据流分为两种&#xff0c;一种是NAL UNIT stream(RTP),一种是 bits stream…

海华模组:WIFI、BT、SoC模组列表

各种模块广泛应用于网络摄像头、智能机器人、儿童故事机、词典笔、智能音箱、智能家电等需要实现无线联网设备的消费类电子产品。 模块化有很大的有点&#xff1a;集成设计、减少调试工作&#xff0c;避开开发盲区、加速将产品推向市场&#xff01; 下面介绍下海华各类通讯模…

JAVA-初步认识-第七章-构造函数和一般函数的区别

一. 构造函数是对象一创建&#xff0c;就被调用了。(调用这个词很特殊&#xff0c;是涉及到实体时&#xff0c;才会有调用的过程) 还有一点想说的是&#xff0c;构造函数的声明应该是固定的&#xff0c;不然没法随着对象的创建一起执行&#xff0c;必须是类名括号的形式。 二. …

深入理解哈希表

转自&#xff1a;https://bestswifter.com/hashtable/ 这篇文章由一个简单的问题引出: 有两个字典&#xff0c;分别存有 100 条数据和 10000 条数据&#xff0c;如果用一个不存在的 key 去查找数据&#xff0c;在哪个字典中速度更快&#xff1f; 有些计算机常识的读者都会立刻回…

Linux服务器ftp+httpd部署

一、ftp安装 1、安装vsftpd 命令&#xff1a;yum -y install vsftpd 2、修改ftp配置文件 命令&#xff1a;vim /etc/vsftpd/vsftpd.conf 3、按i进入insert模式后&#xff0c;按以下要求修改 anonymous_enableYES 改为anonymous_enableNO chroot_local_userYES #去掉前面的注释 …