Android開發(fā)(29)——Fragment和Navigation

本節(jié)內(nèi)容

1.簡(jiǎn)述

2.Fragment的創(chuàng)建

3.添加動(dòng)畫

4.Fragment數(shù)據(jù)傳遞

5.顯示HomeFragment

6.添加toolBar關(guān)聯(lián)

7.設(shè)置ButtonNavigationView

8.抽屜布局drawLayout

9.頁面切換和數(shù)據(jù)傳遞

一、簡(jiǎn)述
1.對(duì)于MVVM來說,View指可交互的視圖。ViewModel一般是管理數(shù)據(jù)的,通常是MutableLiveData。Model就是數(shù)據(jù)模塊,通常需要一個(gè)Repository來聯(lián)系Model和ViewModel。
2.Activity:管理一個(gè)界面的生命周期。
3.Fragment :可以理解為一個(gè)小型的Activity。一個(gè)手機(jī)app,用戶在使用的時(shí)候,手機(jī)屏幕上只會(huì)顯示一個(gè)頁面,但是會(huì)有很多不同的頁面進(jìn)行切換。Fragment就相當(dāng)于每一個(gè)小的頁面,而管理這些頁面的就是ViewPager。當(dāng)用戶滑動(dòng)頁面時(shí),ViewPager就會(huì)把當(dāng)前這個(gè)Fragment移出去,然后換下一個(gè)新的Fragment進(jìn)來。
二、Fragment的創(chuàng)建
1.Fragment 表示應(yīng)用界面中可重復(fù)使用的一部分。Fragment 定義和管理自己的布局,具有自己的生命周期,并且可以處理自己的輸入事件。Fragment 不能獨(dú)立存在,而是必須由 Activity 或另一個(gè) Fragment 托管。Fragment 的視圖層次結(jié)構(gòu)會(huì)成為宿主的視圖層次結(jié)構(gòu)的一部分,或附加到宿主的視圖層次結(jié)構(gòu)。
2.FragmentActivity之間的關(guān)系:
  • Fragment依賴于Activity
  • Fragment 就是Activity中不同功能的分離,它有自己的生命周期。
3.Fragment的生命周期。
  • onAttach():當(dāng)Fragment被添加到activity中時(shí)調(diào)用
  • onCreate():創(chuàng)建Fragment時(shí)調(diào)用
  • onCreateView():Fragment具體顯示的內(nèi)容 -xml
  • onActivityCreated():當(dāng)Activity創(chuàng)建好了之后,才會(huì)調(diào)用這個(gè)方法。相對(duì)Fragment進(jìn)行操作的時(shí)候,就在這個(gè)方法里面操作。
Fragment生命周期
4.靜態(tài)使用Fragment:
  • (1)在Activity對(duì)應(yīng)的xml中添加Fragment組件
 <Fragment
        android:id="@+id/mContainer"
        android:name="com.example.fragment.LoginFragment"
        android:layout_width="match_parent"
        android:layout_height="200dp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
  • (2)自定義一個(gè)類繼承于fragment。比如我們創(chuàng)建一個(gè)類,名為LoginFragment,繼承于Fragment,然后重寫對(duì)應(yīng)的生命周期方法。onCreateView方法必須實(shí)現(xiàn)。
class LoginFragment :Fragment() {
     override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        return inflater.inflate(R.layout.fragmentlogin,container,false)
    }
}
  • (3)創(chuàng)建xml文件 進(jìn)行頁面布局。創(chuàng)建一個(gè)fragmentlogin.xml文件,自己隨便布局一下。
  • (4)使用LayoutInflater解析布局文件.
return inflater.inflate(R.layout.fragmentlogin,container,false)
  • (5)在xml中設(shè)置fragment對(duì)應(yīng)的name屬性。在activity_xml的<Fragment>里面設(shè)置。
android:name="com.example.fragment.LoginFragment"
5.在activity.xml中添加幾個(gè)按鈕。最上方是fragment。
xml布局
5.動(dòng)態(tài)使用Fragment。
  • (1)在Activity對(duì)應(yīng)的xml中添加FrameLayout組件.
<FrameLayout
        android:id="@+id/mContainer"
        android:layout_width="match_parent"
        android:layout_height="200dp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
  • (2)自定義一個(gè)類繼承于fragment(3)重寫對(duì)應(yīng)的生命周期方法 onCreateView(4)創(chuàng)建xml文件 進(jìn)行頁面布局(5)用layoutInflater解析布局文件
  • (6)使用FragmentManager管理fragment的切換, MainActivity中使用supportFragmentManager 獲取FragmentManager,獲取FragmentTransaction對(duì)象。
