展开说说:Android Fragment完全解析-卷一

这篇具有很好参考价值的文章主要介绍了展开说说:Android Fragment完全解析-卷一。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1、是什么

Fragment 中文意思是碎片,Android 3.0推出的一个系统组件,主打一个在应用界面中可模块化又可重复使用。

Fragment 它很独立,它可以定义和管理自己的布局,具有自己的生命周期,并且可以处理自己的输入事件。

Fragment 很粘人,它不能独立存在。它们必须由 activity 或其他 fragment 托管即fragment可以内嵌fragment使用同一 activity 或多个 activity 中可以使用同一 fragment 类的多个实例但是要注意解耦避免让一个 fragment 依赖另一个 fragment 或一个 fragment 操控另一个 fragment。

2、怎么用

Fragment一般是两种用法,使用管理器FragmentManager+事务FragmentTransaction和fragment搭配Viewpager。本文将分析第一种,后面一种会在下一篇文章分析。

activity 是放置应用的全局的界面元素,而Fragment 更适合定义和管理单个屏幕或部分屏幕的界面,可以更轻松地在运行时修改 activity 的外观。大部分应用的首页都采用了Fragment+底部切换选项按钮的布局。

Fragment类有这么样一个提示:

<li>Your activity must extend {@link FragmentActivity}
<li>You must call {@link FragmentActivity#getSupportFragmentManager} to get the
{@link FragmentManager}

也就是说 Fragment 必须嵌入 AndroidX FragmentActivity 中使用并获取管理器FragmentManager。AppCompatActivity 是FragmentActivity 的子类,因此如果我们的Activity是继承AppCompatActivity 就可以放心使用。

举个例子,一个Activity有四个底部选项卡,点击以后会展示四个不同Fragment页面,分别是FragmentHome 、FragmentApp、FragmentMsg、FragmentMy;一般来底部可能是个RadioGroup+RadioButton或者图片加文字的布局,我这里偷懒只写了四个button。

2.1通过新建一个类继承Fragment来创建一个fragment

定义一个自己的FragmentHome 前面说过Fragment也有自己的声明和布局展示,因此我在onCreateView方法使用inflate加载一个布局。类似的还有其他三个,分别是FragmentApp

FragmentMsgFragmentMy

public class FragmentHome extends Fragment {
@Override
public View onCreateView(@NonNull LayoutInflater inflater,  ViewGroup container, Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.fragment_home, null, false);
    Log.e(TAG, "onCreateView:     --" );
    return view;
}
}

2.2 将Fragment添加到Activity有两种方法,但是我们最常使用是第一种。

第一种:使用管理器FragmentManager和事务FragmentTransaction

activity布局应包含 一个容器组件来装载Fragment

<LinearLayout
    android:id="@+id/fragAct_root"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_marginBottom="@dimen/margin_50"
    android:visibility="gone"
    app:layout_constraintTop_toTopOf="parent"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintRight_toRightOf="parent"
    android:orientation="vertical" />

在Activity中将四个Fragment实例化,并创建FragmentManager

fragmentHome = new FragmentHome();
fragmentApp = new FragmentApp();
fragmentMsg = new FragmentMsg();
fragmentMy = new FragmentMy();
创建管理器FragmentManager:
FragmentManager manager = getSupportFragmentManager();

然后我们做增加、替换或者移除、显示、隐藏等都可以通过manager 获取事务来实现:

FragmentTransaction fragmentTransaction = manager.beginTransaction();

这里需要注意:fragmentTransaction只能提交一次无论是commit()或者commitNow(),超过一次会报错java.lang.IllegalStateException: commit already called

想要展示哪个fragment就通过事务的add或replace方法,添加当前fragment并放到前台展示。

先说add方法,一个简单的封装:add一个新的需要把其他的隐藏了否则可能会谍影重重:

private void addFragment(Fragment selectFragment, String fragmentTag) {
    //这里你要过滤FragmentManager的fragment列表
List<Fragment> fragments = manager.getFragments();
    for (Fragment fragment : fragments) {
        if (fragment.isAdded()) {
            Log.e(TAG, "initFragment: 已添加-先隐藏 " + fragment.getClass().getSimpleName() + "     " + fragmentHome.isAdded() + "    " + fragmentHome.isVisible());
            manager.beginTransaction().hide(fragment).commit();
        }
    }

    Fragment fragmentByTag = manager.findFragmentByTag(fragmentTag);
    if (fragmentByTag != null && fragmentByTag.isAdded()) {
        Log.e(TAG, "initFragment: 已经添加过了,别再添加-2 " + selectFragment.getClass().getSimpleName() + "     " + selectFragment.isAdded() + "    " + selectFragment.isVisible() + "   " + selectFragment.isHidden());
        manager.beginTransaction().show(fragmentByTag).commit();
    } else {
        if (selectFragment.isAdded()) {
            Log.e(TAG, "initFragment: 已经添加过了,别再添加-1 " + selectFragment.getClass().getSimpleName() + "     " + selectFragment.isAdded() + "    " + selectFragment.isVisible() + "   " + selectFragment.isHidden());
            manager.beginTransaction().show(selectFragment).commit();
        } else {
            manager.beginTransaction().add(R.id.fragAct_root, selectFragment, fragmentTag).show(selectFragment).commit();
            Log.e(TAG, "initFragment: 再次添加 fragment   +" + selectFragment.getClass().getSimpleName() + "     " + selectFragment.isAdded() + "    " + selectFragment.isVisible() + "   " + selectFragment.isHidden());
        }
    }
}

