Search code examples
androidkotlinandroid-viewpagerandroid-button

Android MVVM Fragment Button click doesn't work after view pager swipe


I have an activity with three fragments that are navigated with a ViewPager. The starting fragment has a button with a click event. When the fragment first appears the button works but when I swipe to the last fragment and back to the main fragment the button doesn't work. It only does this with the button nothing else... I know it's probably something fairly obvious be gentle folks lol!

button layout

        <Button
            android:id="@+id/login_button"
            android:layout_width="match_parent"
            android:textSize="@dimen/body_text_size"
            android:layout_height="wrap_content"
            android:layout_marginStart="@dimen/layout_margin"
            android:layout_marginEnd="@dimen/layout_margin"
            android:layout_marginBottom="@dimen/layout_margin"
            android:focusable="false"
            android:background="@drawable/button_pressed_state"
            android:text="@string/login"
            android:textColor="@color/white"
            android:textStyle="bold" />

Fragment Code that it happens on.

        override fun onCreateView(
            inflater: LayoutInflater,
            container: ViewGroup?,
            savedInstanceState: Bundle?
        ): View? {
            binding = DataBindingUtil.inflate(inflater, R.layout.login_fragment, container, false)
            viewModel = ViewModelProvider(this).get(LoginViewModel::class.java)
            loginView = binding.root
            initClickableLinks()
            launch {
                initButtonClick()
            }
            return loginView
        }


        private suspend fun initButtonClick(): String? {
            val edittextSize = binding.emailAddressEditText.textSize
            val textviewSize = binding.forgetPassTextview.textSize
            var message: String? = ""
            binding.loginButton.setOnClickListener {
                fun onClick(view: View?) {
                    try {
                        viewModel.setEmailAddress(binding.emailAddressEditText.text.toString())
                        viewModel.setPassword(binding.passwordEditText.text.toString())
                        //if nothing is entered this will do nothing but update text
                        val invalidString = requireActivity().getString(R.string.invalid_combo)
                        binding.authTextView.text = ""
                        if (binding.emailAddressEditText.text.toString()
                                .isBlank() || binding.passwordEditText.text.toString().isBlank()
                        ) {
                            binding.authTextView.text = invalidString
                            //exits listener because authentication failed
    //                        return@setOnClickListener
                        }
                        binding.progressBar.visibility = View.VISIBLE
                        //background thread for IO
                        GlobalScope.launch(Dispatchers.IO) {
                            //call api

                            //UI Thread
                            withContext(Dispatchers.Main) {
                                val mess = viewModel.getMessage()
                                if (mess.equals("Successful")) {
                                    val intent = Intent(activity, MemberActivity::class.java)
                                    val loginfo = viewModel.getLoginResult().toString()
                                    intent.putExtra("loginIno", loginfo)
                                    activity?.startActivity(intent)
                                } else {
                                    binding.authTextView.text = mess
                                    Toast.makeText(activity!!.applicationContext, mess, Toast.LENGTH_LONG).show()
                                }
                                binding.progressBar.visibility = View.GONE
                            }
                        }
                    } catch (ex: Exception) {
                        println(ex)
                    }
                }
            }
            return message
        }

This only happens with the button


Solution

  • In part I found that the following only gets called once :

                initButtonClick()
    

    Removing the launch and changing the Private suspend function to a private function that still asynchronously calls the login service fixed the issue and now gets called multiple times.