10

I have RecyclerView.The element at position is 0 is header for EditText ,then all other elements are images.On long pressing on EditText it gives option paste.This works fine. But when I scroll the recycler view to the bottom and again come to top and long press it will not show the paste option and gives error . On Scrolling to the bottom and again coming to top passes call to onBindViewHolder.

TextView: TextView does not support text selection. Selection cancelled.

public class Someclass extends RecyclerView.Adapter<RecyclerView.ViewHolder> implements View.OnClickListener {


    private static final int TYPE_EDIT = 0;
    private static final int TYPE_IMAGE = 1;
    List<String> msomelist = new ArrayList<String>();

    public void someMethod(List<String> somelist) {

        msomelist.clear();
        msomelist.addAll(somelist);
        notifyDataSetChanged();

    }




    public Someclass(Activity activity, List<String> somelist) {
        this.activity = activity;
        this.msomelist.clear();
        this.msomelist.addAll(somelist);
        mContext = activity;
    }

    @Override
    public int getItemViewType(int position) {

        if (position == 0)
            return TYPE_EDIT;

        return TYPE_IMAGE;
    }

    @Override
    public void onClick(View view) {
        int postition = (int) view.getTag();
        msomelist.remove(postition);
        notifyDataSetChanged();

    }

    public static class ViewHolder extends RecyclerView.ViewHolder {
       ImageView img;

        public ViewHolder(View itemView) {
            super(itemView);

            img = (ImageView) itemView.findViewById(R.id.image);
        }
    }

    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        if (viewType == TYPE_IMAGE) {
            View view = LayoutInflater.from(mContext)
                    .inflate(somelayout, false);
            ViewHolder holder = new ViewHolder(view);
            return holder;
        } else {
            View view = LayoutInflater.from(mContext)
                    .inflate(someotherlayout, false);


            return new OtherHolder(view);
        }
    }

    class OtherHolder extends RecyclerView.ViewHolder {
        EditText editText;

        public OtherHolder(View itemView) {
            super(itemView);
            editText = (EditText) itemView.findViewById(R.id.ediItext);
            editText.requestFocus();
        }
    }

    @Override
    public void onBindViewHolder(final RecyclerView.ViewHolder holder, int position) {

        if (holder instanceof ViewHolder) {
            some function.....
        } else if (holder instanceof OtherHolder) {
            some function
        }
    }
}
Chirag Savsani
  • 6,020
  • 4
  • 38
  • 74
stack Learner
  • 1,318
  • 3
  • 18
  • 35

3 Answers3

23

This is a known bug in the Android platform. I didn't believe it at first, but the code @user2246055 posted is an effective workaround!

I preferred to add this in my Adapter instead of subclassing TextView:

        @Override
        public void onViewAttachedToWindow(RecyclerView.ViewHolder holder) {
            super.onViewAttachedToWindow(holder);

            // Bug workaround for losing text selection ability, see:
            // https://code.google.com/p/android/issues/detail?id=208169
            holder.textView.setEnabled(false);
            holder.textView.setEnabled(true);
        }
Lisa Wray
  • 2,242
  • 16
  • 23
  • Thanks so much for this! I was experiencing the same problem and your solution helped me. (on Android 7.1 by the way) – Bernd Kampl Oct 28 '16 at 09:13
  • Could you please elaborate on it a bit? Where do you add it? What class are you overriding? And how do you use that class in the code? – Sasha Shpota Oct 09 '18 at 14:31
  • It works ... I read the answer here but they gave you the credit : https://issuetracker.google.com/issues/37095917 – Cristofer Aug 17 '22 at 14:33
5

Using following MyEditText.java can resolve your problem:

public class MyEditText extends EditText {
private boolean mEnabled; // is this edittext enabled

public MyEditText(Context context) {
    super(context);
}

public MyEditText(Context context, AttributeSet attrs) {
    super(context, attrs);
}

public MyEditText(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
}

@Override
protected void onAttachedToWindow() {
    super.onAttachedToWindow();
    try {
        if (!mEnabled) return;
        super.setEnabled(false);
        super.setEnabled(mEnabled);
    } catch (Exception e) {
        e.printStackTrace();
    }
}

@Override
public void setEnabled(boolean enabled) {
    this.mEnabled = enabled;
    super.setEnabled(enabled);
}}
KernelPanic
  • 2,328
  • 7
  • 47
  • 90
Lucca
  • 91
  • 2
  • 7
  • Actually, it took me 3 hours to try this because it didn't look as if it was related to the problem AT ALL. But it does work! – Lisa Wray Oct 19 '16 at 20:15
  • Long click on EditText will call Editor.performLongClick() to show selection popup window. – Lucca Nov 06 '16 at 17:28
4

Long click on EditText will call Editor.performLongClick() to show selection popup window.

Before getInsertionController().show();

it will check mInsertionControllerEnabled,when you use setText(),TextView will call Editor.prepareCursorControllers() to reset mInsertionControllerEnabled like this:

boolean windowSupportsHandles = false;

ViewGroup.LayoutParams params = mTextView.getRootView().getLayoutParams();
if (params instanceof WindowManager.LayoutParams) {
    WindowManager.LayoutParams windowParams = (WindowManager.LayoutParams) params;
    windowSupportsHandles = windowParams.type < WindowManager.LayoutParams.FIRST_SUB_WINDOW
            || windowParams.type > WindowManager.LayoutParams.LAST_SUB_WINDOW;
}

boolean enabled = windowSupportsHandles && mTextView.getLayout() != null;
mInsertionControllerEnabled = enabled && isCursorVisible();

as you see,rootView must be window type or mInsertionControllerEnabled will be false.

But when you setText() at onBindViewHolder(), the EditText is not attachToWindow yet,so we should setEnable() after EditText attachToWindow to force Editor reset mInsertionControllerEnabled value.Then selection will work now.

rafsanahmad007
  • 23,683
  • 6
  • 47
  • 62
Lucca
  • 91
  • 2
  • 7