整理之Fragment

Posted lizhenxin

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了整理之Fragment相关的知识,希望对你有一定的参考价值。

基础

生命周期

执行层次 退
创建与销毁 onAttach -> onCreate -> onCreateView -> onActivityCreate onDestroyView -> onDestroy -> OnDetach
是否可见 onStart() onStop()
是否在前台(可交互) onResume() onPause()

动态使用

val fragment = Fragment().apply {
    tag = "NEW_TAG"
}
val fragmentManager : FragmentManager = supportFragmentManager
val transcation : Transcation = fragmentManager.beginTranscation()
transcation.replace(R.id.container, fragment)
transcation.add(R.id.container, fragment)
transcation.addToBackStack("StackName")
transcation.detach(fragment)
transcation.hide(fragment)              //隐藏,但未销毁
transcation.show(Fragment fragment)     //显示之前隐藏的Fragment
transcation.commit()

其他基本操作

Activity中findFragmentById 或 findFragmentByTag 获取 activity 中存在的 fragment 的实例
popBackStack (模拟用户点击返回按钮操作)将 fragment 从返回栈中弹出
addOnBackStackChangedListener() 注册一个监听返回栈改变的监听器
Fragment中requireActivity()得到所属activity实例

Activity向Fragment传递参数

1.通过argument传递bundle

const val KEY_DATA = "_KEY_DATA_"
open class TestFragemnt private constractor() : Fragment {
    companion object {
        fun newInstance(data: String) = TestFragment().apply {
            argument = Bundle().apply {
                putString(KEY_DATA, data)
            }
        }
    }
    
    @Override
    fun onActivityCreate(saveInstanceState : Bundle) {
        val data = argument!!.get(KEY_DATA)
    }
}
//调用TestFragment.newInstance("DATA")获取Fragment实例
//或者直接:
class TestFragemnt : Fragment {
    @Override
    fun onActivityCreate(saveInstanceState : Bundle) {
        val data = argument!!.get(KEY_DATA)
    }
}
val fragemnt = Fragment().apply {
    argument = Bundle().apply {
        putString(KEY_DATA, data)
    }
}

使用Navigation导航

此时以“导航”为单位描述一堆fragment,包括一堆fragment和之间的通路。导航会被放到一个容器(android:name="androidx.navigation.fragment.NavHostFragment"的fragment)中使用。

0.添加依赖

implementation 'androidx.navigation:navigation-fragment-ktx:2.1.0'
implementation 'androidx.navigation:navigation-ui-ktx:2.1.0'

1.创建一堆Fragment

2.创建导航文件: res中创建navigation文件夹,内部创建main_nav.xml导航文件,文件中设置页面导航:

<navigation 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:id="@+id/main_nav"
    app:startDestination="@id/mainFragment">
    <!--startDestination属性是导航的起点,会被直接添加到容器中-->
    <fragment
        android:id="@+id/mainFragment"
        android:name="com.example.navigationtest.MainFragment"
        android:label="fragment_main"
        tools:layout="@layout/fragment_main" >
        <action 
            android:id="@+id/action_mainFragment_to_detailFragment"
            app:destination="@id/detailFragment" />
        <!--action为导航方向,destination为目标fragment-->
        <action
            android:id="@+id/action_mainFragment_to_otherFragment"
            app:destination="@id/otherFragment" />
    </fragment>

    <fragment
        android:id="@+id/detailFragment"
        android:name="com.example.navigationtest.DetailFragment"
        android:label="fragment_detail"
        tools:layout="@layout/fragment_detail" />

    <fragment
        android:id="@+id/otherFragment"
        android:name="com.example.navigationtest.OtherFragment"
        android:label="fragment_other2"
        tools:layout="@layout/fragment_other2" />
</navigation>

3.容器中装载导航文件

<fragment
        android:id="@+id/fragment"
        android:name="androidx.navigation.fragment.NavHostFragment"
        android:layout_width="0dp"
        android:layout_height="0dp"
        app:defaultNavHost="true"
        app:navGraph="@navigation/main_nav" />
<!--name属性设置为NavHostFragment表示为导航的容器,navGraph为导航文件的id-->

4.使用导航

//获取控制器
val controller = Navigation.findControllder(this, R.id.fragment)    //Activity中
val controller = Navigation.findNavController(view) //fragment中。view所在fragmnet在控制器中
//使用导航
controller.navigate(R.id.action_mainFragment_to_otherFragment)
controller.navigate(R.id.action_mainFragment_to_detailFragment, bundle)     //带参数
controller.navigateUp()     //导航到上一层

5.添加左上角返回箭头

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

    mNavController = Navigation.findNavController(this, R.id.fragment)
    NavigationUI.setupActionBarWithNavController(this, mNavController)
}
override fun onSupportNavigateUp(): Boolean {
    return mNavController.navigateUp()
}

6.生命周期会走完全程(完全销毁完全创建),但是会先创建并显示新的 再 销毁旧的

使用ViewPager2导航

0.添加依赖

implementation 'androidx.viewpager2:viewpager2:1.0.0'
implementation 'com.google.android.material:material:1.2.0-alpha05'

1.创建ViewPager2布局

<com.google.android.material.tabs.TabLayout
    android:id="@+id/tablayout"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">
    <com.google.android.material.tabs.TabItem
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Monday" />
    <com.google.android.material.tabs.TabItem
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Tuesday" />
    <com.google.android.material.tabs.TabItem
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Wednesday" />
</com.google.android.material.tabs.TabLayout>
<View
    android:id="@+id/divider"
    android:layout_width="match_parent"
    android:layout_height="1dp"
    android:background="?android:attr/listDivider" />
<androidx.viewpager2.widget.ViewPager2
    android:id="@+id/view_pager"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

2.创建一堆Fragment

3.将Fragment加入到ViewPager中:

view_pager.adapter = object : FragmentStateAdapter(this)    {
    override fun getItemCount() = 3
    override fun createFragment(position: Int) = when(position) {
        0 -> ScaleFragment()
        1 -> RotateFragment()
        else -> TranslateFragment()
    }
}

4.写入TabLayout标题

val tabConfigurationStrategy = object : TabLayoutMediator.TabConfigurationStrategy {
    override fun onConfigureTab(tab: TabLayout.Tab, position: Int) {
        tab.text = when(position) {
            0 -> "缩放"
            1 -> "旋转"
            else -> "平移"
        }
    }
}

5.链接Tablayout和ViewPager2

TabLayoutMediator(tablayout, view_pager, tabConfigurationStrategy).attach()

6.生命周期变化为:pause -> resume

以上是关于整理之Fragment的主要内容,如果未能解决你的问题,请参考以下文章

整理之Fragment

Android之Fragment的优点和作用

如何通过代码设置片段标签?

Android 片段生命周期

从片段中的相机拍照

后按时从 onCreate() 开始片段