Android应用开发------fragment

什么是fragment

        fragment是一种可嵌入在Activity中的UI片段,它能让程序更加合理和充分地利用大屏幕地空间,因而在平板上应用得非常广泛。其依靠activity实现,离开activity无法存活,也无法离开。可视为 “子 Activity”。

        简单举个例子,一个应用利用listView将所有地数据链接竖状排列展示,但是在平板上可能还有其余地空间,如果只是展示简短地数据链接,那么非常容易浪费空间,因为我们可以左侧展示数据连接,右边展示具体地详情页。这样空间就合理利用起来了。如图所示。

所以就产生了fragment,实现屏幕空间地合理利用化。

  • 核心作用
    • 实现界面模块化(如将 Activity 拆分为列表页、详情页 Fragment)。
    • 支持动态切换界面(如底部导航栏切换不同 Fragment),提升用户体验。
    • 适配不同屏幕尺寸(如平板端使用 Fragment 组合布局,手机端使用单 Fragment)。

1.fragment的简单使用

        实现效果,在Activity中嵌入两个fragment

1.首先,创建两个fragment,并让其平分屏幕空间,分别命名为left_fragment.xml和right_fragment.xml.

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>

        right_fragment.xml代码:

<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>
2.再分别新建fragment对应的类

        注意:此处代码中继承fragment,要继承自androidx.fragment.app.Fragment,它可以做到让Fragment的特性在所有Android系统版本中保持一致,系统内置的Fragment在Android9.0版本已经废除

        对inflate方法说明,inflater.inflate()方法将R.layout.left_fragment对应的 XML 布局文件实例化为 View 对象。参数false表示不要立即将加载的布局添加到container中,而是由系统稍后处理。这是 Fragment 的标准做法,避免重复添加 View 导致异常。View 被添加两次,进而引发IllegalStateException异常。

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)
 }
}

3.创建Anctivity

<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就被我们成功嵌入到activity中了。

2.动态添加fragment

        什么叫动态添加呢,它其实指的是在程序运行时动态添加到Activity中,根据实际情况去添加,而不是我们上面简单实现的固定嵌入。

以上面代码为例,那么我们再新增一个fragment,起名为anthoer_right_fragment.xml,代码的布局文件一致。

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

创建对应的fragment的类:

        

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

修改Activity中的布局文件,之前我们嵌入的是fragment,那么它就是固定死的,此处我们更改下方一个为framLayout。是Android中最简单的一种布局,所有的控件默认都会摆放在布局的左上角。由 于这里仅需要在布局里放入一个Fragment,不需要任何定位,因此非常适合使用 FrameLayout。

<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" >
     </FrameLayout>
</LinearLayout>

此处再Activity中向Framelayout添加内容,即可实现动态添加Fragment的功能。此处通过设置left_fragment.xml中的按钮的点击事件,然后调用replaceFragment方法将右侧fragment替换。

        对OnCreate()方法解释:首先Activity创建后,执行该方法,按顺序执行,加载布局,设置按钮定义事件(不立即执行),然后加载right_fragment.xml,

        对replaceFragment()方法解释:自定义方法,首先通过supportFragmentManager获取fragmentManager管理对象,然后开启事务,调用replace方法替换,传入要容纳frgament的容器视图,以及携带参数(即要放置的fragment),提交事务即可

        

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

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

3.在fragment中实现返回栈

在 Android 开发中,Fragment 返回栈是由 FragmentManager 管理的一个后进先出(LIFO)的 Fragment 事务队列。它的主要作用是:

 
  • 允许用户通过点击「返回键」回退到之前显示的 Fragment
  • 保存 Fragment 切换的历史记录,避免重复创建 Fragment 实例
  • 实现类似 Activity 栈的导航逻辑,但更轻量级
  1. 栈的结构
    返回栈中存储的是 Fragment 事务(Transaction),而非 Fragment 本身。每个事务记录了添加、替换或移除 Fragment 的操作。

如下述代码实现返回栈

class MainActivity : AppCompatActivity() {
 ...
     private fun replaceFragment(fragment: Fragment) {
         val fragmentManager = supportFragmentManager
         val transaction = fragmentManager.beginTransaction()
         transaction.replace(R.id.rightLayout, fragment)
         transaction.addToBackStack(null)// 可选参数:栈条目标签
         transaction.commit()
     }
}

出栈行为

  • 用户点击返回键时,栈顶事务会被弹出,系统回退到前一个状态
  • 出栈时会触发 Fragment 的生命周期回调(如 onDestroyView()onCreateView()
  • 若栈为空,返回键会退出 Activity

4.fragment和activity之间的交互

此处说明,因为fragment依赖activity,并且activity需要fragment实现多样性,合理使用屏幕等。两者联系紧密,那么肯定离不开交互,那么如何交互呢

1.在activity中获取fragment的实例:
了方便FragmentActivity之间进行交互,FragmentManager提供了一个类似于
findViewById()的方法,专门用于从布局文件中获取Fragment的实例
val fragment = supportFragmentManager.findFragmentById(R.id.leftFrag) as LeftFragment
2.在fragment中获取activity实例
在每个Fragment中都可以通过调用getActivity()方法来得到 和当前Fragment相关联的Activity实例,这里由于getActivity()方法有可能返回null,因此我们需要先进行一个判空处理。有了
Activity的实例
另外当Fragment 中需要使用Context对象时,也可以使用getActivity()方法,因为获取到的Activity本身就 是一个Context对象。
if (activity != null) {
 val mainActivity = activity as MainActivity
}
3.fragment和fragment交互
首先在一个Fragment中 可以得到与它相关联的Activity,然后再通过这个Activity去获取另外一个Fragment的实例, 这样就实现了不同Fragment之间的通信功能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Java失业转安卓

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值