Advanced development components Jetpack learning

1 Data storage and display----ViewModel

add dependency

    //加入ViewModel的依赖
    implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'

When the Activity interface needs to be reversed or returned, the data of the current interface needs to be saved and then restored
.

1 Customize the ViewModel class of the interface, inherit ViewModel, and turn the data needed by the current interface into attributes of this class.

import androidx.lifecycle.ViewModel
//有参构造进行数据的修改
class MainViewModel(countVal:Int): ViewModel() {
    
    
    var count=countVal
}

2 If you need to manually assign values ​​to the data inside, you need to use ViewModelProvider.Factory to achieve

package com.example.viewmodletest

import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
//重写方法,并且将返回值返回
class MainViewModelFactory(var countVal:Int):ViewModelProvider.Factory {
    
    

    override fun <T : ViewModel?> create(modelClass: Class<T>): T {
    
    
        return MainViewModel(countVal) as T
    }

}

3 Obtain the viewModel instance in the interface, bind the factory to manually assign data

package com.example.viewmodletest

import android.content.Context
import android.content.SharedPreferences
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.Button
import android.widget.ShareActionProvider
import android.widget.TextView
import androidx.core.content.edit
import androidx.lifecycle.ViewModelProvider

class MainActivity : AppCompatActivity() {
    
    
    private lateinit var textView: TextView
    private lateinit var btnadd:Button
    private lateinit var btnless:Button
    private lateinit var clearZero:Button

    private lateinit var viewModel: MainViewModel
    private lateinit var sp:SharedPreferences

    private var countVal=0
    override fun onCreate(savedInstanceState: Bundle?) {
    
    
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        initData()
        //检测当前Activity的生命周期
        //lifecycle.addObserver(MyObserver())
        btnadd.setOnClickListener(){
    
    
            viewModel.count++
            refreshData()
        }
        btnless.setOnClickListener(){
    
    
            viewModel.count--
            refreshData()
        }
        //利用构造方法将数据清零
        clearZero.setOnClickListener(){
    
    
            viewModel.count=0
            refreshData()
        }
        refreshData()
    }
    private fun initData(){
    
    
        textView=findViewById(R.id.count)
        btnadd=findViewById(R.id.countSum)
        btnless=findViewById(R.id.countless)
        clearZero=findViewById(R.id.clearZero)
        //获取当前界面的ViewModle
        //viewModel=ViewModelProvider(this).get(MainViewModel::class.java)
        sp=getPreferences(Context.MODE_PRIVATE)
        //从存储的里面取得数据,如果没有数就默认为0
        countVal=sp.getInt("countVal",0)
        viewModel=ViewModelProvider(this,MainViewModelFactory(countVal)).get(MainViewModel::class.java)
    }
    private fun refreshData(){
    
    
        textView.text=viewModel.count.toString()
    }

    //在界面进行暂停时将数据保存
    override fun onPause() {
    
    
        super.onPause()
        sp.edit{
    
    
            putInt("countVal",viewModel.count)
        }
    }
}

2 thread-safe and more elegant ViewModel—LiveData

Use LiveData to wrap the properties. When the data changes, the latest data can be called through the callback function, thus ensuring the thread safety of the data

1 Usage of MutableLiveData

package com.example.viewmodletest

import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
//有参构造进行数据的修改
class MainViewModel(countVal:Int): ViewModel() {
    
    
    //使用LiveData来监听目标值的变动状态
    var counter=MutableLiveData<Int>()
    
    init{
    
    
        counter.value=countVal
    }
    
    fun add(){
    
    
        val count=counter.value?:0
        counter.value=count+1
    }
    fun sub(){
    
    
        val count=counter.value?:0
        counter.value=count-1
    }
    fun zero(){
    
    
        counter.value=0
        //counter.postValue()在非主线程中给LiveData设置数据
    }
}

2 Use of the observe callback function in the main program

package com.example.viewmodletest

import android.content.Context
import android.content.SharedPreferences
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.Button
import android.widget.ShareActionProvider
import android.widget.TextView
import androidx.core.content.edit
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProvider

