5.2--Fragment 的使用方式

之前的项目我们一直用手机模拟器来运行,这次我们来用平板模拟器来运行,我们来创建一个平板模拟器Pixel C ,也是Android 10版本,然后我们来创建一个新的项目 FragmentTest,开始我们的Fragment 探(tian)索(xiu)之(sao)旅(cao)吧(zuo)!

5.2.1 Fragment 的简单用法

先在一个最简单的Fragment 示例来练练手,在一个Activity 中添加两个Fragment ,让这两个Fragment 平分Activity 的空间。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:layout_width="0dp"
        android:layout_height="match_parent"
        android:name=""
        android:layout_weight="1"
        />
    <fragment
        android:id="@+id/rightFrag"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:name=""
        android:layout_weight="1"
        />
</LinearLayout>

这里 android:name 的值是我们创建的Fragment 类的路径,由于我们还没创建Fragment 类,接下来我们就开始创建吧。

首先我们创建左侧的left_fragment.xml 布局文件:

<?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">
    
    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:text="Button"
        />
</LinearLayout>

屏幕水平居中显示一个Button 按钮。

 

接下来是right_fragment.xml:

<?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">
    
    <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,并且背景设置了绿色。

接下来就需要创建Fragment 类来,在Fragment 类的相应生命周期中加载布局文件。

LeftFragment:

class LeftFragment : Fragment() {

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

RightFragment:

class RightFragment : Fragment() {

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

这样我们就完成了Fragment 的基本创建了,还记得刚才说的 android:name 属性吗,我们把这LeftFragment 和 RightFragment 的路径添加进去就可以运行了。

这就是静态注册Fragment!

 

5.2.2 动态添加Fragment

接下来我们改学习动态添加Fragment了,这是公司开发中必不可少的知识点,可以根据不同的具体情况来动态的添加Fragment 而不是像静态一样固定的使用一个Fragment。

 我们左侧的fragment 还使用之前的静态fragment ,我们来让右侧的Fragment 变为动态注册,点击左侧的Button 按钮来切换右侧的Fragment,那么我们来新建一个右侧的fragment 布局文件:

another_right_fragment.xml:

<?xml version="1.0" encoding="utf-8"?>
<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>

然后我们创建一个AnotherRightFragment 类:

class AnotherRightFragment :Fragment() {

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

这样我们准备工作就做完了,接下来改更改activity_main.xml 布局文件了:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:layout_width="0dp"
        android:layout_height="match_parent"
        android:name="com.example.fragmenttest.LeftFragment"
        android:layout_weight="1"
        />
    <FrameLayout
        android:id="@+id/rightLayout"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="1"
        />
</LinearLayout>

我们把右侧的fragment 换成 FrameLayout 了,这是布局中最简单的一种布局,所以的组件都会放在左上角,由于我们只需要放置一个fragment ,不需要任何定位,直接充满FrameLayout  就可以了,这里的fragment 需要在代码中动态添加。

接下来我们进入MainActivity 中进行动态添加:

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 supportFragmentManager = supportFragmentManager
        val beginTransaction = supportFragmentManager.beginTransaction()
        beginTransaction.replace(R.id.rightLayout,fragment)
        beginTransaction.commit()
    }
}

重点就是我们创建的 replaceFragment 函数:

1、我们通过getSupportFragmentManager 拿到了Fragment 管理者

2、通过supportFragmentManager 由拿到了 Fragment 的事务 beginTransaction

3、beginTransaction 调用了replace 函数

4、传入了容器id和fragment 实例

5、最后commit 提交事务完成。

Ps:beginTransaction 调用 add函数可以进行添加fragment,然后调用show 或hide 函数进行展示也隐藏,而replace 函数则是清空布局内的所有Fragment 然后只显示我们传入的Fragment,每次使用replace 都会重新加载生命周期。

5.2.3 在Fragment 的实现返回栈 

我们在一个事务 提交之前调用 addToBackStatck 函数就可以将一个事务添加到返回栈中。这样使用每次使用返回键都会返回到上一个事务中。

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

5.2.4 Fragment 和Activity 之间的交互

这两个独立的类我们怎么相互交互呢?来看看Activity 与 Fragment 的交互,如何拿到fragment 的实例:

在Activity 通过此方式可以拿到fragment的实例,一般来说我们创建了Fragment 就已经拿到了实例了。。。。

supportFragmentManager.findFragmentByTag()
supportFragmentManager.findFragmentById()

还有一种简化的写法,Kotlin 也对 findFragmentViewById 进行了扩展,允许我们直接使用id 名称来自动获取响应的fragment 实例:

val fragment =  leftFrag as LeftFragment

掌握了 在Activity 中拿到Fragment 那么下面就是如何从Fragment 中拿到所属Activity了,直接在Fragment 类中调用getActivity 函数就能拿到所属Activity ,就这么简单, 注意由于getActivity 有可能拿到null 空,所以逻辑代码要做非空判断,比如 所属Activity 被系统回收,或者旋转屏幕等等,都会暂时的丢失所属Activity。

不同的Fragment 之间也是可以通讯的,前提是他们所属一个Activity ,fragment  拿到所属activity,所属activity 在拿到想要通讯的fragment 实例就可以了。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值