惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

小众软件
小众软件
IT之家
IT之家
博客园 - 聂微东
www.infosecurity-magazine.com
www.infosecurity-magazine.com
P
Privacy International News Feed
人人都是产品经理
人人都是产品经理
PCI Perspectives
PCI Perspectives
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
博客园 - 叶小钗
V
Vulnerabilities – Threatpost
美团技术团队
S
Secure Thoughts
N
News | PayPal Newsroom
L
LINUX DO - 最新话题
腾讯CDC
Application and Cybersecurity Blog
Application and Cybersecurity Blog
雷峰网
雷峰网
B
Blog
MyScale Blog
MyScale Blog
T
The Blog of Author Tim Ferriss
TaoSecurity Blog
TaoSecurity Blog
N
News and Events Feed by Topic
Blog — PlanetScale
Blog — PlanetScale
C
Check Point Blog
T
Tailwind CSS Blog
月光博客
月光博客
Simon Willison's Weblog
Simon Willison's Weblog
Hacker News: Ask HN
Hacker News: Ask HN
The Last Watchdog
The Last Watchdog
Google DeepMind News
Google DeepMind News
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
MongoDB | Blog
MongoDB | Blog
S
Security @ Cisco Blogs
Jina AI
Jina AI
Engineering at Meta
Engineering at Meta
S
Security Affairs
Forbes - Security
Forbes - Security
P
Palo Alto Networks Blog
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
博客园 - 司徒正美
博客园 - 三生石上(FineUI控件)
T
Tor Project blog
O
OpenAI News
L
Lohrmann on Cybersecurity
Security Archives - TechRepublic
Security Archives - TechRepublic
P
Proofpoint News Feed
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
L
LangChain Blog
B
Blog RSS Feed
H
Hackread – Cybersecurity News, Data Breaches, AI and More

博客园 - y丶innocence

临时111 RecyclerView 数据多时无法滑动:ConstraintLayout 约束高度修复笔记 Android Kotlin OkHttp3 WebSocket 长连接与 Gson 数据解析系统笔记 Android + Kotlin + OkHttp WebSocket 相关概念与使用流程笔记(TLS/证书 + 鉴权/会话) AI对话导出markdown格式流程 代理转发 分享文件 面向全球的app的excel导出和kotlin IO原理 安卓导出笔记(未整理) java&kotlin listener 0.7 动画 0.4 View 工作流程 0.3 view 滑动冲突 13. Jetpack 0. 安卓开发艺术探索参考资料 12. Material Design 7. 持久化技术 java 基础 4. UI 开发 3. Activity 2.2 Kotlin 面向对象 2.3 Kotlin高级 2.1 Kotlin基础 1. Android简介 [OpenJudge] 反正切函数的应用 (枚举)(数学) [OpenJudge] 摘花生 (模拟)
5. Fragment
y丶innocence · 2026-01-14 · via 博客园 - y丶innocence

5. Fragment

1. Fragment 和 Fragment 的生命周期

1. Fragment

  • Fragment 是一种可以嵌入在 Activity 当中的 UI 片段
  • 应用
    • 使用 RecyclerView 展示一组新闻标题,点开新闻标题后有新闻详情
    • 手机中,新闻标题列表放在一个 Activity 中,将新闻的详细内容放在另一个 Activity 中,即两个 Activity
    • 平板中,将新闻标题列表界面和新闻详细内容界面分别放在两个 Fragment 中, 然后在同一个 Activity 里引入这两个 Fragment