class MainActivity : AppCompatActivity() {
    
    
    private lateinit var textView: TextView
    private lateinit var btnadd:Button
    private lateinit var btnless:Button
    private lateinit var clearZero:Button

    private lateinit var viewModel: MainViewModel
    private lateinit var sp:SharedPreferences

    private var countVal=0
    override fun onCreate(savedInstanceState: Bundle?) {
    
    
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        initData()
        btnadd.setOnClickListener(){
    
    
            viewModel.add()
        }
        btnless.setOnClickListener(){
    
    
            viewModel.sub()
        }
        //利用构造方法将数据清零
        clearZero.setOnClickListener(){
    
    
            viewModel.zero()
        }
        //使用这个方法来检测里面数据的变化,会调用回调函数进行显示,可以保证线程安全
        viewModel.counter.observe(this, Observer {
    
    
            count->textView.text=count.toString()
        })

    }
    private fun initData(){
    
    
        textView=findViewById(R.id.count)
        btnadd=findViewById(R.id.countSum)
        btnless=findViewById(R.id.countless)
        clearZero=findViewById(R.id.clearZero)
        //获取当前界面的ViewModle
        //viewModel=ViewModelProvider(this).get(MainViewModel::class.java)
        sp=getPreferences(Context.MODE_PRIVATE)
        //从存储的里面取得数据,如果没有数就默认为0
        countVal=sp.getInt("countVal",0)
        viewModel=ViewModelProvider(this,MainViewModelFactory(countVal)).get(MainViewModel::class.java)
    }
    //在界面进行暂停时将数据保存
    override fun onPause() {
    
    
        super.onPause()
        sp.edit{
    
    
            putInt("countVal",viewModel.counter.value ?: 0)
        }
    }
}

3Lifecycles detects the life cycle of the interface

When making a network request, if the network request has not ended, but the current interface has ended, there is no need to process the request result at this time, so it is necessary to detect the life cycle of the current interface, and the lifecycles in the jetpack component need to be used

Instructions

1 Customize the observation class and implement the DefaultLifecycleObserver interface

package com.example.viewmodletest

import android.util.Log
import androidx.lifecycle.*

class MyObserver:DefaultLifecycleObserver {
    
    

    override fun onCreate(owner: LifecycleOwner) {
    
    
        Log.d("MyObserver","activityCreate")
        super.onCreate(owner)
    }

    override fun onStart(owner: LifecycleOwner) {
    
    
        Log.d("MyObserver","activityStart")
        super.onStart(owner)
    }

    override fun onResume(owner: LifecycleOwner) {
    
    
        super.onResume(owner)
    }

    override fun onPause(owner: LifecycleOwner) {
    
    
        super.onPause(owner)
    }

    override fun onStop(owner: LifecycleOwner) {
    
    
        Log.d("MyObserver","activityStop")
        super.onStop(owner)
    }

    override fun onDestroy(owner: LifecycleOwner) {
    
    
        Log.d("MyObserver","activityDestroy")
        super.onDestroy(owner)
    }
}

2 Introduce the current observation object in the interface that needs to be detected

lifecycle.addObserver(MyObserver())

insert image description here

4WorkManager component for processing timed tasks

WorkManager and Service are not the same, and there is no direct connection.
Service is one of the four major components of the Android system, and it keeps running in the background without being destroyed. And WorkManager is just a tool for processing timed tasks. It can ensure that even if the application exits or even the phone is restarted, the previously registered tasks will still be executed. Therefore, WorkManager is very suitable for performing some tasks that interact with the server periodically. Such as periodically synchronizing data

The first step is to add dependencies

//Join WorkManager's dependency
implementation 'androidx.work:work-runtime:2.8.1'

The second step is to write the task class to complete the background tasks that need to be processed


import android.content.Context
import android.util.Log
import androidx.work.Worker
import androidx.work.WorkerParameters

class SimpleWorker(context:Context,params:WorkerParameters) :Worker(context,params){
    
    
    override fun doWork(): Result {
    
    
        Log.d("SimpleWorker","do work in SimpleWorker")
        return Result.success()
    }
}

The third step is to implement the request binding of the background task in the program

