落花踏尽游何处,笑入胡姬酒肆中。这篇文章主要讲述从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)
【从0系统学Android--4.1探究碎片】这个方法是适用于在布局中通过
<
fragment>
静态添加 Fragment
的情况,如果是动态的,就直接 new Fragment() 了。那么如何在碎片中调用 Activity 呢?其实每个碎片中都可以通过调用
getActivity()
方法来得到和当前碎片相关联的 Activity 实例。那么碎片与碎片直接如何通信呢?
思路:首先在一个碎片中可以得到与之关联的 Activity,然后通过这个 Activity 再去获取另外一个碎片实例就可以了。
推荐阅读
- 星云精准测试对安卓底层驱动代码的测试案例分析
- How to Close Frozen Applications in macOS
- cordova+vue构建app
- Appium移动端自动化测试--使用IDE编辑并强化脚本
- Appium移动端自动化测试--控件定位方法
- Android 开机充电图标和充电动画
- cordova+vue构建app进阶
- pringboot热部署导致applicationContext获取为空
- IDEA启动springboot项目找不到application.yml配置文件