2. 生命周期

  • Fragment 生命周期与 Activity 几乎类似

    • 相似点,与 Activity 关联的 Fragment,如果 Activity 处于某一状态,则该 Fragment 也处于该状态
      • 运行状态
      • 暂停状态
      • 停止状态
      • 销毁状态
    • 区别
      • 将 Fragment 从 Activity 中移除
        • 如果调用了 addToBackStack,则进入停止状态
        • 如果没调用 addToBackStack,则进入销毁状态
          • 即将 Fragment 添加进返回栈后再移除,处于运行但是不可见的状态(停止状态)
  • onAttach():当 Fragment 和 Activity 建立关联时调用。

  • onCreateView():为 Fragment 创建视图(加载布局)时调用。

  • onActivityCreated():确保与 Fragment 相关联的 Activity 已经创建完毕时调用。

  • onDestroyView():当与 Fragment 关联的视图被移除时调用。

  • onDetach():当 Fragment 和 Activity 解除关联时调用。

  1. 启动 Activity 和 Fragment
    • onAttach()、 onCreate()、onCreateView()、onActivityCreated()、onStart() 和 onResume()
  2. 切换为另一个 Fragment (使用addToBackStack)
    • onPause()、onStop() 和 onDestroyView()
  3. 返回之前的 Fragment
    • onCreateView()、onActivityCreated()、onStart() 和 onResume()
  4. 退出程序
    • onPause()、onStop()、onDestroyView()、onDestroy() 和 onDetach()

2. 动态加载布局

  • 在不同文件夹下,建立相同的 layout 文件,就能自动选择对应的布局
    • 限定符
      • 【截图】
    • 最小宽度限定符(smallest-width qualifier)
      • layout-sw600sp
        • 单位为 dp
        • 宽度大于等于 600 dp 的设备加载 layout-sw600dp/xxx 的布局
        • 小于的加载 layout/xxx 的布局

