3

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

ZeGerm4n
  • 191
  • 1
  • 10
  • You mean every other click or the only time that it does not work is the 1st? –  Jul 13 '18 at 16:02
  • the only time that it does not work is the first click, every following click works as expected – ZeGerm4n Jul 13 '18 at 16:25
  • From the code you provided I'm surprised you can see that the listener works the 2nd time. The toast is shown only if the listener is null, am I mistaken? So how do you say that it works the 2nd time? What do you see? –  Jul 13 '18 at 17:14
  • in onBindViewHolder of my RecyclerViewAdapter I save the KeyListener of my EditText to its tag attribute and then set its KeyListener to null, like: 'editText.let { it.tag = it.keyListener; it.keyListener = null; }' I am doing that to make it non editiable, in onLongClick I then set it back to the value saved to the tag attribute. The desired behavior is that its only editable when longClicked. The only problem that I have is that my OnClickListener is only called on the 2nd+ click, with the help of the debugger I was able to see that it simply does not get called the first time – ZeGerm4n Jul 13 '18 at 17:37

2 Answers2

2

you must make edit text focusable attribute false, because its default value is auto and this means is framework determine it must be true and false.when it be true at your first touch it has been focused by keyboard.

https://developer.android.com/reference/android/R.styleable#View_focusable

mahdi shahbazi
  • 1,882
  • 10
  • 19
  • when setting focusable to false I cannot use OnLongClickListener anymore – ZeGerm4n Jul 13 '18 at 15:51
  • @dimiSan add your edittext in other view like linearlayout and set your long click on it – mahdi shahbazi Jul 15 '18 at 05:07
  • this indeed solved issue with click listener inside dialog in my project, in which TextView only receives all clicks except first, but can't understand why this happens, and relation it has with focus? – Amr Feb 16 '22 at 08:59
0

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)

ZeGerm4n
  • 191
  • 1
  • 10
  • for those wondering why this is the correct solution to my problem here is a good explanation that I just found: https://stackoverflow.com/questions/11790573/onclick-event-is-not-triggering-android?answertab=votes#tab-top – ZeGerm4n Jul 15 '18 at 17:58