android – 在Lollipop上打破的TextView fromHtml链接

android – 在Lollipop上打破的TextView fromHtml链接,第1张

概述我们的应用程序有几个TextViews实例,其内容由myTv.setText( Html.from Html())设置;已经适用于 Android 4.4.0及更低版本. 从4.4.2和Lollypop开始,这些链接已停止工作.文本仍显示带下划线且带有超链接颜色,但点击它们不会产生任何结果. 必须要说的是,这些字段被标记为可复制粘贴,已知这些字段与这些字段相互作用. 有没有人能够解决这个问题? 问 我们的应用程序有几个TextVIEws实例,其内容由myTv.setText( Html.from Html())设置;已经适用于 Android 4.4.0及更低版本.

从4.4.2和Lollypop开始,这些链接已停止工作.文本仍显示带下划线且带有超链接颜色,但点击它们不会产生任何结果.

必须要说的是,这些字段被标记为可复制粘贴,已知这些字段与这些字段相互作用.

有没有人能够解决这个问题?

解决方法 问题是,当在TextVIEw中启用复制和粘贴时,AndroID将使用ArrowKeyMovementMethod,它支持选择文本但不支持单击链接.当您使用@R_404_6862@MovementMethod时,您可以单击链接但不能选择文本(无论您使用的是Lollipop,KitKat还是较低的AndroID版本).

为了解决这个问题,我扩展了ArrayKeyMovementMethod类并使用@R_404_6862@MovementMethod ontouchEvent覆盖了ontouchEvent.为了允许文本选择,我必须删除三行代码.由于我在具有大量文本格式的富文本编辑器中使用该类,因此我还添加了逻辑来查找所单击的字符,而不管文本大小,缩进或文本对齐.如果您希望使用纯文本的简单解决方案,请在自定义ArrowKeyMovementMethod类中使用它:

@OverrIDepublic 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[] @R_404_6862@ = buffer.getSpans(off,off,ClickableSpan.class);        if (@R_404_6862@.length != 0) {            if (action == MotionEvent.ACTION_UP) {                @R_404_6862@[0].onClick(Widget);            } else if (action == MotionEvent.ACTION_DOWN) {                Selection.setSelection(buffer,buffer.getSpanStart(@R_404_6862@[0]),buffer.getSpanEnd(@R_404_6862@[0]));            }            return true;        }        /* These are the lines of code you want to remove        else {            Selection.removeSelection(buffer);        }*/    }    return super.ontouchEvent(Widget,buffer,event);}

别忘了打电话:
myTv.setMovementMethod(new ClickAndSelectMovementMethod());

如果您希望支持各种文本格式的版本使用此代码:

import androID.graphics.Rect;import androID.text.Layout;import androID.text.Selection;import androID.text.Spannable;import androID.text.Spanned;import androID.text.TextPaint;import androID.text.method.ArrowKeyMovementMethod;import androID.text.method.MovementMethod;import androID.text.style.absoluteSizeSpan;import androID.text.style.ClickableSpan;import androID.text.style.LeadingmarginSpan;import androID.vIEw.MotionEvent;import androID.Widget.TextVIEw;/** * ArrowKeyMovementMethod does support selection of text but not the clicking of * @R_404_6862@s. @R_404_6862@MovementMethod does support clicking of @R_404_6862@s but not the * selection of text. This class adds the @R_404_6862@ clicking to the * ArrowKeyMovementMethod. We basically take the @R_404_6862@MovementMethod ontouchEvent * code and remove the line Selection.removeSelection(buffer); which de-selects * all text when no @R_404_6862@ was found. */public class ClickAndSelectMovementMethod extends ArrowKeyMovementMethod {    private static Rect slineBounds = new Rect();    @OverrIDe    public boolean ontouchEvent(TextVIEw Widget,MotionEvent event) {        int action = event.getAction();        if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_DOWN) {            int index = getCharIndexAt(Widget,event);            if (index != -1) {                ClickableSpan[] @R_404_6862@ = buffer.getSpans(index,index,ClickableSpan.class);                if (@R_404_6862@.length != 0) {                    if (action == MotionEvent.ACTION_UP) {                        @R_404_6862@[0].onClick(Widget);                    } else if (action == MotionEvent.ACTION_DOWN) {                        Selection.setSelection(buffer,buffer.getSpanEnd(@R_404_6862@[0]));                    }                    return true;                }            }            /*             * else { Selection.removeSelection(buffer); }             */        }        return super.ontouchEvent(Widget,event);    }    private int getCharIndexAt(TextVIEw textVIEw,MotionEvent event) {        // get coordinates        int x = (int) event.getX();        int y = (int) event.getY();        x -= textVIEw.getTotalpaddingleft();        y -= textVIEw.getTotalpaddingtop();        x += textVIEw.getScrollX();        y += textVIEw.getScrollY();        /*         * fail-fast check of the line bound. If we're not within the line bound         * no character was touched         */        Layout layout = textVIEw.getLayout();        int line = layout.getlineForVertical(y);        synchronized (slineBounds) {            layout.getlineBounds(line,slineBounds);            if (!slineBounds.contains(x,y)) {                return -1;            }        }        // retrIEve line text        Spanned text = (Spanned) textVIEw.getText();        int linestart = layout.getlinestart(line);        int lineEnd = layout.getlineEnd(line);        int lineLength = lineEnd - linestart;        if (lineLength == 0) {            return -1;        }        Spanned lineText = (Spanned) text.subSequence(linestart,lineEnd);        // compute leading margin and subtract it from the x coordinate        int margin = 0;        LeadingmarginSpan[] marginSpans = lineText.getSpans(0,lineLength,LeadingmarginSpan.class);        if (marginSpans != null) {            for (LeadingmarginSpan span : marginSpans) {                margin += span.getLeadingmargin(true);            }        }        x -= margin;        // retrIEve text wIDths        float[] wIDths = new float[lineLength];        TextPaint paint = textVIEw.getPaint();        paint.getTextWIDths(lineText,wIDths);        // scale text wIDths by relative Font size (absolute size / default size)        final float defaultSize = textVIEw.getTextSize();        float scaleFactor = 1f;        absoluteSizeSpan[] absspans = lineText.getSpans(0,absoluteSizeSpan.class);        if (absspans != null) {            for (absoluteSizeSpan span : absspans) {                int spanStart = lineText.getSpanStart(span);                int spanEnd = lineText.getSpanEnd(span);                scaleFactor = span.getSize() / defaultSize;                int start = Math.max(linestart,spanStart);                int end = Math.min(lineEnd,spanEnd);                for (int i = start; i < end; i++) {                    wIDths[i] *= scaleFactor;                }            }        }        // find index of touched character        float startChar = 0;        float endChar = 0;        for (int i = 0; i < lineLength; i++) {            startChar = endChar;            endChar += wIDths[i];            if (endChar >= x) {                // which "end" is closer to x,the start or the end of the character?                int index = linestart + (x - startChar < endChar - x ? i : i + 1);                return index;            }        }        return -1;    }}
总结

以上是内存溢出为你收集整理的android – 在Lollipop上打破的TextView fromHtml链接全部内容,希望文章能够帮你解决android – 在Lollipop上打破的TextView fromHtml链接所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1127772.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-30
下一篇 2022-05-30

发表评论

登录后才能评论

评论列表(0条)

保存