3. 代码

  • Fragment

    • 可以直接存放 Fragment
  • FrameLayout

    • 可以动态加载 Fragment
  • 修改代码

    • MainActivity2

      • package com.example.helloworld
        
        import android.content.Context
        import android.content.Intent
        import android.os.Bundle
        import android.util.Log
        import android.widget.ArrayAdapter
        import android.widget.Button
        import android.widget.ListView
        import androidx.appcompat.app.AppCompatActivity
        import androidx.appcompat.widget.Toolbar
        
        
        class MainActivity2 : BaseActivity() {
        
            override fun onCreate(savedInstanceState: Bundle?) {
                super.onCreate(savedInstanceState)
                setContentView(R.layout.second_layout)
        
                // toolbar 部分
                val toolbar: Toolbar = findViewById(R.id.toolbar2)
                setSupportActionBar(toolbar)
                supportActionBar?.setDisplayHomeAsUpEnabled(true)            // 设置返回按钮
                toolbar.setNavigationOnClickListener { finish() }             // 设置结束 act2
        
                ActivityCollector.addActivity(this)
        
                // 从前一个 Activity 接收数据
                val extraData1 = intent.getStringExtra("param1")
                val extraData2 = intent.getStringExtra("param2")
                Log.d("Activity2", "param1 is $extraData1, param2 is $extraData2")
        
        
                // 返回数据(但是未实现)
                val button2: Button = findViewById(R.id.button2)        // 通过 id 找到 view, 并指明类型为 button
                button2.setOnClickListener {
                    val intent = Intent().apply { putExtra("data_return", "Hello Activity1") }
                    setResult(RESULT_OK, intent)
                    finish()
                }
        
                // 关闭所有 Activity
                val button3: Button = findViewById(R.id.button3)
                button3.setOnClickListener {
                    ActivityCollector.finishAll()
                }
        
                val button4: Button = findViewById(R.id.button4)
                button4.setOnClickListener {
                    startNewActivity(this, MainActivity3::class.java)
                }
        
                val button5: Button = findViewById(R.id.button5)
                button5.setOnClickListener {
                    startNewActivity(this, MainActivity4::class.java)
                }
        
                val button7: Button = findViewById(R.id.button7)
                button7.setOnClickListener {
                    startNewActivity(this, FragmentActivity::class.java)
                }
        
            }
        
        
        }
        
        
        
    • second_layout

      • <?xml version="1.0" encoding="utf-8"?>
        <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
          android:orientation="vertical"
            android:layout_width="match_parent"
          android:layout_height="match_parent">
        
            <androidx.appcompat.widget.Toolbar
                android:id="@+id/toolbar2"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:background="?attr/colorPrimary"
                android:minHeight="?attr/actionBarSize"
                android:theme="?attr/actionBarTheme" />
        
            <Button
                android:id="@+id/button2"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="Back" />
        
            <Button
                android:id="@+id/button3"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="Quit App" />
        
            <Button
                android:id="@+id/button4"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="Go third" />
        
            <Button
                android:id="@+id/button5"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="Go forth" />
        
            <Button
                android:id="@+id/button7"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="Go Fragment" />
        
        </LinearLayout>
        
  • 新增代码

    • FragmentActivity

      • package com.example.helloworld
        
        import android.os.Bundle
        import android.util.Log
        import android.widget.Button
        import androidx.activity.ComponentActivity
        import androidx.activity.compose.setContent
        import androidx.activity.enableEdgeToEdge
        import androidx.appcompat.app.AppCompatActivity
        import androidx.appcompat.widget.Toolbar
        import androidx.compose.foundation.layout.fillMaxSize
        import androidx.compose.foundation.layout.padding
        import androidx.compose.material3.Scaffold
        import androidx.compose.material3.Text
        import androidx.compose.runtime.Composable
        import androidx.compose.ui.Modifier
        import androidx.compose.ui.tooling.preview.Preview
        import androidx.fragment.app.Fragment
        import com.example.helloworld.AnotherRightFragment.Companion
        import com.example.helloworld.ui.theme.HelloWorldTheme
        
        class FragmentActivity : BaseActivity() {
            override fun onCreate(savedInstanceState: Bundle?) {
                super.onCreate(savedInstanceState)
                setContentView(R.layout.fragment_layout)
                ActivityCollector.addActivity(this)
        
                val button6: Button = findViewById(R.id.button6)        // button6 在 Fragmentlayout 里面的 Fragment 中,但是会报错
                button6.setOnClickListener {
                    replaceFragment(AnotherRightFragment())
                }
                replaceFragment(RightFragment())
        
        
                // 交互
                val leftFragment = LeftFragment.newInstance("a","")
                leftFragment.fragmentLog()
                val leftFragment2 = supportFragmentManager.findFragmentById(R.id.leftFrag) as? LeftFragment
                leftFragment2?.fragmentLog()
                val anotherFragment = AnotherRightFragment.newInstance("a","")
                anotherFragment.fragmentLog()
                val rightFragment = supportFragmentManager.findFragmentById(R.id.rightLayout) as? RightFragment
                rightFragment?.fragmentLog() // 没有打印
        
            }
        
            // 动态添加 Fragment
            private fun replaceFragment(fragment: Fragment) {
                val fragmentManager = supportFragmentManager
                val transaction = fragmentManager.beginTransaction()                    // 开启一个事务
                transaction.replace(R.id.rightLayout, fragment)      // 向对应 FrameLayout 添加 fragment 对象
                transaction.addToBackStack(null)
                transaction.commit()                                                    // 提交事务
            }
            fun fragmentLog() {
                Log.d("FragmentActivity", "call activity from fragment")
            }
        }
        
        
        
    • LeftFragment

      • package com.example.helloworld
        
        import android.os.Bundle
        import android.util.Log
        import androidx.fragment.app.Fragment
        import android.view.LayoutInflater
        import android.view.View
        import android.view.ViewGroup
        
        // TODO: Rename parameter arguments, choose names that match
        // the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
        private const val ARG_PARAM1 = "param1"
        private const val ARG_PARAM2 = "param2"
        
        /**
         * A simple [Fragment] subclass.
         * Use the [LeftFragment.newInstance] factory method to
         * create an instance of this fragment.
         */
        class LeftFragment : 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)
                }
        
                val fragActivity = activity as? FragmentActivity     // fragment 调用 activity
                fragActivity?.fragmentLog()
            }
        
            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)
            }
        
            fun fragmentLog() {
                Log.d("LeftFragment", "call fragment from activity")
            }
        
            companion object {
                /**
                 * Use this factory method to create a new instance of
                 * this fragment using the provided parameters.
                 *
                 * @param param1 Parameter 1.
                 * @param param2 Parameter 2.
                 * @return A new instance of fragment LeftFragment.
                 */
                // TODO: Rename and change types and number of parameters
                @JvmStatic
                fun newInstance(param1: String, param2: String) =
                    LeftFragment().apply {
                        arguments = Bundle().apply {
                            putString(ARG_PARAM1, param1)
                            putString(ARG_PARAM2, param2)
                        }
                    }
            }
        }
        
    • RightFragment

      • package com.example.helloworld
        
        import android.os.Bundle
        import android.util.Log
        import androidx.fragment.app.Fragment
        import android.view.LayoutInflater
        import android.view.View
        import android.view.ViewGroup
        
        // TODO: Rename parameter arguments, choose names that match
        // the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
        private const val ARG_PARAM1 = "param1"
        private const val ARG_PARAM2 = "param2"
        
        /**
         * A simple [Fragment] subclass.
         * Use the [RightFragment.newInstance] factory method to
         * create an instance of this fragment.
         */
        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)
            }
        
            fun fragmentLog() {
                Log.d("RightFragment", "call fragment from activity")
            }
        
            companion object {
                /**
                 * Use this factory method to create a new instance of
                 * this fragment using the provided parameters.
                 *
                 * @param param1 Parameter 1.
                 * @param param2 Parameter 2.
                 * @return A new instance of fragment RightFragment.
                 */
                // TODO: Rename and change types and number of parameters
                @JvmStatic
                fun newInstance(param1: String, param2: String) =
                    RightFragment().apply {
                        arguments = Bundle().apply {
                            putString(ARG_PARAM1, param1)
                            putString(ARG_PARAM2, param2)
                        }
                    }
            }
        }
        
    • AnotherRightFragment

      • package com.example.helloworld
        
        import android.os.Bundle
        import android.util.Log
        import androidx.fragment.app.Fragment
        import android.view.LayoutInflater
        import android.view.View
        import android.view.ViewGroup
        
        // TODO: Rename parameter arguments, choose names that match
        // the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
        private const val ARG_PARAM1 = "param1"
        private const val ARG_PARAM2 = "param2"
        
        /**
         * A simple [Fragment] subclass.
         * Use the [AnotherRightFragment.newInstance] factory method to
         * create an instance of this fragment.
         */
        class AnotherRightFragment : 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_another_right, container, false)
            }
        
            fun fragmentLog() {
                Log.d("AnotherRightFragment", "call fragment from activity")
            }
        
            companion object {
                /**
                 * Use this factory method to create a new instance of
                 * this fragment using the provided parameters.
                 *
                 * @param param1 Parameter 1.
                 * @param param2 Parameter 2.
                 * @return A new instance of fragment AnotherRightFragment.
                 */
                // TODO: Rename and change types and number of parameters
                @JvmStatic
                fun newInstance(param1: String, param2: String) =
                    AnotherRightFragment().apply {
                        arguments = Bundle().apply {
                            putString(ARG_PARAM1, param1)
                            putString(ARG_PARAM2, param2)
                        }
                    }
            }
        }
        
    • fragment_layout

      • <?xml version="1.0" encoding="utf-8"?>
        <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.helloworld.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="3" >
            </FrameLayout>
        
        </LinearLayout>
        
    • fragment_left

      • <?xml version="1.0" encoding="utf-8"?>
        <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
            xmlns:tools="http://schemas.android.com/tools"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            tools:context=".LeftFragment">
        
            <Button
                android:id="@+id/button6"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center_horizontal"
                android:text="Button" />
        </FrameLayout>
        
    • fragment_right

      • <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>
        
    • fragment_another_right

      • <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
            android:orientation="vertical"
            android:background="#ffff00"
            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 another right fragment"
                />
        
        </LinearLayout>
        

【最佳实践和Kotlin知识】

posted @ 2026-01-14 16:10  y丶innocence  阅读(10)  评论()    收藏  举报