再说replace方法,如果你不用add,用了replace那一行代码就足够了

manager.beginTransaction().replace(R.id.fragAct_root, fragmentHome).commit();

第二种在Xml布局中写

<fragment
    android:id="@+id/fragAct_fragment"
    android:name="com.example.testdemo3.fragment.FragmentApp"
    android:layout_width="match_parent"
    android:layout_height="match_parent"/>

和普通组件一样使用在Activity中findviewbyid就可以了使用,这里注意fragment标签要小写、name属性对应的是你自定义fragment的全路径,后续fragment对象的使用方法同上面第一种。

3、常用方法

整体来看,fragment 应用界面中可模块化又可重复使用fragment 的视图层次结构会成为宿主的视图层次结构的一部分,或附加到宿主的视图层次结构并且可以方便将它增加、替换或者移除这些更改的记录会记录在由 activity 管理的返回堆栈中,以便撤消这些更改。

3.1 添加fragment

如需将 Fragment 添加到 FragmentManager通过事务调用 add()。此方法会收到用于存储此 Fragment 的容器的 ID,以及您要添加的 Fragment 的类名。添加的 Fragment 会转为 RESUMED 状态即最上层可以和用户交互的状态

3.2移除fragment

如需从宿主中移除 Fragment,调用 remove(),同时传入通过 findFragmentById() 或 findFragmentByTag() 从 Fragment 管理器检索到的 Fragment 实例。 如果 fragment 的视图之前已添加到容器中,则此时视图会从容器中移除。已移除的 fragment 会转为 DESTROYED 状态不可用。

3.3替换fragment

 replace() 将容器中现有的 fragment 替换为新 fragment 。调用 replace() 等同于对容器中的 Fragment 调用 remove() 后将新的 Fragment 添加到同一容器中就是系统帮你每次移除旧的并加入新的

3.4 提交

事务的提交操作为异步操作,调用 commit() 不会立即执行事务,而是会将事务调度为能在主界面线程上运行就在主界面线程上运行。如果使用 commitNow() 会立即在界面线程上运行 Fragment 事务,一般来说 commit() 即可。

4、避坑指南

4.1如果两次添加同一个Fragment对象,会报以下错误:
    java.lang.IllegalStateException: Fragment already added: FragmentHome{b2a5424 (a7835f58-5a56-49c9-b889-c0d8b8b17d8c) id=0x7f0800c5}  at androidx.fragment.app.FragmentManagerImpl.addFragment(FragmentManagerImpl.java:1379)
4.2如果同一个fragment使用了两个不同的tag进行add就会包如下错误:因此建议将TAG定义成常量
Caused by: java.lang.IllegalStateException: Can't change tag of fragment FragmentHome{595c6d5 (e4ff5b43-2336-422e-a219-008628a5c3b7) id=0x7f0800c5 fragmentHomeTag}: was fragmentHomeTag now FragmentHomeTag
        at androidx.fragment.app.FragmentTransaction.doAddOp(FragmentTransaction.java:172)

4.3 事务只能提交一次,无论是commit()或者commitNow(),超过一次会报错

java.lang.IllegalStateException: commit already called

4.4 横竖屏切换处理

我们在activity启动后应该自动展示一个fragment而不是一定要等用户主动触发再去加载展示对吧。如果你放到了onCreate中添加第一个fragment,那么在遇到横竖屏切换的话就会发现不论之前显示的个fragment切换以后都展示第一个fragment了,因为它重走生命周期了。其实呢可以这样避免:

//选出最近的fragment并展示,避免每次横竖屏切换就回到了第一个fragment
List<Fragment> fragments = manager.getFragments();
Fragment firstFragment = fragmentHome;
if (!fragments.isEmpty()) {
    firstFragment = fragments.get(fragments.size() - 1);
}
//上面2.2中写了这个方法
addFragment(firstFragment, firstFragment.getClass().getSimpleName() + "Tag");

横竖屏切换前的Fragment实例是怎样保存下来的呢?是的,是它。FragmentActivity的onSaveInstanceState方法。

