Edittext is gaining focus and showing the keyboard after AlertDialog dismissed

147 Views Asked by At

I have an EditText in a fragment and in an AlertDialog. I'm using the EditText and then click the done button. But whenever I dismiss the AlertDialog the Edittext is gaining focus and showing the keyboard. I don't want to show the keyboard after AlerDialog closes. How can I resolve this?

https://www.youtube.com/watch?v=mbTQmAnOvBg

I used val imm = getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager imm.hideSoftInputFromWindow(view.windowToken, 0) after dismissing the AlertDialog, but it didn't work.

MainFragment.kt

import android.app.AlertDialog
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.WindowManager
import androidx.databinding.DataBindingUtil
import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import androidx.navigation.NavDirections
import androidx.navigation.Navigation
import com.martiandeveloper.decisionmaker.R
import com.martiandeveloper.decisionmaker.databinding.DialogOptionBinding
import com.martiandeveloper.decisionmaker.databinding.FragmentMainBinding
import com.martiandeveloper.decisionmaker.viewmodel.MainViewModel
import timber.log.Timber


class MainFragment : Fragment() {

    private lateinit var fragmentMainBinding: FragmentMainBinding

    private lateinit var mainViewModel: MainViewModel

    private lateinit var optionDialog: AlertDialog

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

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        initUI()
    }

    private fun initUI() {
        mainViewModel = getViewModel()

        fragmentMainBinding.mainViewModel = mainViewModel
        fragmentMainBinding.lifecycleOwner = this

        observe()

        optionDialog = AlertDialog.Builder(context).create()
    }

    private fun getViewModel(): MainViewModel {

        return ViewModelProvider(this, object : ViewModelProvider.Factory {
            override fun <T : ViewModel?> create(modelClass: Class<T>): T {
                @Suppress("UNCHECKED_CAST")
                return MainViewModel() as T
            }
        })[MainViewModel::class.java]

    }

    private fun navigate(navDirections: NavDirections) {
        view?.let { Navigation.findNavController(it).navigate(navDirections) }
    }

    private fun observe() {

        mainViewModel.eventOptionMBTNClick.observe(viewLifecycleOwner, {
            if (it) {
                mainViewModel.setIsOptionDialogShowing(true)
                mainViewModel.onOptionMBTNClickComplete()
            }
        })

        mainViewModel.eventDecideMBTNClick.observe(viewLifecycleOwner, {
            if (it) {
                Timber.i("Decide")
                mainViewModel.onDecideMBTNClickComplete()
            }
        })

        mainViewModel.eventCancelMBTNClick.observe(viewLifecycleOwner, {
            if (it) {
                mainViewModel.setIsOptionDialogShowing(false)
                mainViewModel.onCancelMBTNClickComplete()
            }
        })

        mainViewModel.eventDoneMBTNClick.observe(viewLifecycleOwner, {
            if (it) {
                Timber.i("Done")
                mainViewModel.onDoneMBTNClickComplete()
            }
        })

        mainViewModel.isOptionDialogShowing.observe(viewLifecycleOwner, {
            if (it) {
                showOptionDialog()
            } else {
                if (optionDialog.isShowing) {
                    optionDialog.dismiss()
                }
            }
        })

    }

    private fun showOptionDialog() {
        val binding = DialogOptionBinding.inflate(LayoutInflater.from(context))

        binding.mainViewModel = mainViewModel
        binding.lifecycleOwner = this

        binding.dialogOptionOptionET.requestFocus()

        optionDialog.setView(binding.root)
        optionDialog.setCanceledOnTouchOutside(false)
        optionDialog.setCancelable(false)
        optionDialog.show()

        val window = optionDialog.window
        window?.clearFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE or         
        WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM)
        window?.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE)
    }

}

fragment_main.xml

<?xml version="1.0" encoding="utf-8"?>
<layout 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">

<data>

    <variable
        name="mainViewModel"
        type="com.martiandeveloper.decisionmaker.viewmodel.MainViewModel" />

</data>

