如何将ViewModel添加到使用ViewPager和Tablayout的项目中?

问题描述

您好,我是Android开发的新手,所以这个问题可能对您来说很奇怪。

我有一个名为 IdentityCardInfo 的类,该类具有变量。我在 InfoFragment 中得到了这个变量。

在InfoFragment中,我想在 ResultsFragment 显示这些变量,该变量具有3个带有TabLayout的标签

我想使用 viewmodel 将数据传递到布局,但我不知道该如何使用,但搜索却卡住了。

这是IdentityCardInfo类的代码

class IdentityCardInfo {

    companion object AppConstant{
        const val serieNo ="67G74444"
        const val validDate = "01/01/2022"
        const val dateOfBirth = "10/08/1998"
        const val fullName = "Muhittin KAYA"
        const val identityNo: Long = 11111111111
        const val gender = "MALE"
        const val nationality = "TUR"
    }
}

以下是InfoFragment的代码

class InfoFragment : BaseFragment() {

    lateinit var navController: NavController

    companion object {
        private const val TAG = "Info Fragment"
    }

    override fun onCreateView(
        inflater: LayoutInflater,container: ViewGroup?,savedInstanceState: Bundle?
    ): View? {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.fragment_info,container,false)
    }

    override fun onViewCreated(view: View,savedInstanceState: Bundle?) {
        super.onViewCreated(view,savedInstanceState)
        navController = Navigation.findNavController(view)
        button_info_idcard.setonClickListener {
            //start OcrActivity
            val intent = Intent(activity,OcrActivity::class.java)
            startActivityForResult(intent,101)
        }

        imagebutton_info_settings.setonClickListener {
            navController.navigate(R.id.action_infoFragment_to_settingsFragment)
        }
    }

    override fun onActivityResult(requestCode: Int,resultCode: Int,data: Intent?) {
        super.onActivityResult(requestCode,resultCode,data)
        Log.i("Muhittin","onActivityResult()")

        if (requestCode == 101) {
            val message = data?.getStringExtra("TEST_TEXT")
            Toast.makeText(context,message,Toast.LENGTH_SHORT).show()

            val serieNo = IdentityCardInfo.serieNo
            val validDate = IdentityCardInfo.validDate
            val dateOfBirth = IdentityCardInfo.dateOfBirth
            val fullname = IdentityCardInfo.fullName
            val gender = IdentityCardInfo.gender
            val identityNo = IdentityCardInfo.identityNo
            val nationality = IdentityCardInfo.nationality

            val bundle = bundleOf(
                "TEST_TEXT" to message,"SERIE_NO" to serieNo,"VALID_DATE" to validDate,"dob" to dateOfBirth,"FULL_NAME" to fullname,"GENDER" to gender,"IDENTITY_NO" to identityNo,"NATIONALITY" to nationality
            )
            navController.navigate(
                R.id.action_infoFragment_to_detailFragment,bundle
            )
        }
    }
}

这是针对ResultsFragment的:(我不添加制表符代码和viewpager代码

class ResultsFragment : Fragment() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        retainInstance = true
    }

    override fun onCreateView(
        inflater: LayoutInflater,savedInstanceState: Bundle?
    ): View? {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.fragment_results,false)
    }

    override fun onActivityCreated(savedInstanceState: Bundle?) {
        super.onActivityCreated(savedInstanceState)
        val tabLayout: TabLayout = requireView().findViewById(R.id.tabLayout_results)

        tabLayout.tabGravity = TabLayout.GraviTY_FILL
        val tabTitles = arrayOf(
            resources.getString(R.string.result_tab1_name),resources.getString(R.string.result_tab2_name),resources.getString(R.string.result_tab3_name)
        )

        val viewPager: ViewPager = requireView().findViewById(R.id.viewpager_results)
        viewPager.offscreenPageLimit = 3
        val adapter = PagerAdapter(fragmentManager,tabTitles)
        viewPager.adapter = adapter
        tabLayout.setupWithViewPager(viewPager)
    }

}

解决方法

如果您要使用<div style="height:100px;background-color:red">text</div>在同一活动的片段之间进行数据传输,请here's the Android documentation about it。它允许片段访问共享对象而无需彼此了解,或通过活动进行通信(使用一堆代码来实现该通信)

您基本上会执行以下操作:

<link href='https://fonts.googleapis.com/css?family=PT Serif Caption' rel='stylesheet'>