val fragmentTransaction = supportFragmentManager.beginTransaction()
fragmentTransaction.add(R.id.mContainer,LoginFragment())
fragmentTransaction.commit()
  • mContainer是activtiy里面FrameLayout容器的id。
運(yùn)行程序,得到以下結(jié)果。
運(yùn)行結(jié)果
6.新建一個(gè)Fragment,然后布局一下對(duì)應(yīng)的xml文件。隨便布局一下。
7.然后在MainActivity里面實(shí)現(xiàn)一下mReplace的監(jiān)聽事件,當(dāng)我們點(diǎn)擊REPLACE按鈕的時(shí)候,它就會(huì)直接替換。
 mReplace.setOnClickListener { 
supportFragmentManager
.beginTransaction()
.replace(R.id.mContainer,RegistFragment("jack"))
.commit()
        }
點(diǎn)擊replace按鈕之后
三、添加動(dòng)畫
1.前面點(diǎn)擊按鈕完了之后,文本切換了,但是點(diǎn)擊下方的返回按鈕時(shí)并不會(huì)回到原來的頁面,即剛剛那個(gè)fragment并不在棧里面。如果想要點(diǎn)擊返回時(shí)回到之前的界面,那么可以添加一個(gè).addToBackStack(null),這樣就可以讓它在棧里面了。
我們通過實(shí)現(xiàn)add按鈕的點(diǎn)擊事件來展示一下是如何使用的。
 mAdd.setOnClickListener {
 supportFragmentManager
.beginTransaction()
.add(R.id.mContainer,RegistFragment("rose"))
.addToBackStack(null)
.commit()
        }
  • 這個(gè)函數(shù)的意思就是把它添加到回退棧里面。
2.給這個(gè)頁面切換添加動(dòng)畫效果,首先添加一個(gè)anim包,然后添加動(dòng)畫的資源文件。
目錄
  • slide_in.xml
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="500">
    <translate android:fromXDelta="100%" android:toXDelta="0%"/>
</set>
  • slide_out.xml
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="500">
    <translate android:fromXDelta="0%" android:toXDelta="-100%"/>
</set>
  • 在MainActivity里面用上這個(gè)動(dòng)畫。
.setCustomAnimations(R.anim.slide_in,R.anim.pop_out)
3.重新布局一下fragmentlogin頁面,如下圖所示。
fragmentlogin頁面
4.重新布局一下activity_main.xml,把那幾個(gè)按鈕都刪掉,只留下一個(gè)FrameLayout,然后把它的高設(shè)為0dp,寬度設(shè)為match_parent。
5.實(shí)現(xiàn)上面LOGIN按鈕的點(diǎn)擊事件,要在LoginFragment類里面實(shí)現(xiàn)。重寫一下這個(gè)類里面的onActivityCreated方法,然后在里面先獲取子控件,再實(shí)現(xiàn)其點(diǎn)擊事件。
   override fun onActivityCreated(savedInstanceState: Bundle?) {
        super.onActivityCreated(savedInstanceState)
        val btn= view?.findViewById<Button>(R.id.mLogin)
        btn?.setOnClickListener {
            fragmentManager?.let {
                    it.beginTransaction()
                    .setCustomAnimations(R.anim.slide_in,R.anim.slide_out)
                    .replace(R.id.mContainer,RegistFragment("jack"))
                    .addToBackStack(null)
                    .commit()
            }
        }
    }
6.在MainActivity里面使用一下supportFragmentManager
supportFragmentManager
            .beginTransaction()
            .replace(R.id.mContainer,LoginFragment())
            .commit()
7.如果這樣的話,點(diǎn)擊返回按鈕并沒有動(dòng)畫。想要點(diǎn)擊返回按鈕也有動(dòng)畫的話,那么就要再在anim包里面添加兩個(gè)動(dòng)畫,然后把它們添加到.setCustomAnimations里面
.setCustomAnimations(R.anim.slide_in,R.anim.slide_out,R.anim.pop_in,R.anim.pop_out)
四、Fragment數(shù)據(jù)傳遞
1.給ResgisterFragment添加一個(gè)構(gòu)造方法
class RegistFragment ( val name:String):Fragment()
2.給fragmentregister.xml添加一個(gè)TextView,然后在ResgisterFragment類里面實(shí)現(xiàn)onActivityCreated方法
override fun onActivityCreated(savedInstanceState: Bundle?) {
        super.onActivityCreated(savedInstanceState)
        view?.findViewById<TextView>(R.id.mTextView)?.text  =name
    }
