Android入门教程之Fragment的具体使用详解

目录
  • Fragment 的简单用法
  • 动态加载 Fragment
  • Fragment 实现返回栈
  • Fragment 和 Activity 之间的交互
  • Fragment 生命周期

Fragment 的简单用法

Fragment 是一种可以嵌入在 Activity 当中的 UI 片段,它能让程序更加合理和充分地利用大屏幕的空间,因此在平板上应用非常广泛

在一个 Activity 中添加两个 Fragment,并让两个 Fragment 平分 Activity 的空间,首先新建一个左侧 Fragment 的布局 left_fragment.xml,这个布局只放置了一个按钮

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:text="Button" />

</LinearLayout>

然后新建一个右侧 Fragment 的布局 right_fragment.xml,将背景色设置成绿色,并放置一个 TextView 用于显示一段文本

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:background="#00ff00"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:textSize="24sp"
        android:text="This is right fragment" />

</LinearLayout>

接着新建一个 LeftFragment 类,并让它继承自 Fragment,注意这里要使用 AndroidX 库中的 Fragment,将刚刚定义的两个布局动态加载进来

class LeftFragment : Fragment() {

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        return inflater.inflate(R.layout.left_fragment, container, false)
    }
}
class RightFragment : Fragment() {

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        return inflater.inflate(R.layout.right_fragment, container, false)
    }
}

接下来修改 activity_main.xml 中的代码,使用 <fragment> 标签在布局中添加 Fragment

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <fragment
        android:id="@+id/leftFrag"
        android:name="com.example.fragmenttest.LeftFragment"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="1" />

    <fragment
        android:id="@+id/rightFrag"
        android:name="com.example.fragmenttest.RightFragment"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="1" />

</LinearLayout>

动态加载 Fragment

Fragment 真正强大之处在于,它可以在程序运行时根据具体情况来动态添加 Fragment,使得程序界面更加多样化

修改 activity_main.xml 的代码,使用 FrameLayout 布局,所有的空间都会默认摆放在布局的左上角,由于这里仅需要在布局里放入一个 Fragment,不需要任何定位,因此适合使用 FragLayout

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <fragment
        android:id="@+id/leftFrag"
        android:name="com.example.fragmenttest.LeftFragment"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="1" />

    <FrameLayout
        android:id="@+id/rightLayout"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="1" />

</LinearLayout>

修改 MainActivity 中的代码,实现动态添加 Fragment 的功能,给左侧 Fragment 的按钮注册一个点击事件,会动态加载右侧 Fragment

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        button.setOnClickListener {
            replaceFragment(RightFragment())
        }
    }

    private fun replaceFragment(fragment: Fragment) {
        val fragmentManager = supportFragmentManager
        val transaction = fragmentManager.beginTransaction()
        transaction.replace(R.id.rightLayout, fragment)
        transaction.commit()
    }
}

Fragment 实现返回栈

在上一节,通过点击按钮加载一个 Fragment 之后,按下 Back 键程序就会直接退出,如果我们希望实现类似返回栈的效果,按下 Back 键可以返回

FragmentTransaction 中提供了一个 addToBackStack() 方法,可以用于将一个事务添加到返回栈中,修改 MainActivity 中的代码

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        button.setOnClickListener {
            replaceFragment(RightFragment())
        }
    }

    private fun replaceFragment(fragment: Fragment) {
        val fragmentManager = supportFragmentManager
        val transaction = fragmentManager.beginTransaction()
        transaction.replace(R.id.rightLayout, fragment)
        transaction.addToBackStack(null)
        transaction.commit()
    }
}

我们在事务提交之前调用了 FragmentTransaction 的 addToBackStack() 方法,它可以接收一个名字用于描述返回栈的状态,一般传入 null 即可。现在重新运行程序,点击按钮加载右侧 Fragment,然后按下 Back 键,程序不会立刻退出,而是返回上一状态

Fragment 和 Activity 之间的交互

为了方便 Fragment 和 Activity 之间进行交互,FragmentManager 提供了一个类似于 findViewById() 的方法,专门用于从布局文件中获取 Fragment 的实例

supportFragmentManager.findFragmentById(R.id.leftFrag) as LeftFragment

那么在 Fragment 中又该怎么调用 Activity 里的方法呢?在每个 Fragment 中都可以通过调用 getActivity() 方法来得到和当前 Fragment 相关联的 Activity 实例

 if (activity != null) {
     val mainActivity = activity as MainActivity
 }