doWorkBtn.setOnClickListener(){
    
    
            //处理单次请求的结果
            request=OneTimeWorkRequest.Builder(SimpleWorker::class.java)
                .setInitialDelay(5,TimeUnit.MINUTES)//设置多长时间后开始运行
                .addTag("simple")
                .build()
            //周期性处理请求,但是周期时间要大于15分钟
           // val request=PeriodicWorkRequest.Builder(SimpleWorker::class.java,15,TimeUnit.MINUTES).build()
            WorkManager.getInstance(this).enqueue(request)
        }
        //需要后台任务
        doWorkBtnCancel.setOnClickListener(){
    
    
            WorkManager.getInstance(this).cancelAllWorkByTag("simple")
            //通过id来结束后台任务
            WorkManager.getInstance(this).cancelWorkById(request.id)
        }

Advanced, need to monitor the task processing of the returned result

request=OneTimeWorkRequest.Builder(SimpleWorker::class.java)
                .setInitialDelay(5,TimeUnit.MINUTES)//设置多长时间后开始运行
                .addTag("simple")
                .build()
            //周期性处理请求,但是周期时间要大于15分钟
           // val request=PeriodicWorkRequest.Builder(SimpleWorker::class.java,15,TimeUnit.MINUTES).build()
            WorkManager.getInstance(this)
                .getWorkInfoByIdLiveData(request.id)
                .observe(this){
    
    workInfo->
                    if(workInfo.state==WorkInfo.State.SUCCEEDED){
    
    
                        Log.d("MainActivity","do work success")
                    }else if(workInfo.state==WorkInfo.State.FAILED){
    
    
                        Log.d("MainActivity","do work failed")
                    }
                }
               

Advanced usage method, when there are multiple background tasks that need to be used together, you can use the chained office method

val requestA=OneTimeWorkRequest.Builder(AAA::class.java)
                .build()
            val requestB=OneTimeWorkRequest.Builder(BBB::class.java)
                .build()
            //.enqueue(request)
            WorkManager.getInstance(this)
                .beginWith(requestA)
                .then(requestB)
                .enqueue()

5DataBinding data binding simple implementation

1 Data binding in Activity

The main purpose of databing is to provide an easy way to connect the views in the user interface layout to the data stored in the application code.
First enable the data binding function.

 //数据绑定
 android {
    
    
 ................
    buildFeatures{
    
    
        viewBinding true
        dataBinding true
        
        }
    }

2 Prepare the data entity

data class User(val name:String,val address:String) {
    
    
}

3 Change the layout of the display interface

<?xml version="1.0" encoding="utf-8"?>

<layout xmlns:android="http://schemas.android.com/apk/res/android">

    <data>
        <variable
            name="user"
            type="com.example.viewmodletest.entity.User" />

    </data>

    <LinearLayout
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="@{user.name}"/>

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="@{user.address}"/>

    </LinearLayout>
</layout>

4Enable the binding of interface data in the main program

import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.databinding.DataBindingUtil
import com.example.viewmodletest.databinding.UserdatabingdingBinding
import com.example.viewmodletest.entity.User

class UserDataActivity:AppCompatActivity() {
    
    
    override fun onCreate(savedInstanceState: Bundle?) {
    
    
        super.onCreate(savedInstanceState)
        val binding:UserdatabingdingBinding= DataBindingUtil.setContentView(this,R.layout.userdatabingding)
        binding.user= User("小明","中国")
    }
}

2 DataBinding+ViewModel in Fragment

Realize a small tool that can convert RMB into a dollar with one click
1 First bind a ViewModel to the Fragment to store the data in the Fragment to deal with data problems such as screen inversion

import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel

class FragmentViewModel: ViewModel() {
    
    
    private val rate=0.1453f
    val yuan:MutableLiveData<String> = MutableLiveData()
    val result:MutableLiveData<Float> = MutableLiveData()
    fun convert(){
    
    
        yuan.let {
    
    
            if(!it.value.equals("")){
    
    
                result.value=it.value?.toFloat()?.times(rate)
            }else{
    
    
                result.value=0.0f
            }
        }
    }
}

2 Create a new fragmentlayout in the main interface

<?xml version="1.0" encoding="utf-8"?>

