Search code examples
javaandroidkotlinandroid-edittextonclicklistener

Android OnClickListener only triggered on second click


My OnClickListener gets only called on the second click. The OnLongClickListener for the same View works as expected. I tried using OnTouchListener instead, but that gets obviously triggered when swiping.

My listeners are abstract methods of an Interface that I implement in my activity:

interface OnVocableFlashcardFragmentInteractionListener {
    fun onEditTextLongClick(view: View): Boolean
    fun onEditTextClick(view: View)
}

I set the listeners of my View like this in my RecyclerViewAdapter Class:

init{
    setHasStableIds(true)

    mEditTextOnClickListener = View.OnClickListener {
        mListener.onEditTextClick(it)
    }

    mEditTextOnLongClickListener = View.OnLongClickListener {
        mListener.onEditTextLongClick(it)
    }
}

override fun onBindViewHolder(holder: FlashcardViewHolder, position: Int) {
    ...
    editText.let { it.tag = it.keyListener; it.keyListener = null; }
    editText.setOnClickListener(mEditTextOnClickListener)
    editText.setOnLongClickListener(mEditTextOnLongClickListener)
    ...
}

The implementation of the listeners in my activity looks like following:

override fun onEditTextClick(view: View) {
    //-- only show toast if view is not editable (becomes editable on LongClick)
    if ((view as EditText).keyListener == null) {
        if (mToast != null) {
            mToast!!.cancel()
        }
        //-- inform user to long press to edit entry
        mToast = Toast.makeText(this, resources.getString(R.string.long_click_to_edit), Toast.LENGTH_LONG)
        mToast!!.show()
    }
}

override fun onEditTextLongClick(view: View): Boolean {
    //-- I saved the KeyListener in the editTexts tag attribute
    //-- to make it clickable again when needed
    (view as EditText).keyListener = view.getTag() as KeyListener
    showSoftKeyboard(view)
    return true
}

The XML of my View looks like following:

            <EditText
            android:id="@+id/et_vocable_word"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_margin="8dp"
            android:background="@null"
            android:textStyle="bold"
            android:hint="@string/enter_word"
            android:imeOptions="actionNext"
            android:inputType="textNoSuggestions"
            android:maxLines="1"
            android:singleLine="true" />

the view's parents and its parents parents are not declared as android:focusable="true" or android:clickable="true"

In my AndroidManifest.xml I have set android:windowSoftInputMode="stateHidden" for my activity to prevent the SoftInput from showing up when the activity starts.

Am I doing something utterly wrong or why does the OnClickListener only get called on the second click? Does anyone have an Idea how I could solve the problem?

OnClickListener not triggered on first click


Solution

  • I was able to achieve the desired behavior by using OnTouchListener instead of OnClickListener like so:

    override fun onEditTextTouch(editText: EditText, event: MotionEvent): Boolean {
        //-- if the pressed gesture has finished
        if (event.action == MotionEvent.ACTION_UP)
        //-- only show toast if view is not editable (becomes editable on LongClick)
            if (editText.keyListener == null) {
                if (mToast != null) {
                    mToast!!.cancel()
                }
                //-- inform user to long press to edit entry
                mToast = Toast.makeText(this, resources.getString(R.string.long_click_to_edit), Toast.LENGTH_LONG)
                mToast!!.show()
            }
        return false
    }
    

    In my previous attempts at replacing my clickListener with a touchListener I forgot to check for (event.action == MotionEvent.ACTION_UP) so my code was also executed when swiping (which i did not want)