3.在LoginFragmentonActivityCreated方法里面先把EditText里的內(nèi)容解析出來。
val nameTv = view?.findViewById<EditText>(R.id.mNameTv)
  • 然后在replace方法里面把解析到的內(nèi)容傳進(jìn)去。
.replace(R.id.mContainer,RegistFragment(nameTv?.text.toString()))
  • 這樣數(shù)據(jù)就能傳遞過去了。但是一旦把手機(jī)旋轉(zhuǎn)一下,就會(huì)報(bào)錯(cuò)。因?yàn)樾D(zhuǎn)屏幕之后,Activity重新走了一遍生命周期,所以Fragment也要重新創(chuàng)建一下。但是它重新創(chuàng)建的時(shí)候需要我們給它的構(gòu)造函數(shù)添加一個(gè)參數(shù),可是我們給不了。如果手機(jī)不支持屏幕旋轉(zhuǎn)功能的話,那么就可以這樣寫。但是如果手機(jī)屏幕可以旋轉(zhuǎn),這樣就不行。
4.想要讓屏幕旋轉(zhuǎn)過來后數(shù)據(jù)也不會(huì)變的話,可以像下面一樣操作。使用View Model,但是一般情況下都不會(huì)這么用。
  • 先創(chuàng)建一個(gè)MyViewModel類繼承自ViewModel,然后在里面添加一個(gè)liveData類型的數(shù)據(jù)。
class MyViewModel:ViewModel() {
    var fragment:MutableLiveData<Fragment>?=MutableLiveData()
}
  • LoginFragment類里面的onActivityCreated方法里面,用rf來記錄數(shù)據(jù)。
  override fun onActivityCreated(savedInstanceState: Bundle?) {
        super.onActivityCreated(savedInstanceState)

        val btn= view?.findViewById<Button>(R.id.mLogin)
        val nameTv = view?.findViewById<EditText>(R.id.mNameTv)
        btn?.setOnClickListener {
            val rf = RegistFragment()
            val bundle = Bundle()
            bundle.putString("name",nameTv?.text.toString())
            rf.arguments = bundle

            val act = activity as MainActivity
            act.viewModel.fragment?.value = rf

            fragmentManager?.let {
                   it.beginTransaction()
                    .setCustomAnimations(R.anim.slide_in,R.anim.slide_out,R.anim.pop_in,R.anim.pop_out)
                       .replace(R.id.mContainer,rf)
                    .addToBackStack(null)
                    .commit()
            }
        }
  • 然后在MainActivity先懶加載一個(gè)變量,在onCreate方法把它解析出來。然后判斷它是不是空,如果是空的就把Fragment傳遞過去,否則就把它作為livedata進(jìn)行監(jiān)聽。
class MainActivity : AppCompatActivity() {
lateinit var viewModel:MyViewModel
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

         viewModel = ViewModelProvider(this,ViewModelProvider.NewInstanceFactory()).get(MyViewModel::class.java)
        if (viewModel.fragment?.value==null){
            viewModel.fragment?.value = LoginFragment()
        }
       viewModel.fragment?.observe(this, Observer {
           supportFragmentManager
               .beginTransaction()
               .replace(R.id.mContainer,it)
               .commit()
       })
   }
}
  • 最后屏幕轉(zhuǎn)過來數(shù)據(jù)也沒有改變。
屏幕旋轉(zhuǎn)后
5.傳數(shù)據(jù)用arguments來傳,但這還不是最好的寫法。
五、顯示homefragment
1.前情提要
  • NavController:管理界面切換。
  • NavGraph:導(dǎo)航圖。定義好了界面之間的跳轉(zhuǎn)。
