从0系统学Android--4.1探究碎片



本系列文章目录更多精品文章分类

本系列持续更新中.... 初级阶段内容参考《第一行代码》

第四章:手机平板要兼顾--探究碎片

平板电脑和手机最大的区别就在于屏幕的大小,一般手机的屏幕大小会在 3 英寸到 6 英寸之间,而一般平板电脑屏幕大小会在 7 英寸到 10 英寸之间。屏幕大小差距过大会导致同样的界面视觉效果有很大的差异。

为了兼顾手机和平板开发,Android 3.0 引入了碎片的概念,可以让界面在平板上更好的展示。

4.1 碎片是什么

碎片(Fragment)是一种可以嵌入到 Activity 中的 UI 片段,让程序更加合理和充分利用屏幕的空间。它和 Activity 很像,同样都能包含布局,同样有生命周期。

如何利用平板的屏幕空间呢?比如我们要开发一个新闻类的 APP。在手机端可以是这样的。

可以是如果在平板上也这样设计,那么新闻标题列表就会给拉伸的很长,而新闻的标题一般都不会太长,这样设计就会导致页面不合理。

因此,更好的设计方案是将新闻列表和新闻详细内容界面放到两个碎片中,然后在同一 Activity 中引入这两个碎片,这样屏幕空间就充分利用起来了。

4.2 碎片的使用方式

首先我们先创建一个平板的模拟器,准备好后新建一个包用于碎片化的练习。

4.2.1 碎片的简单用法

写一个最简单的碎片示例,在一个 Activity 中添加两个碎片,并让这两个碎片平方 Activity 空间。

  1. 新建一个左侧碎片布局 left_fragment.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:orientation="vertical">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button"
android:layout_gravity="center_horizontal"
android:id="@+id/bt"/>
</LinearLayout>
  1. 新建一个右侧碎片布局right_fragment.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="#FF0000"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:textSize="20sp"
android:text="This is right Fragment"/>
</LinearLayout>
  1. 新建 LeftFragment 类,让他继承 Fragment,Fragment 可能会有两个不同的包,建议使用支持库中的 Fragment,因为它可以让 Fragment 在所有的 Android 系统版本中保持功能一致性。比如在 Fragment 中嵌套 Fragment ,如果你使用的是系统内置的 Fragment 则在 Android 4.2 系统之前的设备上运行程序会崩溃。
public class LeftFragment extends Fragment {
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { View view = inflater.inflate(R.layout.left_fragment, container, false);
return view; }
}
  1. 同样的方法再创建一个 RightFragment
public class RightFragment extends Fragment {
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { View view = inflater.inflate(R.layout.left_fragment, container, false);
return view; }
}
  1. 修改 fragmentbaseuse_activity 代码
<?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:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:name="com.example.firstcode.fourth_chapter.LeftFragment"
android:id="@+id/fg_left"/>
<fragment
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:name="com.example.firstcode.fourth_chapter.RightFragment"
android:id="@+id/fg_right"/> </LinearLayout>

这里使用了 <fragment> 标签在布局中添加碎片,然后在标签中通过 android:name 属性来指明要添加的碎片的类名,注意一定要把包名加上。

运行结果:

4.2.2 动态添加碎片

在上一节中我们学习了如何在布局中添加碎片,下面我们来学习如何用代码动态的添加碎片。

新建一个 another_right_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="#FFFF00"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:textSize="20sp"
android:text="another fragment"/>
</LinearLayout>

里面代码基本相同,只是更该了一下背景颜色,用来区分。

再新建一个 Fragement

public class AnotherRightFragment extends Fragment {
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { View view = inflater.inflate(R.layout.another_right_fragment, container, false);
return view; }
}

修改主页面的布局

<?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:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:name="com.example.firstcode.fourth_chapter.LeftFragment"
android:id="@+id/fg_left"/>
<!-- <fragment
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:name="com.example.firstcode.fourth_chapter.RightFragment"
android:id="@+id/fg_right"/>-->
<FrameLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:id="@+id/framelayout"/> </LinearLayout>