不同的 Fragment 之间也可以通信,基本思路是:首先在一个 Fragment 中得到与它相关联的 Activity,然后再通过这个 Activity 去获取另外一个 Fragment 实例,就实现了不同的 Fragment 之间的通信了

Fragment 生命周期

和 Activity 一样,Fragment 也有自己的生命周期,并且大体一致,只不过在一些细小的地方会有部分区别:

  • 运行状态

当一个 Fragment 所关联的 Activity 正处于运行状态,该 Fragment 也处于运行状态

  • 暂停状态

当一个 Activity 进入暂停状态(由于另一个未占满的 Activity 被添加到了栈顶),与它相关联的 Fragment 就会进入暂停状态

  • 停止状态

当一个 Activity 进入停止状态,与它相关联的 Fragment 就会进入停止状态,或者通过调用 FragmentTransaction 的 remove()、replace() 方法将 Fragment 从 Activity 中移除,但在事务提交前调用了 addToBackStack() 方法,也会进入停止状态

  • 销毁状态

当 Activity 被销毁时,与它相关联的 Fragment 就会进入销毁状态,或者通过调用 FragmentTransaction 的 remove()、replace() 方法将 Fragment 从 Activity 中移除,但在事务提交前没有调用了 addToBackStack() 方法,也会进入销毁状态

Fragment 完整的生命周期可参考下图

到此这篇关于Android入门教程之Fragment的具体使用详解的文章就介绍到这了,更多相关Android Fragment内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

时间: 2021-10-08

Android Fragment使用全解

我们都知道,Android上的界面展示都是通过Activity实现的,Activity实在是太常用了,我相信大家都已经非常熟悉了,这里就不再赘述. 但是Activity也有它的局限性,同样的界面在手机上显示可能很好看,在平板上就未必了,因为平板的屏幕非常大,手机的界面放在平板上可能会有过分被拉长.控件间距过大等情况.这个时候更好的体验效果是在Activity中嵌入"小Activity",然后每个"小Activity"又可以拥有自己的布局.因此,我们今天的主角Frag

Android Fragment监听返回键的一种合理方式

开场 以下场景为杜撰: 产品经理:"小罗,这个信息发送界面,如果用户输入了内容,点击返回键的时候,要先询问用户是否保存草稿箱哈". 小罗:"收到,这问题简单." 说完小罗就准备着手处理,然后却发现信息编辑界面是一个Fragment,然而Fragment并没有提供返回键点击的直接处理:小罗虽菜,但是摸鱼也摸了些年头了,这问题难不倒小罗. 小罗心想,反正Activity提供了onBackPressed方法,再不济的情况把这个操作分发到Fragment中去就好,可是对于处

Android在fragment中编写toobar的步骤详解

第一步的话就是首先导入我们的依赖的包: compile 'com.android.support:appcompat-v7:23.3.0' 第二步的话就是准备我们的布局文件和我们的item 在这的话我是将我们的toobar单独的放在一个布局文件中的方便以后的调用以及将我们的主题改为 我们noactionbar,同时在我们的主文件中进行引用 修改为nopactionbar 引用 设置单独的xml文件 然后的话就是我们在我们的这个位置设置的是我们的啊就是toobar的单独的一个文件代码如下: <?x

详解Android studio 动态fragment的用法

fragment的使用时Android的基础,它有两种用法,第一个就是静态的fragment.第二个则是动态的fragment. 静态fragment直接在layout创建你想要的fragment的XML的文件,然后在你的Java包里面创建对应fragment的class文件 布局代码如下所示 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http:

Android中PreferenceFragment的使用详解

目录 PreferenceFragment简介 PreferenceFragment使用 PreferenceFragment 扩展 PreferenceFragment简介 在我们写一个项目的时候,基本都有选项设置界面,这类设置界面的原理基本都是本地的一些个性化设置,通过读取本地设置来改变某些差异显示(例如字体大小,主题颜色,WIFI自动下载等).这些设置一般都会使用Preference来保存,Android专门为这种Activity提供了便捷的基类PreferenceActivity(如果是

Android中ContentProvider和ContentResolver详解

Android中ContentProvider和ContentResolver详解 在Android中,我们的应用有的时候需要对外提供数据接口,可以有如下几种方法: 1)AIDL 2)Broadcast 3)ContentProvider. 使用AIDL需要我们编写AIDL接口以及实现,而且对方也要有相应的接口描述,有点麻烦:使用Broadcast,我们不需要任何接口描述,只要协议文档就可以了,但是有点不好就是,这种方式不直接而且是异步的:使用ContentProvider我们不需要接口描述,只