<androidx.constraintlayout.widget.ConstraintLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="16dp"
    tools:context=".view.MainFragment">

    <com.google.android.material.textfield.TextInputLayout
        android:id="@+id/fragment_main_mainTIL"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:focusable="true"
        android:focusableInTouchMode="true"
        android:textColorHint="@color/woodland"
        app:boxStrokeColor="@color/woodland"
        app:hintAnimationEnabled="false"
        app:hintTextColor="@color/woodland"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent">

        <com.google.android.material.textfield.TextInputEditText
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="@drawable/background"
            android:fontFamily="@font/actor"
            android:hint="@string/ask_me_your_question_here"
            android:imeOptions="actionDone"
            android:inputType="text"
            android:text="@={mainViewModel.questionET}"
            android:textColor="@color/apple_white"
            android:textColorHint="@color/woodland" />

    </com.google.android.material.textfield.TextInputLayout>

    <com.google.android.material.textview.MaterialTextView
        android:id="@+id/fragment_main_optionsMTV"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="16dp"
        android:fontFamily="@font/actor"
        android:text="@string/options"
        android:textColor="@color/woodland"
        app:layout_constraintEnd_toEndOf="@id/fragment_main_mainTIL"
        app:layout_constraintStart_toStartOf="@id/fragment_main_mainTIL"
        app:layout_constraintTop_toBottomOf="@id/fragment_main_mainTIL" />

    <ScrollView
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_marginTop="16dp"
        android:layout_marginBottom="16dp"
        app:layout_constraintBottom_toTopOf="@id/fragment_main_buttonsLL"
        app:layout_constraintTop_toBottomOf="@id/fragment_main_optionsMTV">

        <com.google.android.material.textview.MaterialTextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:fontFamily="@font/actor"
            android:textColor="@color/apple_white"
            android:textSize="18sp" />

    </ScrollView>

    <LinearLayout
        android:id="@+id/fragment_main_buttonsLL"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent">

        <com.google.android.material.button.MaterialButton
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginEnd="8dp"
            android:backgroundTint="@color/antarctic_deep"
            android:fontFamily="@font/actor"
            android:onClick="@{() -> mainViewModel.onOptionMBTNClick()}"
            android:text="@string/option"
            android:textAllCaps="false"
            android:textColor="@color/apple_white"
            app:cornerRadius="0dp"
            app:icon="@drawable/ic_option"
            app:iconTint="@color/moorland_mist"
            app:strokeColor="@color/woodland"
            app:strokeWidth="1dp" />

        <com.google.android.material.button.MaterialButton
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginStart="8dp"
            android:backgroundTint="@color/antarctic_deep"
            android:fontFamily="@font/actor"
            android:onClick="@{()->mainViewModel.onDecideMBTNClick()}"
            android:text="@string/decide"
            android:textAllCaps="false"
            android:textColor="@color/apple_white"
            app:cornerRadius="0dp"
            app:icon="@drawable/ic_decide"
            app:iconTint="@color/moorland_mist"
            app:strokeColor="@color/woodland"
            app:strokeWidth="1dp" />

    </LinearLayout>

</androidx.constraintlayout.widget.ConstraintLayout>

</layout>

dialog_option.xml

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">

<data>

    <variable
        name="mainViewModel"
        type="com.martiandeveloper.decisionmaker.viewmodel.MainViewModel" />

</data>

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@color/moorland_mist"
    android:orientation="vertical"
    android:padding="16dp">

    <com.google.android.material.textfield.TextInputLayout
        android:id="@+id/dialog_option_optionET"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textColorHint="@color/woodland"
        app:boxStrokeColor="@color/woodland"
        app:hintAnimationEnabled="false"
        app:hintTextColor="@color/woodland">

        <com.google.android.material.textfield.TextInputEditText
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="@drawable/background"
            android:fontFamily="@font/actor"
            android:hint="@string/enter_your_option_here"
            android:imeOptions="actionDone"
            android:inputType="text"
            android:text="@={mainViewModel.optionET}"
            android:textColor="@color/apple_white"
            android:textColorHint="@color/woodland" />

    </com.google.android.material.textfield.TextInputLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="16dp"
        android:gravity="center"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent">

        <com.google.android.material.button.MaterialButton
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginEnd="8dp"
            android:backgroundTint="@color/antarctic_deep"
            android:fontFamily="@font/actor"
            android:onClick="@{() -> mainViewModel.onCancelMBTNClick()}"
            android:text="@string/cancel"
            android:textAllCaps="false"
            android:textColor="@color/apple_white"
            app:cornerRadius="0dp"
            app:icon="@drawable/ic_cancel"
            app:iconTint="@color/moorland_mist"
            app:strokeColor="@color/woodland"
            app:strokeWidth="1dp" />

        <com.google.android.material.button.MaterialButton
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginStart="8dp"
            android:backgroundTint="@color/antarctic_deep"
            android:fontFamily="@font/actor"
            android:onClick="@{()->mainViewModel.onDoneMBTNClick()}"
            android:text="@string/done"
            android:textAllCaps="false"
            android:textColor="@color/apple_white"
            app:cornerRadius="0dp"
            app:icon="@drawable/ic_done"
            app:iconTint="@color/moorland_mist"
            app:strokeColor="@color/woodland"
            app:strokeWidth="1dp" />

    </LinearLayout>

</LinearLayout>

</layout>
2

There are 2 best solutions below

0
On

create Extensions.kt

fun Activity.hideKeyboard(event: MotionEvent) {
    if (event.action == MotionEvent.ACTION_DOWN) {
        val view = currentFocus
        if (view != null) {
            view.clearFocus()
            val inputMethodManager =
                getSystemService(Activity.INPUT_METHOD_SERVICE) as InputMethodManager
            inputMethodManager.hideSoftInputFromWindow(
                view.windowToken,
                InputMethodManager.HIDE_NOT_ALWAYS
            )
        }
    }
}

activity you will use

override fun dispatchTouchEvent(event: MotionEvent): Boolean {
        hideKeyboard(event)
        return super.dispatchTouchEvent(event)
    }

Extensions. create kt this way you can use it in any activity you want. Extensions. Delete kt except libraries and this write code

0
On

Try this:

fun showKeyboard(view: View) = ViewCompat.getWindowInsetsController(view)?.show(WindowInsetsCompat.Type.ime())

showKeyboard(binding.root)    //<- the root View of your dialog