<layout xmlns:android="http://schemas.android.com/apk/res/android">

    <data>
        <variable
            name="myDataBinding"
            type="com.example.viewmodletest.FragmentViewModel" />
    </data>

    <LinearLayout
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        
        <TextView

            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text='@{myDataBinding.result==0.0 ? "输入要兑换的人民币"  : String.valueOf(myDataBinding.result)+"美元"}'
            android:layout_gravity="center"/>
        <!--双向表达式-->

        <EditText
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="@={myDataBinding.yuan}"
            android:layout_gravity="center"
            />

        <Button
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:onClick="@{()->myDataBinding.convert()}"
            android:text="点击将人民币转换成美元" />

    </LinearLayout>
</layout>

3 Write the Fragment implementation class for the current fragment

package com.example.viewmodletest


import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.databinding.DataBindingUtil
import androidx.fragment.app.Fragment
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProvider
import com.example.viewmodletest.databinding.MainFragmentBinding
import com.example.viewmodletest.BR.myDataBinding

class ConvertFragment:Fragment() {
    
    
    companion object{
    
    
        fun newInstance()=ConvertFragment()
    }
    private lateinit var viewModel: FragmentViewModel
    lateinit var binding:MainFragmentBinding

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
    
    
        binding=DataBindingUtil.inflate(inflater,R.layout.main_fragment,container,false)
        binding.lifecycleOwner=this
        return binding.root
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    
    
        super.onViewCreated(view, savedInstanceState)
        viewModel=ViewModelProvider(this).get(FragmentViewModel::class.java)
        binding.setVariable(myDataBinding,viewModel)

    }
}

4 Load Fragment in the xml of the main Activity

<?xml version="1.0" encoding="utf-8"?>

<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools">

    <data>
        <variable
            name="user"
            type="com.example.viewmodletest.entity.User" />

    </data>

    <LinearLayout
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="@{user.name}"/>

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="@{user.address}"/>

        <!--在里面实现数据的展示和处理-->
        <fragment
            android:id="@+id/fragment1"
            android:name="com.example.viewmodletest.ConvertFragment"
            tools:layout="@layout/main_fragment"
            android:layout_width="match_parent"
            android:layout_height="match_parent">

        </fragment>

    </LinearLayout>


</layout>

5 Start in the main class

import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.databinding.DataBindingUtil
import com.example.viewmodletest.databinding.UserdatabingdingBinding
import com.example.viewmodletest.entity.User
//希望实现一个人民币兑换美元的程序
class UserDataActivity:AppCompatActivity() {
    
    
    override fun onCreate(savedInstanceState: Bundle?) {
    
    
        super.onCreate(savedInstanceState)
        val binding:UserdatabingdingBinding= DataBindingUtil.setContentView(this,R.layout.userdatabingding)
        //使用此布局去加载fragment
        binding.user= User("小明","中国")
    }
}

6 result display
insert image description here

insert image description hereWhen the screen is reversed, the data is not lost

insert image description here

6Navigation solves the jump problem between Fragments

Implementing Navigation requires three parts, namely

Navigation graph: an XML resource containing all navigation-related information
NavHostFragment: a special Fragment, a container for carrying navigation content
NavController: an object that manages application navigation, and implements operations such as jumping between Fragments

1 Add dependency

//加入navigation的依赖
    implementation 'androidx.navigation:navigation-fragment-ktx:2.3.1'
    implementation 'androidx.navigation:navigation-ui-ktx:2.3.1'

2 Create a new navigation resource directory, and create a Navigation graph.xml file in the directory

insert image description here
Create a navigation directory, and then create a new nav_graph.xml file in this directory , and set it after switching the name
insert image description here
of the Framelayout that jumps in Design . After the above synchronization several times, multiple FrameLayouts can be generated for operation
insert image description here
insert image description here
insert image description here
insert image description here
, after creating multiple files, you can perform chain steps.
insert image description here
There will be many generated files on the left.