2.因?yàn)槲覀円獙?shí)現(xiàn)在目的地之間傳遞數(shù)據(jù),所以在gradel的dependencies里面添加以下代碼。
def nav_version = "2.3.1"
classpath "androidx.navigation:navigation-safe-args-gradle-plugin:$nav_version"
3.我們要生成適用于 Kotlin 獨(dú)有的模塊的 Kotlin 代碼,那么就在第二個(gè)gradle里面添加以下代碼。
apply plugin: "androidx.navigation.safeargs.kotlin"
4.先創(chuàng)建一個(gè)名為HomeFragment的類,繼承自Fragment()。可以直接通過構(gòu)造方法把頁面id 傳過來,這樣就不需要在onCreateView里面再解析了。
class HomeFragment :Fragment(R.layout.fragment_home){
}
5.創(chuàng)建一個(gè)和上面這個(gè)類匹配的xml文件,取名fragment_home。隨意布局一下這個(gè)頁面,我的如下圖所示。給按鈕添加一個(gè)id。
fragment_home.xml布局
6.創(chuàng)建一個(gè)navGraph來管理頁面之間的跳轉(zhuǎn)。新建一個(gè)navigation的包,然后再創(chuàng)建一個(gè)navigation的xml文件。
文件目錄
  • 在fragment_home.xml中關(guān)聯(lián)一下HomeFragment類。
tools:context="HomeFragment"
  • 在nav_graph.xml中把fragment_home.xml文件添加進(jìn)來
nav_graph界面
7.完成這個(gè)新的demo我們需要完成以下工作:
  • Navigation Graph 導(dǎo)航圖,管理fragment之間的邏輯關(guān)系
  • NavigationFragment 容器
  • NavController 導(dǎo)航控制器,控制頁面之間的切換。
8.我們已經(jīng)完成了第一步,現(xiàn)在我們來完成第二步,添加容器。在activity_xml里面,拖動(dòng)containers的NavHostFragment過來,然后選擇nav_graph。
拖動(dòng)一個(gè)containers
9.當(dāng)它運(yùn)行起來,顯示的就是我們剛剛布局的那個(gè)頁面。
運(yùn)行結(jié)果
六、添加toolBar關(guān)聯(lián)navVontroller
1.在activity.xml中添加一個(gè)toolBar,并把fragment的頂部約束到toolBar的下方。
<androidx.appcompat.widget.Toolbar
        android:id="@+id/toolBar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@color/colorPurple"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        tools:ignore="MissingConstraints" />
2.然后我們?cè)贏ndroidManifest.xml中把theme改為NoActionBar。這樣就不會(huì)顯示系統(tǒng)自帶的Bar了。
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
3.在MainActivity里面添加一個(gè)導(dǎo)航控制器。
 private lateinit var navController:NavController
4.顯示toolBar里面的內(nèi)容。
  • 在onCreate里面獲取navController
     //獲取NavHostFragment對(duì)象
       val navHostFragment = supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as NavHostFragment
       //通過這個(gè)對(duì)象獲取對(duì)應(yīng)的navController
        navController = navHostFragment.findNavController()
  • 用自己的toolbar作為默認(rèn)ActionBar
setSupportActionBar(toolBar)
  • 這樣就可以顯示工程的名字了,之前是只有一個(gè)toolBar,沒有工程名字。
顯示工程名
5.給我們自己的toolBar設(shè)置一下主題。
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
6.但是這樣顯示的只是工程名字,并不是當(dāng)前fragment所對(duì)應(yīng)的label。想要讓它顯示的是fragment對(duì)應(yīng)的label的話,我們就要讓ActionBar 和NavController產(chǎn)生關(guān)聯(lián)。這樣的話,當(dāng)NavController切換的時(shí)候 會(huì)把對(duì)應(yīng)的Fragment的label顯示到actionbar
setupActionBarWithNavController(navController)
當(dāng)前fragment的label為Home
七、設(shè)置BottomNavigationView
1.新建一個(gè)SearchFragment類繼承自Fragment,再創(chuàng)建一個(gè)fragment_sreach的xml文件。然后隨便布局一下。
class SearchFragment :Fragment(R.layout.fragment_sreach){
}
2.在nav_graph里面把serach_fragment添加進(jìn)去。在那之前記得在search_fragment里面把以下代碼添加進(jìn)去。
tools:context=".SearchFragment"
nav_graph.xml
3.在activity_main.xml的底部添加導(dǎo)航條。然后自行約束一下。
布局之后的結(jié)果
4.這樣添加的導(dǎo)航條什么內(nèi)容都沒有,要想在里面添加內(nèi)容就需要一個(gè)menu。所以我們new一個(gè)resource file,類型為menu,然后在里面添加一個(gè)xml文件。
menu文件
5.在drawable里面右擊一下,new一個(gè)vector Asset,這樣就可以添加系統(tǒng)為我們提供的圖片。search圖標(biāo)如下圖所示:
search圖標(biāo)
6.menu里的xml文件代碼如下圖所示。id是nav_graph里面每個(gè)fragment的id。
<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:id="@+id/homeFragment"
        android:title="Home"
        android:icon="@drawable/ic_home"/>

    <item android:id="@+id/searchFragment"
        android:title="Search"
        android:icon="@drawable/ic_search"/>