Android 中ContentProvider的实例详解

Android 中ContentProvider的实例详解 Content Provider 的简单介绍: * Android中的Content Provider 机制可支持在多个应用中存储和读取数据.这也是跨应用 共享数据的唯一方式.在Android系统中,没有一个公共的内存区域,供多个应用共享存储数据: * Android 提供了一些主要数据类型的ContentProvider ,比如:音频.视频.图片和私人通讯录等: 在android.provider 包下面找到一些android提供的C

Android中SQLite 使用方法详解

Android中SQLite 使用方法详解 现在的主流移动设备像android.iPhone等都使用SQLite作为复杂数据的存储引擎,在我们为移动设备开发应用程序时,也许就要使用到SQLite来存储我们大量的数据,所以我们就需要掌握移动设备上的SQLite开发技巧.对于Android平台来说,系统内置了丰富的API来供开发人员操作SQLite,我们可以轻松的完成对数据的存取. 下面就向大家介绍一下SQLite常用的操作方法,为了方便,我将代码写在了Activity的onCreate中: @Ov

Android 中 ActivityLifecycleCallbacks的实例详解

Android 中 ActivityLifecycleCallbacks的实例详解           以上就是使用ActivityLifecycleCallbacks的实例,代码注释写的很清楚大家可以参考下, MyApplication如下: package com.cc; import java.util.LinkedList; import android.app.Activity; import android.app.Application; import android.os.Bun

Android 中 onSaveInstanceState()使用方法详解

Android 中 onSaveInstanceState()使用方法详解 覆盖onSaveInstanceState方法,并在onCreate中检测savedInstanceState和获取保存的值 @Override protected void onSaveInstanceState(Bundle outState) { outState.putInt("currentposition", videoView.getCurrentPosition()); super.onSave

Android 中Manifest.xml文件详解

Android 中Manifest.xml文件详解 每一个Android项目都包含一个清单(Manifest)文件--AndroidManifest.xml,它存储在项目层次中的最底层.清单可以定义应用程序及其组件的结构和元数据. 它包含了组成应用程序的每一个组件(活动.服务.内容提供器和广播接收器)的节点,并使用Intent过滤器和权限来确定这些组件之间以及这些组件和其他应用程序是如何交互的. 它还提供了各种属性来详细地说明应用程序的元数据(如它的图标或者主题)以及额外的可用来进行安全设置和单

Java中的instanceof关键字在Android中的用法实例详解

在下面介绍Android中如何使用instanceof关键字开发更方便时,先来温习一下java中instanceof的概念. instanceof大部分的概念是这样定义的:instanceof是Java的一个二元操作符,和==,>,<是同一类东西.由于它是由字母组成的,所以也是Java的保留关键字.它的作用是测试它左边的对象是否是它右边的类的实例,返回boolean类型的数据.举个栗子: String s = "I AM an Object!"; boolean isObj

Android 中Banner的使用详解

首先倒入一个依赖: compile 'com.youth.banner:banner:1.4.9' 添加的权限: <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> 布局文件: <com.youth.banner.B

Android中图片压缩方案详解及源码下载

Android中图片压缩方案详解及源码下载 图片的展示可以说在我们任何一个应用中都避免不了,可是大量的图片就会出现很多的问题,比如加载大图片或者多图时的OOM问题,可以移步到Android高效加载大图及多图避免程序OOM.还有一个问题就是图片的上传下载问题,往往我们都喜欢图片既清楚又占的内存小,也就是尽可能少的耗费我们的流量,这就是我今天所要讲述的问题:图片的压缩方案的详解. 1.质量压缩法 设置bitmap options属性,降低图片的质量,像素不会减少 第一个参数为需要压缩的bitmap图

Android中Parcelable的使用详解

Parcelable与Serializable Serializable是Java为我们提供的一个标准化的序列化接口. Parcelable是Android为我们提供的序列化的接口. 对比: 1.Parcelable相对于Serializable的使用相对复杂一些. 2.Parcelable的效率相对Serializable也高很多. 3.Parcelable不能使用在要将数据存储在磁盘上的情况,因为Parcelable在外界有变化的情况下不能很好的保证数据的持续性.尽管Serializable