展开说说:Android Fragment完全解析-卷一,学习总结,android文章来源地址https://www.toymoban.com/news/detail-857051.html

到了这里,关于展开说说:Android Fragment完全解析-卷一的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Android Fragment动画实现

    在 Android 中,你可以使用 FragmentTransaction 来实现 Fragment 的动画效果。这允许你在添加、替换或移除 Fragment 时应用动画,从而改善用户体验。下面是如何实现 Fragment 动画的基本步骤: 1. 创建两个 Fragment: 首先,创建两个 Fragment,例如 FragmentA 和 FragmentB。这些 Fragment 将被用于

    2024年02月09日
    浏览(35)
  • Xamarin.Android中的Fragment

    一般而言,会在 activity 中添加一个加载 fragment 的方法。通过点击菜单的按钮,加载不同的 fragment 。其样子一般是这样的: 在 fragment 中往往通过工厂模式,提供及返回实例 非常简单,因为fragment一定是要寄存到某个activity中。因此直接使用如下代码: 通过 FragmentManager 查找

    2024年02月10日
    浏览(53)
  • Android 基于Fragment的权限封装

    业内普遍比较认可使用另外一种小技巧来进行实现。是什么小技巧呢?回想一下,之前所有申请运行时权限的操作都是在 Activity 中进行的,事实上,Android 在 Fragment 中也提供了一份相同的 API,使得我们在 Fragment 中也能申请运行时权限。 但不同的是,Fragment 并不像 Activity 那

    2024年01月23日
    浏览(32)
  • android - fragment 数据丢失?状态丢失?

    最佳答案 一些状态丢失的例子: 1.  假设您有一个按钮和一个 TextView 。在代码中,你已经定义了初始值为 0 的整数 i,它通过单击按钮递增 1,并且它的值显示在 TextView 中。假设你已经按下按钮 5 次,那么 textview 将被设置为 0。也就是说  Integer 在屏幕变化时丢失了它的值 。

    2024年02月10日
    浏览(49)
  • Android Navigation 导航切换fragment用法

    对于Android Navigation组件的导航到Fragment,您可以按照以下步骤操作: 首先,在您的项目的build.gradle文件中添加Navigation依赖: 在你的res目录下的navigation文件夹中创建一个nav_graph.xml文件,并定义您的导航图。 在您的布局文件中,添加NavHostFragment作为导航的目标。 在您的Activi

    2024年02月12日
    浏览(34)
  • Android Activity和Fragment的对比

    参考来源 参考来源 参考来源 onAttach() 作用:fragment已经关联到activity,这个时候 activity已经传进来了, 获得activity的传递的值 就可以进行 与activity的通信里, 当然也可以使用getActivity(),前提是这个fragment已经和宿主的activity关联,并且没有脱离,有且只有调用一次。 onCreate(

    2024年02月11日
    浏览(41)
  • Android ViewPager2 + Fragment 联动

    本篇主要介绍一下 ViewPager2 + Fragment , 上篇中简单使用了ViewPager2 实现了一个图片的滑动效果, 那图片视图可以滑动, ViewPager2也可以滑动 Fragment 概述 ViewPager2 官方对它的描述就是 以可滑动的格式显示视图或 Fragment 也就说明提供了滑动Fragment的实现 并且还很简单, 下面来看看吧

    2023年04月08日
    浏览(33)
  • Android Studio中fragment的应用

    目录 一、fragment的概念 1.1Fragment的历史由来 1.2什么是Fragment 1.3Fragment的生命周期  1.4Fragment的优点 二、Fragment的使用方法 三、Fragment的动态加载实现  四、总结 Fragment出现的初衷是为了适应大屏幕的平板电脑, 当然现在他仍然是平板APP UI设计的宠儿,而且我们普通手机开发也

    2024年02月03日
    浏览(36)
  • Android studio心得——fragment动态加载

    在Android应用程序中,Fragment是一种可以嵌入Activity中的组件。通过 Fragment,我们可以将UI 目录 前言 一、什么是Android Studio 二、简介Fragment 三、学期知识汇总 四、什么是碎片(Fragment) 五、页面实现步骤 1.程序APP主界面的常用例子 2.定义4个Fragment 3.activity_main.xml代码展示 4.四个

    2024年02月09日
    浏览(31)
  • Android案例之Fragment的使用——川菜菜谱

    本案例将会演示如何在一个Activity中展示两个Fragment(一个Fragment用于展示川菜列表,一个Fragment用于展示川菜做法),并实现Activity与Fragment通信功能 1. 准备工作 导入两个所需图片至mipmap文件夹,在res/layout文件夹的activity_main.xml文件中添加两个fragment,分别用于显示菜单列表和

    2023年04月20日
    浏览(46)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包