</menu>
7.在activity_main.xml中的BottomNavigationView里面添加以下代碼,把menu加進(jìn)去,這樣它就會(huì)顯示內(nèi)容了。
app:menu="@menu/bottom_nav_menu"
BottomNavigationView顯示的內(nèi)容
8.關(guān)聯(lián)bottomNavigationView和NavController,在MainActivity里面。這樣設(shè)置完了之后,點(diǎn)擊search按鈕就能自動(dòng)切換頁面了。
bottom_nav_view.setupWithNavController(navController)
Home主界面
點(diǎn)擊search切換頁面
9.配置程序的頂層頁面,頂層之間的切換,沒有返回箭頭。如果不添加以下代碼。第二個(gè)頁面的toolBar就會(huì)默認(rèn)添加一個(gè)返回箭頭,意思是把第一個(gè)頁面作為主頁面。這個(gè)意思就是讓這兩個(gè)頁面處于同等地位,沒有什么主次之分。
val config:AppBarConfiguration = AppBarConfiguration(
        setOf(R.id.homeFragment,R.id.searchFragment)
    )
setupActionBarWithNavController(navController,config)
八、抽屜布局drawerLayout
1.在activity_main.xml中,先把最外層設(shè)置為抽屜布局
androidx.drawerlayout.widget.DrawerLayout
  • 在里面創(chuàng)建一個(gè)ConstraintLayout,然后把toolBar,BottomNavigationView,和中間的fragment都copy進(jìn)去。
2.在drawerLayout里面添加一個(gè)NavigationView,并設(shè)置id。gravity設(shè)為start,表示在左邊。
 <com.google.android.material.navigation.NavigationView
        android:id="@+id/nav_view"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:gravity="start"/>
  • 這樣運(yùn)行起來就是以下效果。因?yàn)闆]有添加內(nèi)容,所以是空的。
加了NavigationView
3.要想讓它顯示內(nèi)容的話,我們就需要一個(gè)menu,直接把我們前面設(shè)置的menu加進(jìn)去即可。
app:menu="@menu/bottom_nav_menu"
4.但是這樣并不能點(diǎn)擊,所以我們要關(guān)聯(lián)NavigationView 和NavController
nav_view.setupWithNavController(navController)
  • 這樣旁邊不僅有標(biāo)簽欄,而且還可以點(diǎn)擊進(jìn)行跳轉(zhuǎn)。
左側(cè)菜單欄
5.給這個(gè)菜單欄添加一個(gè)icon,這樣點(diǎn)擊圖標(biāo)也可以把它拉出來。只需要在前面的config里面再添加一下drawerLayout的id即可。
val config:AppBarConfiguration = AppBarConfiguration(
        setOf(R.id.homeFragment,R.id.searchFragment),
        drawer_layout
    )
  • 添加之后icon圖標(biāo)也顯示出來了
icon圖標(biāo)
6.但是此時(shí)的icon點(diǎn)擊之后是沒有效果的。想要點(diǎn)擊它之后就彈出菜單的話,我們需要先把config定義在外部。
 private  lateinit var config:AppBarConfiguration
  • 然后在實(shí)現(xiàn)一下onSupportNavigateUp方法。
override fun onSupportNavigateUp(): Boolean {
        return navController.navigateUp(config)
    }
  • 這樣點(diǎn)擊這個(gè)圖標(biāo),菜單欄就會(huì)顯示出來了。
九、頁面切換和數(shù)據(jù)傳遞
1.添加一個(gè)login的fragment,包括代碼和xml布局。代碼如下圖所示:
class LoginFragment :Fragment(R.layout.fragment_login){
}
  • xml就隨便布局一下。然后設(shè)置一下context。再把它加進(jìn)nav_graph。讓homeFragment指向loginFragment。這樣點(diǎn)擊按鈕,就會(huì)跳轉(zhuǎn)到這個(gè)頁面來。