<?xml version="1.0" encoding="utf-8"?>
<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/nav_graph"
    app:startDestination="@id/fragmentA">

    <fragment
        android:id="@+id/fragmentA"
        android:name="com.example.viewmodletest.FragmentA"
        android:label="fragment_a"
        tools:layout="@layout/fragment_a" >
        <action
            android:id="@+id/action_fragmentA_to_fragmentB"
            app:destination="@id/fragmentB" />
    </fragment>
    <fragment
        android:id="@+id/fragmentB"
        android:name="com.example.viewmodletest.FragmentB"
        android:label="fragment_b"
        tools:layout="@layout/fragment_b" >
        <action
            android:id="@+id/action_fragmentB_to_fragmentC"
            app:destination="@id/fragmentC" />
    </fragment>
    <fragment
        android:id="@+id/fragmentC"
        android:name="com.example.viewmodletest.FragmentC"
        android:label="fragment_c"
        tools:layout="@layout/fragment_c" />
</navigation>

Introduce the Framelayout generated above in the main layout

<?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"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:text="主布局头部"
        android:background="@color/teal_700"/>


    <fragment
        android:id="@+id/fragment"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:name="androidx.navigation.fragment.NavHostFragment"
        app:defaultNavHost="true"
        app:navGraph="@navigation/nav_graph"/>
    <!--app:defaultNavHost="true"表示点击返回按钮时退回到上一个fragment-->


    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:text="主布局尾部"
        android:background="@color/teal_700"/>


</LinearLayout>

Then add its layout in each Framelayout.
For example, add a button to jump to FragmentB in fragmenta.xml and pass parameters

<?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=".FragmentA">

    <!-- TODO: Update blank fragment layout -->
    <TextView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:text="@string/hello_blank_fragment" />

    <Button
        android:id="@+id/toFB"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:text="点击跳转到FB"/>

</FrameLayout>
package com.example.viewmodletest

import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Button
import androidx.navigation.Navigation

// 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 [FragmentA.newInstance] factory method to
 * create an instance of this fragment.
 */
class FragmentA : 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_a, container, false)
    }

    //界面被创建出来之后的组件绑定
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    
    
        super.onViewCreated(view, savedInstanceState)
        var toFB = view.findViewById<Button>(R.id.toFB)
        toFB.setOnClickListener {
    
    
            //it是代表匿名函数的参数
            val navControl= Navigation.findNavController(it)
            val bundle=Bundle()
            bundle.putString("name","你是我的笑啊笑啊")
            //数据传递
            navControl.navigate(R.id.action_fragmentA_to_fragmentB,bundle)
        }
    }

    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 FragmentA.
         */
        // TODO: Rename and change types and number of parameters
        @JvmStatic
        fun newInstance(param1: String, param2: String) =
            FragmentA().apply {
    
    
                arguments = Bundle().apply {
    
    
                    putString(ARG_PARAM1, param1)
                    putString(ARG_PARAM2, param2)
                }
            }
    }
}

To Fragment to receive data

package com.example.viewmodletest

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
import android.widget.Button
import android.widget.TextView
import androidx.navigation.Navigation

// 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 [FragmentB.newInstance] factory method to
 * create an instance of this fragment.
 */
class FragmentB : 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("name")
            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_b, container, false)
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    
    
        super.onViewCreated(view, savedInstanceState)
        var textB = view.findViewById<TextView>(R.id.textB)

        /*textB.text=savedInstanceState?.getString("name").toString()
        Log.d("aa",savedInstanceState?.getString("name").toString())*/
        textB.text=param1
        Log.d("aa", param1.toString())
        var toFC=view.findViewById<Button>(R.id.toFC)
        toFC.setOnClickListener {
    
    
            val navControl= Navigation.findNavController(it)
            navControl.navigate(R.id.action_fragmentB_to_fragmentC)
        }
    }

    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 FragmentB.
         */
        // TODO: Rename and change types and number of parameters
        @JvmStatic
        fun newInstance(param1: String, param2: String) =
            FragmentB().apply {
    
    
                arguments = Bundle().apply {
    
    
                    putString(ARG_PARAM1, param1)
                    putString(ARG_PARAM2, param2)
                }
            }
    }
}

Result display

insert image description here
insert image description here

Guess you like

Origin blog.csdn.net/m0_56184347/article/details/129939713