Vlad Alexeev
Vlad Alexeev

Reputation: 2224

using onClick on TextView with selectable text - how to avoid double click?

This is so strange, but if you put an onClickListener on a TextView (or non-editable EditText) which has android:textIsSelectable="true" - it needs not one tap, but two. I checked it on 3 phones and all of them perform onClick only after second tap.

Of course, if you make focusable="false" or android:textIsSelectable="false" it works from the 1st tap, but text selection doesn't work.

Please, help me with that issue

Upvotes: 14

Views: 3579

Answers (6)

RKS
RKS

Reputation: 463

Use view.requestFocus() while initiating that view in the Fragment/Activity

myView.apply { 
    requestFocus()
    text = "Click here"
}

This worked for me while using textIsSelectable for TextView

Upvotes: 0

SerjantArbuz
SerjantArbuz

Reputation: 1244

Set in XML to your TextView:

android:textIsSelectable="true"

After that set onTouchListener to your TextView and in them do this:

if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) view.requestFocus(); 

It's set focus for every tap on TextView. After all set onClickListener to your TextView.

I have the same problem with a ViewHolder in my RecyclerView.Adapter. So, I cut it for you if you need:

class RollHolder extends RecyclerView.ViewHolder implements View.OnClickListener, View.OnTouchListener {

    private TextView textView;

    RollHolder(View itemView) {
        super(itemView);
        textView = (TextView) itemView.findViewById(R.id.text_view);
        textView.setOnClickListener(this);
        textView.setOnTouchListener(this);
    }

    @Override
    public void onClick(View view) {
        switch (view.getId()){
            case R.id.text_view:
                // Do here that you need
                break;
        }
    }

    @Override
    public boolean onTouch(View view, MotionEvent motionEvent) {
        switch (view.getId()){
            case R.id.text_view:
                if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) view.requestFocus();
                break;
        };
        return false;
    }
}

Upvotes: 4

Radiokot
Radiokot

Reputation: 11

Use onTouchListener to detect clicks and redirect them to the container view:

textView.setOnTouchListener { _, event ->
    if (event.action == 1 && !textView.hasSelection()) {
        containerView.callOnClick()
    }
    false
}

This will keep the ability to select and unselect text without calling onClick event.

Upvotes: 1

Sethu
Sethu

Reputation: 428

Try this.

use in XML file

    android:onclick"your Name"//for example I used "onImageListClick"

    public void onImageListClick(View view)
        {
             //do your task.
            //Intent intent = new Intent(this, ImageListActivity.class);
            //intent.putExtra(Extra.IMAGES, IMAGES);
            //startActivity(intent);
        }

or

  txtboxname.setOnClickListener(new View.OnClickListener() {
   @Override
    public void onClick(View arg0) {
////do you task.
       }        
});

Upvotes: -4

TWiStErRob
TWiStErRob

Reputation: 46508

I had the same problem and it's hard to ask and search for a resolution.

Here are two things that I noticed in addition to the double tap behavior:

  • if you really double tap (quickly) on a TextView with textIsSelectable, it selects the word you tapped, even when the focus is on something else, which means the view somehow registered the first touch as well.
  • if you long tap while the focus is somewhere else, it works and starts the selection action mode as if it was focused already

Here's how I managed to make it work. It's not beautiful, but everything works fine so far: in the XML you only need to add textIsSelectable, no other focusable / focusableInTouchMode / clickable / enabled attributes needed; then you need two listeners, one is the existing onClick which works, but needs a double take and the other is an onFocusChange where you handle the exceptional first tap:

hint = (TextView)view.findViewById(R.id.hint);
hint.setOnClickListener(new OnClickListener() {
    @Override public void onClick(View v) {
        handleHintClick();
    }
});
hint.setOnFocusChangeListener(new OnFocusChangeListener() {
    @Override public void onFocusChange(View v, boolean hasFocus) {
        if (hasFocus) { handleHintClick(); }
    }
});

Here is an alternative solution in a related question which I don't like and didn't even try: wrap the TextView in a FrameLayout and add the listener to that.

Here is another related question which has more solutions.

Upvotes: 2

Android
Android

Reputation: 9033

android:longClickable="false"
android:clickable="false"

Disable the button with setEnabled(false) until it is safe for the user to click it again.

May this helpful to you

Upvotes: -2

Related Questions