<fragment>替换成了 FrameLayout ,FragmentLayout 是 Android 中最简单的一种布局,所有的控件默认会摆放在布局的左上角。这里仅需要放入一个碎片,不需要任何定位,因此非常适合使用 FrameLayout

下面在代码中向 FrameLayout 中添加内容,从而实现动态添加碎片的功能。

public class FragmentBaseActivity extends AppCompatActivity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_fragmentbase);
Button button = findViewById(R.id.bt);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
replaceFragment(new AnotherRightFragment());
}
});
replaceFragment(new RightFragment()); } private void replaceFragment(Fragment fragment){
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.framelayout,fragment);
fragmentTransaction.commit();
}
}

首先给左侧碎片中的按钮注册了点击事件,然后调用了 replaceFragment() 方法动态的添加了 RightFragment 这个碎片。当点击左侧按钮的时候,就会触发 replaceFragment() 这个方法。

动态添加碎片主要分为 5 步:

  1. 创建待添加的碎片
  2. 获取 FrgmentManagerFragmentManager是一个抽象类,在 Activity 中通过 getSupportFragmentManager() 方法来获取。
  3. 开启一个事务,通过调用 beginTransaction() 方法开启
  4. 向容器中添加或者替换掉已经添加的碎片,一般使用 replace() 就可以了。
  5. 提交事务,调用 commit() 方法来完成。

这样就完成了。

4.2.3 在碎片中模拟返回栈

在上一小节中已经学习了如何动态添加碎片,不过当我们按下 Back 键程序就直接退出了,如何实现类似于返回栈的效果,当按下 back 键的时候返回到上一个碎片呢?

FragmentTransaction 中提供了一个 addToBackStack() 方法,可以用于将一个事务添加到返回栈中。

    private void replaceFragment(Fragment fragment){
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); fragmentTransaction.replace(R.id.framelayout,fragment);
// 可以接受一个名字用于描述返回栈的状态,一般传入 null 即可 会将这个 Fragment 添加到栈中
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
}

这样再运行程序,你会发现按下 Back 后程序没有立马退出,而是先退出了 Fragment,等 Fragment 界面也消失了,再按下 back 才会退出。

4.2.4 碎片和活动之间进行通信

为了方便碎片和活动之间进行通信,FragmentManager 提供了一个类似于 findViewById() 的方法,专门用于从布局文件中获取碎片的实例。

RightFragment rightFragment = (RightFragment)getSupportFragmentManager().findFragmentById(R.id.right_fragment)

这个方法是适用于在布局中通过<fragment>静态添加 Fragment 的情况,如果是动态的,就直接 new Fragment() 了。

那么如何在碎片中调用 Activity 呢?其实每个碎片中都可以通过调用 getActivity() 方法来得到和当前碎片相关联的 Activity 实例。

那么碎片与碎片直接如何通信呢?

思路:首先在一个碎片中可以得到与之关联的 Activity,然后通过这个 Activity 再去获取另外一个碎片实例就可以了。

