从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. luogu P5171 Earthquake

    题目描述 给定 a,b,c ,求满足方程 ax+by⩽c 的非负整数解个数. 输入格式 输入三个整数 a,,b,,c . 输出格式 输出一个整数表示答案. 类欧几里得算法 #include<cs ...

  2. textView的用法及技巧

    转自:http://bbs.9ria.com/thread-244445-1-1.html 一.新建一个textView //初始化 UITextView *textView = [[[UITextV ...

  3. 2019沈阳icpc网络赛H德州扑克

    题面:https://nanti.jisuanke.com/t/41408 题意:A,2,3,4,5,6,7,8,9,10,J,Q,K,13张牌,无花色之分,val为1~13. 给n个人名+n个牌,输 ...

  4. UVA-156

    Most crossword puzzle fans are used to anagrams - groups of words with the same letters in different ...

  5. Round-number

    Description Most of the time when rounding a given number, it is customary to round to some multiple ...

  6. Dubbo源码分析之 SPI(一)

    一.概述 dubbo SPI 在dubbo的作用是基础性的,要想分析研究dubbo的实现原理.dubbo源码,都绕不过 dubbo SPI,掌握dubbo SPI 是征服dubbo的必经之路. 本篇文 ...

  7. Python3 类与对象

    目录 面向对象基础 面向过程编程 面向对象编程 类 什么是类 如何定义类 类的基本操作 对象 实例化对象 对象添加特有属性 对象与类的查找顺序 对象的绑定方法 面向对象基础 面向过程编程 面向过程的核 ...

  8. Brett Beauregard大神的Arduino PID算法

    大神的全部PID http://brettbeauregard.com/blog/category/pid/ Improving the Beginner’s PID – Introduction I ...

  9. 起言-----UE4学习方法

    1.bilibili 2.官网教程 3.我觉得以上两个就够了 官方文档链接 https://docs.unrealengine.com/ 官网在线视频链接 https://learn.unrealen ...

  10. java之线程(线程的创建方式、java中的Thread类、线程的同步、线程的生命周期、线程之间的通信)

    CPU:10核 主频100MHz 1核  主频    3GHz 那么哪一个CPU比较好呢? CPU核不是越多越好吗?并不一定.主频用于衡量GPU处理速度的快慢,举个例子10头牛运送货物快还是1架飞机运 ...