指向關(guān)系
2.在HomeFragment里面給按鈕添加點(diǎn)擊事件。這樣就可以直接切換。
override fun onActivityCreated(savedInstanceState: Bundle?) {
        super.onActivityCreated(savedInstanceState)
        button_login.setOnClickListener {
            val action:NavDirections= HomeFragmentDirections
                .actionHomeFragmentToLoginFragment()
            findNavController().navigate(action)
        }
    }
3.但是這樣跳轉(zhuǎn)很不美觀,所以我們可以添加一些動(dòng)畫效果。slide_in如下圖所示,其他的都差不多。一共有四個(gè)動(dòng)畫。
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="500">
    <translate
        android:fromXDelta="100%"
        android:toXDelta="0%"
        />
</set>
4.然后在nav_graph里面把這幾個(gè)動(dòng)畫添加進(jìn)去。
添加動(dòng)畫
5.添加一個(gè)WelcomeFragment和xml文件,隨便布局一下,然后再和WelcomeFragment關(guān)聯(lián)一下。
fragmenr_welcome.xml
6.把它添加進(jìn)nav_graph,然后和loginFragment關(guān)聯(lián)一下。
關(guān)聯(lián)結(jié)果
7.關(guān)聯(lián)完了之后,再把之前的動(dòng)畫添加進(jìn)去。直接到代碼中,把之前的哪那些動(dòng)畫代碼copy進(jìn)去即可。
           app:enterAnim="@anim/slide_in"
            app:exitAnim="@anim/slide_out"
            app:popEnterAnim="@anim/pop_in"
            app:popExitAnim="@anim/pop_out" 
8.然后在LoginFragment里面實(shí)現(xiàn)按鈕的點(diǎn)擊事件。
override fun onActivityCreated(savedInstanceState: Bundle?) {
        super.onActivityCreated(savedInstanceState)
        button_confirm.setOnClickListener {
            val action = LoginFragmentDirections.actionLoginFragmentToWelcomeFragment()
            findNavController().navigate(action)
        }
    }
9.如果想要傳遞數(shù)據(jù)怎么辦呢,首先在nav_graph里面選中welcomeFragment,然后點(diǎn)擊Arguments里面的+號(hào)
添加接收的數(shù)據(jù)
  • 然后在LoginFragment里面把數(shù)據(jù)傳遞進(jìn)去
val action = 
LoginFragmentDirections.actionLoginFragmentToWelcomeFragment(name_edit_view.text.toString())
10.在WelcomeFragment里面獲取傳遞過來的參數(shù)值。
class WelcomeFragment :Fragment(R.layout.fragment_welcome){
    val args:WelcomeFragmentArgs by NavArgs()

    override fun onActivityCreated(savedInstanceState: Bundle?) {
        super.onActivityCreated(savedInstanceState)
        name_text_view.text=args.Username
    }

}
  • 或者直接使用arguments
 name_text_view.text = arguments?.getString("username")
  • 這樣點(diǎn)擊之后,值就會(huì)傳遞過去。Jack是我在前面一個(gè)框內(nèi)寫入的內(nèi)容。
Jack傳過去了
11.如果我們想讓輸入的內(nèi)容也變?yōu)閠oolBar的標(biāo)題的話,那么就在nav_graph中屬于welcomeFragment的代碼里面修改一下。這樣就會(huì)顯示為標(biāo)題了。
android:label="{username}"
  • 效果如下圖所示:
效果圖
12.將welcome界面和home界面關(guān)聯(lián)起來,當(dāng)點(diǎn)擊back按鈕的時(shí)候會(huì)立刻跳轉(zhuǎn)到Home頁面。在WelcomeFragment里面,實(shí)現(xiàn)按鈕的點(diǎn)擊事件。
 button_back.setOnClickListener {
            findNavController().navigate(
                WelcomeFragmentDirections.actionWelcomeFragmentToHomeFragment()
            )
        }
13.如果用戶成功登錄了的話,那么按底下的返回就不會(huì)跳到上一個(gè)頁面,而是跳到主界面。我們就在nav_graph里面,給loginFragment和WelcomeFragment之間那根線,設(shè)置一下它的popBehavior
設(shè)置
  • 這樣在最后一次登錄了的時(shí)候,點(diǎn)擊下方的回退,back按鈕,就會(huì)直接到home主頁面了。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容