从0系统学Android--4.1探究碎片的更多相关文章

  1. 从0系统学Android-2.5更多隐式Intent用法

    本系列文章,参考<第一行代码>,作为个人笔记 更多内容:更多精品文章分类 从0系统学Android-2.5更多隐式Intent用法 上一节中我们学习了通过隐式 Intent 来启动 Act ...

  2. 从0系统学Android--3.7 聊天界面编写

    从0系统学Android--3.7 聊天界面编写 本系列文章目录:更多精品文章分类 本系列持续更新中.... 3.7 编写界面的最佳实践 前面学习了那么多 UI 开发的知识,下面来进行实践,做一个美观 ...

  3. 从0系统学Android--3.6 RecyclerView

    从0系统学Android--更强大的滚动控件---RecyclerView 本系列文章目录:更多精品文章分类 本系列持续更新中.... 参考<第一行代码> 首先说明一点昨天发了一篇关于 L ...

  4. 从0系统学Android--3.5 最常用和最难用的控件---ListView

    从0系统学Android-- 3.5 最常用和最难用的控件---ListView 本系列文章目录:更多精品文章分类 本系列持续更新中.... 3.5 最常用和最难用的控件---ListView Lis ...

  5. 从0系统学Android--3.2四种基本布局

    从0系统学Android--3.2四种基本布局 本系列文章目录:更多精品文章分类 本系列持续更新中.... 3.3 系统控件不够用?创建自定义控件 上一节我们学习了 Android 中的一些常用的控件 ...

  6. 从0系统学Android--3.1编写UI界面

    从0系统学Android--3.1编写UI界面 本系列文章目录:更多精品文章分类 本系列持续更新中.... 界面设计和功能开发同样重要,界面美观的应用程序不仅可以大大增加用户粘性,还能帮我们吸引到更多 ...

  7. 从0系统学Android--2.6 Activity 的最佳实践

    从0系统学Android--2.6 Activity 的最佳实践 本系列文章目录:更多精品文章分类 本系列持续更新中.... 实践中的技巧 2.6.1 知晓当前是在哪个 Activity 这个其实很简 ...

  8. 从0系统学Android--5.2 发送广播

    从0系统学Android--52 发送广播 本系列文章目录:更多精品文章分类 本系列持续更新中.... 初级阶段内容参考<第一行代码> 5.3 发送自定义广播 前面已经学习了如何接受广播了 ...

  9. 从0系统学Android--1.3创建你的第一个 Android 项目

    1.3 创建你的第一个 Android 项目 环境搭建完成后,我们就可以写下我们的第一个项目了. 1.3.1 创建 HelloWorld 项目 在 Android Studio 的欢迎页面点击 Sta ...

随机推荐

  1. 一道时间复杂度为O(N)空间复杂度为O(1)的排序问题

    题目:对1, 2, ... , n的一个无序数组,排序,要求时间复杂度为O(N),空间复杂度为O(1). 思路:该题利用数组元素和数组下标相差1的关系,Java代码如下: import java.ut ...

  2. luogu P4343 [SHOI2015]自动刷题机 |二分答案

    题目描述 曾经发明了信号增幅仪的发明家 SHTSC 又公开了他的新发明:自动刷题机--一种可以自动 AC 题目的神秘装置. 自动刷题机刷题的方式非常简单:首先会瞬间得出题目的正确做法,然后开始写程序. ...

  3. HDU 5121 Just A Mistake

    Just A Mistake Time Limit: 5000/5000 MS (Java/Others)    Memory Limit: 512000/512000 K (Java/Others) ...

  4. HDU2833-WuKong(求不同起点,终点最短路的交点最多数量)

    Liyuan wanted to rewrite the famous book "Journey to the West" ("Xi You Ji" in C ...

  5. 面试题-关于Java线程池一篇文章就够了

    在Java面试中,线程池相关知识,虽不能说是必问提,但出现的频次也是非常高的.同时又鉴于公众号"程序新视界"的读者后台留言让写一篇关于Java线程池的文章,于是就有本篇内容,本篇将 ...

  6. 【JS】328- 8个你不知道的DOM功能

    最近一直在关注工具,从 React 和 npm-install-everything 中休息一下,看看一些原生的 DOM 和 Web API 的功能,他们可以在没有任何依赖库的浏览器中直接运行. 这篇 ...

  7. 比SecureCRT更好用的工具MobaXterm下载安装使用教程

    一.下载 1.官网下载:下载地址 下载左边的免费版本 2.百度网盘下载:下载地址  提取码:tbge java开发工具下载地址及安装教程大全,点这里. 更多深度技术文章,在这里. 二.安装 1.双击安 ...

  8. HDFS的架构和设计要点

    HDFS的架构和设计要点 转 大数据之路 发布于 2012/10/11 23:00 字数 4487 阅读 495 收藏 1 点赞 0 评论 0 撸了今年阿里.头条和美团的面试,我有一个重要发现.... ...

  9. pythpn爬虫--来一波美女,备好纸巾了!

    关于图片名称的中央乱码问题 import requests from lxml import etree url = 'http://pic.netbian.com/4kmeinv/index_%d. ...

  10. WMB Commands

    Check ports: mqsiprofile //Run this first mqsireportproperties MB8BROKER -e AddressSampleProvider -o ...