然后,每个片段将通过执行以下操作来获取同一ViewModel实例的副本:

ViewModel

,然后// create a ViewModel that holds the data you want to share class IdentityCardViewModel : ViewModel() { val identityInfo = MutableLiveData<IdentityCardInfo>() fun setInfo(info: IdentityCardInfo) { identityInfo.value = info } } 可以使用// Get a reference to the IdentityCardViewModel created and held by the activity private val model: IdentityCardViewModel by activityViewModels() 设置数据。 InfoFragment可以观察此数据并在看到新值时执行一些操作:

model.setInfo(yourIdentityCardInfo)
,

@muhittin kaya请参阅下面的代码来解决您的问题

InfoFragment

class InfoFragment : BaseFragment() {

    lateinit var navController: NavController

    // Initialize your variable
    lateinit var infoFragmentInterface: InfoFragmentDataInterface

    // If you get initialization exception then uncomment below line and comment above line
    //private var  infoFragmentInterface: InfoFragmentDataInterface? = null


    companion object {
        private const val TAG = "Info Fragment"
    }

    override fun onCreateView(
        inflater: LayoutInflater,container: ViewGroup?,savedInstanceState: Bundle?
    ): View? {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.fragment_info,container,false)
    }

    override fun onViewCreated(view: View,savedInstanceState: Bundle?) {
        super.onViewCreated(view,savedInstanceState)
        navController = Navigation.findNavController(view)
        button_info_idcard.setOnClickListener {
            //start OcrActivity
            val intent = Intent(activity,OcrActivity::class.java)
            startActivityForResult(intent,101)
        }

        imagebutton_info_settings.setOnClickListener {
            navController.navigate(R.id.action_infoFragment_to_settingsFragment)
        }
    }

    override fun onActivityResult(requestCode: Int,resultCode: Int,data: Intent?) {
        super.onActivityResult(requestCode,resultCode,data)
        Log.i("Muhittin","onActivityResult()")

        if (requestCode == 101) {
            val message = data?.getStringExtra("TEST_TEXT")
            Toast.makeText(context,message,Toast.LENGTH_SHORT).show()

            val serieNo = IdentityCardInfo.serieNo
            val validDate = IdentityCardInfo.validDate
            val dateOfBirth = IdentityCardInfo.dateOfBirth
            val fullname = IdentityCardInfo.fullName
            val gender = IdentityCardInfo.gender
            val identityNo = IdentityCardInfo.identityNo
            val nationality = IdentityCardInfo.nationality

            val bundle = bundleOf(
                "TEST_TEXT" to message,"SERIE_NO" to serieNo,"VALID_DATE" to validDate,"DOB" to dateOfBirth,"FULL_NAME" to fullname,"GENDER" to gender,"IDENTITY_NO" to identityNo,"NATIONALITY" to nationality
            )

            //Add This line for passing your data
            //You can also pass string data here
            infoFragmentInterface.getInfoFragmentData(bundle)

            navController.navigate(
                R.id.action_infoFragment_to_detailFragment,bundle
            )
        }
    }
}

// Create this interface to pass your data
interface InfoFragmentDataInterface {
    fun getInfoFragmentData(bundle: Any)
}

结果片段

class ResultsFragment : Fragment(),InfoFragmentDataInterface {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        retainInstance = true
    }

    override fun onCreateView(
        inflater: LayoutInflater,savedInstanceState: Bundle?
    ): View? {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.fragment_results,false)
    }

    override fun onActivityCreated(savedInstanceState: Bundle?) {
        super.onActivityCreated(savedInstanceState)
        val tabLayout: TabLayout = requireView().findViewById(R.id.tabLayout_results)

        tabLayout.tabGravity = TabLayout.GRAVITY_FILL
        val tabTitles = arrayOf(
            resources.getString(R.string.result_tab1_name),resources.getString(R.string.result_tab2_name),resources.getString(R.string.result_tab3_name)
        )

        val viewPager: ViewPager = requireView().findViewById(R.id.viewpager_results)
        viewPager.offscreenPageLimit = 3
        val adapter = PagerAdapter(fragmentManager,tabTitles)
        viewPager.adapter = adapter
        tabLayout.setupWithViewPager(viewPager)
    }

    override fun getInfoFragmentData(bundle: Any) {
        // You'll get your Bundle data here.
    }
}