• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

十、Android-探究Fragment

武飞扬头像
loongx
帮助5

10. 探究Fragment

Fragment: 片段、碎片。是一部分内容构成的片段,体现在屏幕上是一块内容区域。

10.1 Fragment的简单使用

新建Fragment的默认代码

private const val ARG_PARAM1 = "param1"
private const val ARG_PARAM2 = "param2"

class LeftFragment : Fragment() {
    private var param1: String? = null
    private var param2: String? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        arguments?.let {
            param1 = it.getString(ARG_PARAM1)
            param2 = it.getString(ARG_PARAM2)
        }
    }

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
                              savedInstanceState: Bundle?): View? {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.fragment_left, container, false)
    }

    companion object {
        @JvmStatic
        fun newInstance(param1: String, param2: String) =
            LeftFragment().apply {
                arguments = Bundle().apply {
                    putString(ARG_PARAM1, param1)
                    putString(ARG_PARAM2, param2)
                }
            }
    }
}

布局代码

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".LeftFragment">

    <Button
        android:id="@ id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        android:text="Button" />

</androidx.constraintlayout.widget.ConstraintLayout>

Activity中使用

<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <fragment
        android:id="@ id/leftFrag"
        android:name="com.example.fragmenttest.LeftFragment"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toLeftOf="@id/frameLayout"
        app:layout_constraintTop_toTopOf="parent" />

    <FrameLayout
        android:id="@ id/frameLayout"
        android:name="com.example.fragmenttest.RightFragment"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        app:layout_constraintLeft_toRightOf="@id/leftFrag"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />


</androidx.constraintlayout.widget.ConstraintLayout>

10.2 动态添加Fragment

新建另一个FragmentRightFragment

private const val ARG_PARAM1 = "param1"
private const val ARG_PARAM2 = "param2"

class RightFragment : Fragment() {
    // TODO: Rename and change types of parameters
    private var param1: String? = null
    private var param2: String? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        arguments?.let {
            param1 = it.getString(ARG_PARAM1)
            param2 = it.getString(ARG_PARAM2)
        }
    }

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.fragment_right, container, false)
    }

    companion object {
        @JvmStatic
        fun newInstance(param1: String, param2: String) =
            RightFragment().apply {
                arguments = Bundle().apply {
                    putString(ARG_PARAM1, param1)
                    putString(ARG_PARAM2, param2)
                }
            }
    }
}

fragment_right.xml

<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@android:color/holo_orange_light"
    tools:context=".RightFragment">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        android:text="@string/hello_blank_fragment"
        android:textSize="24sp"/>

</androidx.constraintlayout.widget.ConstraintLayout>

然后再MainActivity中动态添加:

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

LeftFragment中的Button方法中调用:

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        binding = FragmentLeftBinding.inflate(inflater, container, false)
        binding.button.setOnClickListener {
            val mainActivity = activity as? MainActivity
            mainActivity?.let {
                val right = RightFragment()
                it.replaceFragment(right)
        }
        return binding.root
    }

动态添加Fragment的步骤:

  1. 创建待添加的Fragment实例;
  2. 获取FragmentManager,在Activity中可以直接调用getSupportFragmentManager()方法获取;
  3. 开启一个事务,通过调用beginTransaction()方法开启;
  4. 向容器中添加或者替换Fragment,一般使用replace()方法实现,需要传入容器的id和待添加的Fragment实例;
  5. 提交事务,调用commit()方法来完成;

10.3 在Fragment中实现返回栈

FragmentTransaction中提供了一个addToBackStack()方法,将一个事务添加到返回栈中。

    fun replaceFragment(fragment: Fragment) {
        val fragmentManager = supportFragmentManager
        val transaction = fragmentManager.beginTransaction()
        transaction.replace(R.id.rightLayout, fragment)
        // 参数一般null就行
        transaction.addToBackStack(null)
        transaction.commit()
    }

调用系统的Back键,会先把添加的BackStack会退掉,这里就是fragment会回退到原来的R.id.rightLayout

10.4 在 Fragment 中使用视图绑定

如需设置绑定类的实例以供Fragment 使用,请在 FragmentonCreateView() 方法中执行以下步骤:

  1. 调用生成的绑定类中包含的静态 inflate() 方法。此操作会创建该绑定类的实例以供 Fragment 使用。
  2. 通过调用 getRoot() 方法或使用 Kotlin 属性语法获取对根视图的引用。
  3. onCreateView() 方法返回根视图,使其成为屏幕上的活动视图。
    private var _binding: ResultProfileBinding? = null
    // This property is only valid between onCreateView and
    // onDestroyView.
    private val binding get() = _binding!!

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        _binding = ResultProfileBinding.inflate(inflater, container, false)
        val view = binding.root
        return view
    }

    override fun onDestroyView() {
        super.onDestroyView()
        _binding = null
    }
    

您现在即可使用该绑定类的实例来引用任何视图。

10.5 Fragment和Activity之间的交互

  • 在Activity中获取Fragment实例:
val leftFragment = supportFragmentManager.findFragmentById(R.id.leftFrag) as? LeftFragment
leftFragment?.let { }

获取到Fragment实例后,就可以调用Fragment里面的对应方法了。

  • 在Fragment中获取Activity实例:
val mainActivity = activity as? MainActivity
mainActivity?.let { }

获取到Activity后,可以调用Activity中对应方法。

  • 同一个Activity中的Fragment之间通信
           val mainActivity = activity as? MainActivity
            mainActivity?.let {
                val right = RightFragment()
                it.replaceFragment(right)
                val fragmentManager = mainActivity.supportFragmentManager
                val rightFragment = fragmentManager.findFragmentById(R.id.rightFrag)
            }

10.6 Fragment的生命周期

Fragment的四种状态,和Activity一样:

  1. 运行状态

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

  1. 暂停状态

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

  1. 停止状态

当一个Activity进入停止状态时,与它相关联的Fragment就会进入停止状态,或者通过调用FragmentTransaction的remove()replace()方法将Fragment从Activity中移除,但在事务提交之前调用了addToBackStack()方法,这时的Fragment也会进入停止状态。总的来说,进入停止状态的Fragment对用户来说是完全不可见的,有可能会被系统回收。

  1. 销毁状态

Fragment总是依附于Activity而存在,因此当Activity被销毁时,与它相关联的Fragment就会进入销毁状态。或者通过调用FragmentTransaction的remove()replace()方法将Fragment从Activity中移除,但在事务提交之前并没有调用addToBackStack()方法,这时的Fragment也会进入销毁状态。

部分声明周期说明:

  • onAttach():当Fragment和Activity建立关联时调用。
  • onCreateView():为Fragment创建视图(加载布局)时调用。
  • onActivityCreated():确保与Fragment相关联的Activity已经创建完毕时调用。
  • onDestroyView():当与Fragment关联的视图被移除时调用。
  • onDetach():当Fragment和Activity解除关联时调用。

学新通

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhfgkieg
系列文章
更多 icon
同类精品
更多 icon
继续加载