How can i have EditText with Clickable Spannables and still selectable by longClick?

VSB*_*VSB 10 android android-edittext spannablestring onclicklistener

I have TextView with spans of type ClickableStringSpan defined as below:

public class ClickableStringSpan extends ClickableSpan {
    private View.OnClickListener mListener;
    int color;
    public ClickableStringSpan(View.OnClickListener listener,int color) {
        mListener = listener;
        this.color = color;

    }

    @Override
    public void onClick(View v) {
        mListener.onClick(v);
    }

       @Override public void updateDrawState(TextPaint ds) {
           super.updateDrawState(ds);
           ds.setUnderlineText(false);
           ds.setColor(color);
       }
}
Run Code Online (Sandbox Code Playgroud)

I set clickable spans on my text like this:

spanStr.setSpan(new ClickableString(new linkedTextClickListener(), linkColor),
                        startIndex, endIndex,
                        SpannableString.SPAN_INCLUSIVE_EXCLUSIVE);
Run Code Online (Sandbox Code Playgroud)

Now I want to apply these string to EditTexts instead of TextViews. Everything is fine just Clickable strings are now not clicked anymore. I want to know how can I pass clicks on this sort of spans to their assigned clicklistener?

Update: My main concern to edit text is I want to allow user select some part of text and share it meanwhile he/she can click on ClickableSpans.

Ema*_*lin 10

您需要将TextView的/ EditText的移动方法设置为LinkMovementMethod才能获得单击的链接.不幸的是,这会禁用选择仅在将移动方法设置为ArrowKeyMovementMethod时才有效的文本的功能. http://developer.android.com/reference/android/text/method/LinkMovementMethod.html http://developer.android.com/reference/android/text/method/ArrowKeyMovementMethod.html

为了解决这个问题,我创建了一个继承自ArrowKeyMovementMethod的自定义MovementMethod类,并添加了单击链接的功能.:

/**
 * ArrowKeyMovementMethod does support selection of text but not the clicking of links.
 * LinkMovementMethod does support clicking of links but not the selection of text.
 * This class adds the link clicking to the ArrowKeyMovementMethod.
 * We basically take the LinkMovementMethod onTouchEvent code and remove the line
 *      Selection.removeSelection(buffer);
 * which deselects all text when no link was found.
 */
public class EnhancedMovementMethod extends ArrowKeyMovementMethod {

    private static EnhancedMovementMethod sInstance;

    public static MovementMethod getInstance() {
        if (sInstance == null) {
            sInstance = new EnhancedMovementMethod ();
        }
        return sInstance;
    }

    @Override
    public boolean onTouchEvent(TextView widget, Spannable buffer, MotionEvent event) {
        int action = event.getAction();

        if (action == MotionEvent.ACTION_UP ||
            action == MotionEvent.ACTION_DOWN) {
            int x = (int) event.getX();
            int y = (int) event.getY();

            x -= widget.getTotalPaddingLeft();
            y -= widget.getTotalPaddingTop();

            x += widget.getScrollX();
            y += widget.getScrollY();

            Layout layout = widget.getLayout();
            int line = layout.getLineForVertical(y);
            int off = layout.getOffsetForHorizontal(line, x);

            ClickableSpan[] link = buffer.getSpans(off, off, ClickableSpan.class);

            if (link.length != 0) {
                if (action == MotionEvent.ACTION_UP) {
                    link[0].onClick(widget);
                }
                else if (action == MotionEvent.ACTION_DOWN) {
                    Selection.setSelection(buffer, buffer.getSpanStart(link[0]), buffer.getSpanEnd(link[0]));
                }

                return true;
            }
            /*else {
                Selection.removeSelection(buffer);
            }*/
        }

        return super.onTouchEvent(widget, buffer, event);
    }

}
Run Code Online (Sandbox Code Playgroud)

你需要做的就是设置EditText的移动方法,你很高兴:

yourEditTExt.setMovementMethod(EnhancedMovementMethod.getInstance());
Run Code Online (Sandbox Code Playgroud)

上面的代码仅适用于未格式化的文本,这意味着一旦您决定使用文本样式(粗体,斜体等)或不同的字体大小格式化文本,它将不再找到单击的链接.我确实有处理格式化文本的代码,但由于这不是问题的一部分,我使示例代码尽可能短.