我怎么能有EDITTEXT可点击Spannables,仍然由longClick选择?能有、我怎么、EDITTEXT、Spannables

2023-09-06 04:22:34 作者:相见,不如怀念

我的TextView与定义如下类型ClickableStringSpan的跨度:

 公共类ClickableStringSpan扩展ClickableSpan {
    私人View.OnClickListener mListener;
    INT的颜色;
    公共ClickableStringSpan(View.OnClickListener监听器,INT的颜色){
        mListener =侦听器;
        this.color =颜色;

    }

    @覆盖
    公共无效的onClick(视图v){
        mListener.onClick(五);
    }

       @覆盖公共无效updateDrawState(TextPaint DS){
           super.updateDrawState(DS);
           ds.setUnderlineText(假);
           ds.setColor(颜色);
       }
}
 

我在我的文字是这样设置可点击跨度

  spanStr.setSpan(新ClickableString(新linkedTextClickListener(),LINKCOLOR)
                        在startIndex,endIndex的,
                        SpannableString.SPAN_INCLUSIVE_EXCLUSIVE);
 

现在我想将这些字符串适用于EditTexts而不是TextViews。一切都很好,只是可点击的字符串现在不再点击。我想知道我怎么可以通过点击这种跨度到其指定clicklistener?

更新:我主要关心的编辑文本是我想允许用户选择文本的某些部分,并分享它同时他/她可以点击ClickableSpans

。 解决方案 这个请求桌面站点功能是干嘛的,我以为是添加一个网页快捷方式到桌面,结果点完了没反应

您需要设置的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确实文本支持选择,但链接不是点击。
 * LinkMovementMethod做链接支持点击,但文字不选择。
 *此类添加了链接点击到ArrowKeyMovementMethod。
 *我们基本上采取LinkMovementMethod的onTouchEvent code和删除行
 * Selection.removeSelection(缓冲液);
 *当没有链接被发现将取消所有文本。
 * /
公共类EnhancedMovementMethod扩展ArrowKeyMovementMethod {

    私有静态EnhancedMovementMethod sInstance;

    公共静态MovementMethod的getInstance(){
        如果(sInstance == NULL){
            sInstance =新EnhancedMovementMethod();
        }
        返回sInstance;
    }

    @覆盖
    公共布尔的onTouchEvent(TextView的小部件,Spannable缓冲,MotionEvent事件){
        INT行动= event.getAction();

        如果(行动== MotionEvent.ACTION_UP ||
            行动== MotionEvent.ACTION_DOWN){
            INT X =(int)的event.getX();
            INT Y =(INT)event.getY();

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

            X + = widget.getScrollX();
            Y + = widget.getScrollY();

            布局布局= widget.getLayout();
            INT线= layout.getLineForVertical(Y);
            诠释关闭= layout.getOffsetForHorizo​​ntal(线,X);

            ClickableSpan []链接= buffer.getSpans(脱,脱,ClickableSpan.class);

            如果(link.length!= 0){
                如果(动作== MotionEvent.ACTION_UP){
                    链接[0] .onClick(小工具);
                }
                否则,如果(动作== MotionEvent.ACTION_DOWN){
                    Selection.setSelection(缓冲液,buffer.getSpanStart(联系[0]),buffer.getSpanEnd(联系[0]));
                }

                返回true;
            }
            /*其他 {
                Selection.removeSelection(缓冲液);
            } * /
        }

        返回super.onTouchEvent(窗口小部件,缓冲,事件);
    }

}
 

所有你需要做的是设置你的EditText的运动方法,你是好去:

  yourEditTExt.setMovementMethod(EnhancedMovementMethod.getInstance());
 

在code以上仅适用于无格式文本,这意味着一旦你决定要使用的格式文本样式(粗体,斜体等)或不同的字体大小的文字,也不会发现点击链接了。我确实有code,处理格式的文本,但因为这是不是问题的一部分,我做了抽样code尽可能短。

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);
       }
}

I set clickable spans on my text like this:

spanStr.setSpan(new ClickableString(new linkedTextClickListener(), linkColor),
                        startIndex, endIndex,
                        SpannableString.SPAN_INCLUSIVE_EXCLUSIVE);

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.

解决方案

You need to set the TextView's/EditText's movement method to LinkMovementMethod to be able to get clicked links. Unfortunately that disables the ability to select text which works only if you set the movement method to ArrowKeyMovementMethod. http://developer.android.com/reference/android/text/method/LinkMovementMethod.html http://developer.android.com/reference/android/text/method/ArrowKeyMovementMethod.html

To solve this I created an custom MovementMethod class that inherits from ArrowKeyMovementMethod and adds the ability to click links. :

/**
 * 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);
    }

}

All you need to do is set the movement method of your EditText and you're good to go:

yourEditTExt.setMovementMethod(EnhancedMovementMethod.getInstance());

The code above only works with unformatted text, meaning once you decide to format your text using text styles (bold, italic etc.) or different font sizes, it won't find the clicked link any more. I do have the code to deal with formatted text but since that wasn't part of the question I made the sample code as short as possible.