从0系统学Android--4.1探究碎片
从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 空间。
- 新建一个左侧碎片布局
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>
- 新建一个右侧碎片布局
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>
- 新建 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;
}
}
- 同样的方法再创建一个
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;
}
}
- 修改
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 步:
- 创建待添加的碎片
- 获取
FrgmentManager
,FragmentManager
是一个抽象类,在 Activity 中通过getSupportFragmentManager()
方法来获取。 - 开启一个事务,通过调用
beginTransaction()
方法开启 - 向容器中添加或者替换掉已经添加的碎片,一般使用
replace()
就可以了。 - 提交事务,调用
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探究碎片的更多相关文章
- 从0系统学Android-2.5更多隐式Intent用法
本系列文章,参考<第一行代码>,作为个人笔记 更多内容:更多精品文章分类 从0系统学Android-2.5更多隐式Intent用法 上一节中我们学习了通过隐式 Intent 来启动 Act ...
- 从0系统学Android--3.7 聊天界面编写
从0系统学Android--3.7 聊天界面编写 本系列文章目录:更多精品文章分类 本系列持续更新中.... 3.7 编写界面的最佳实践 前面学习了那么多 UI 开发的知识,下面来进行实践,做一个美观 ...
- 从0系统学Android--3.6 RecyclerView
从0系统学Android--更强大的滚动控件---RecyclerView 本系列文章目录:更多精品文章分类 本系列持续更新中.... 参考<第一行代码> 首先说明一点昨天发了一篇关于 L ...
- 从0系统学Android--3.5 最常用和最难用的控件---ListView
从0系统学Android-- 3.5 最常用和最难用的控件---ListView 本系列文章目录:更多精品文章分类 本系列持续更新中.... 3.5 最常用和最难用的控件---ListView Lis ...
- 从0系统学Android--3.2四种基本布局
从0系统学Android--3.2四种基本布局 本系列文章目录:更多精品文章分类 本系列持续更新中.... 3.3 系统控件不够用?创建自定义控件 上一节我们学习了 Android 中的一些常用的控件 ...
- 从0系统学Android--3.1编写UI界面
从0系统学Android--3.1编写UI界面 本系列文章目录:更多精品文章分类 本系列持续更新中.... 界面设计和功能开发同样重要,界面美观的应用程序不仅可以大大增加用户粘性,还能帮我们吸引到更多 ...
- 从0系统学Android--2.6 Activity 的最佳实践
从0系统学Android--2.6 Activity 的最佳实践 本系列文章目录:更多精品文章分类 本系列持续更新中.... 实践中的技巧 2.6.1 知晓当前是在哪个 Activity 这个其实很简 ...
- 从0系统学Android--5.2 发送广播
从0系统学Android--52 发送广播 本系列文章目录:更多精品文章分类 本系列持续更新中.... 初级阶段内容参考<第一行代码> 5.3 发送自定义广播 前面已经学习了如何接受广播了 ...
- 从0系统学Android--1.3创建你的第一个 Android 项目
1.3 创建你的第一个 Android 项目 环境搭建完成后,我们就可以写下我们的第一个项目了. 1.3.1 创建 HelloWorld 项目 在 Android Studio 的欢迎页面点击 Sta ...
随机推荐
- 一道时间复杂度为O(N)空间复杂度为O(1)的排序问题
题目:对1, 2, ... , n的一个无序数组,排序,要求时间复杂度为O(N),空间复杂度为O(1). 思路:该题利用数组元素和数组下标相差1的关系,Java代码如下: import java.ut ...
- luogu P4343 [SHOI2015]自动刷题机 |二分答案
题目描述 曾经发明了信号增幅仪的发明家 SHTSC 又公开了他的新发明:自动刷题机--一种可以自动 AC 题目的神秘装置. 自动刷题机刷题的方式非常简单:首先会瞬间得出题目的正确做法,然后开始写程序. ...
- HDU 5121 Just A Mistake
Just A Mistake Time Limit: 5000/5000 MS (Java/Others) Memory Limit: 512000/512000 K (Java/Others) ...
- HDU2833-WuKong(求不同起点,终点最短路的交点最多数量)
Liyuan wanted to rewrite the famous book "Journey to the West" ("Xi You Ji" in C ...
- 面试题-关于Java线程池一篇文章就够了
在Java面试中,线程池相关知识,虽不能说是必问提,但出现的频次也是非常高的.同时又鉴于公众号"程序新视界"的读者后台留言让写一篇关于Java线程池的文章,于是就有本篇内容,本篇将 ...
- 【JS】328- 8个你不知道的DOM功能
最近一直在关注工具,从 React 和 npm-install-everything 中休息一下,看看一些原生的 DOM 和 Web API 的功能,他们可以在没有任何依赖库的浏览器中直接运行. 这篇 ...
- 比SecureCRT更好用的工具MobaXterm下载安装使用教程
一.下载 1.官网下载:下载地址 下载左边的免费版本 2.百度网盘下载:下载地址 提取码:tbge java开发工具下载地址及安装教程大全,点这里. 更多深度技术文章,在这里. 二.安装 1.双击安 ...
- HDFS的架构和设计要点
HDFS的架构和设计要点 转 大数据之路 发布于 2012/10/11 23:00 字数 4487 阅读 495 收藏 1 点赞 0 评论 0 撸了今年阿里.头条和美团的面试,我有一个重要发现.... ...
- pythpn爬虫--来一波美女,备好纸巾了!
关于图片名称的中央乱码问题 import requests from lxml import etree url = 'http://pic.netbian.com/4kmeinv/index_%d. ...
- WMB Commands
Check ports: mqsiprofile //Run this first mqsireportproperties MB8BROKER -e AddressSampleProvider -o ...