Search code examples
kotlinandroid-viewpagerandroid-tablayoutandroid-viewmodel

How to add ViewModel to a project which uses ViewPager and Tablayout?


Hello i am new in Android Development so maybe this question can be weird for you.

I have a class named IdentityCardInfo which has variables. And I am getting this variables in InfoFragment.

From InfoFragment I want to show these variables in a ResultsFragment wihch has 3 tabs with tablayout.

I want to use ViewModel to pass data to tablayouts but I don't know how to use I've searched but get stuck.

Here is code for IdentityCardInfo class:

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"
    }
}

Here is code for 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
            )
        }
    }
}

This is for ResultsFragment: (I don't add tablayout code and viewpager code)

class ResultsFragment : Fragment() {

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

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.fragment_results, container, 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)
    }

}

Solution

  • @muhittin kaya Refer below code to resolve your issue

    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)
    }
    

    ResultsFragment

    class ResultsFragment : Fragment(), InfoFragmentDataInterface {
    
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            retainInstance = true
        }
    
        override fun onCreateView(
            inflater: LayoutInflater, container: ViewGroup?,
            savedInstanceState: Bundle?
        ): View? {
            // Inflate the layout for this fragment
            return inflater.inflate(R.layout.fragment_results, container, 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.
        }
    }