美文网首页
AndroidText设置SpannableString后,文本

AndroidText设置SpannableString后,文本

作者: 逸云天 | 来源:发表于2017-12-11 14:34 被阅读0次

    问题描述

    之前就TextView通过设置SpannableString封装了一个TextView设置不同的文字颜色,文字大小,点击事件的公共方法,实现了字符串不同区域显示不同颜色、响应不同点击事件的需求。后来某个同事有类似需求使用该方法后,发现文字不显示了,点击一下文字区域又会显示,太诡异了。

    /**
     * 设置TextView不同的颜色,大小,点击事件,要求字符串列表大小=颜色列表大小,否则设置失败
     * @param tv TextView
     * @param str 不同字符串列表
     * @param color 不同颜色列表
     * @param isUnderLine 是否显示下划线
     * @param clickListener 点击回调接口
     */
    public static void setText(TextView tv,
                               String[] str,
                               int[] color,
                               boolean[] isUnderLine,
                               ClickListener clickListener) {
    
        if(str == null || color == null || tv == null){
            return;
        }
    
        if(str.length != color.length) {
            return;
        }
    
        StringBuilder long_str = new StringBuilder();
        for (int i = 0; i < str.length; i++) {
            long_str.append(str[i]);
        }
    
        SpannableString builder = new SpannableString(long_str.toString());
    
        for (int i = 0; i < str.length; i++) {
    
            try {
                int star = long_str.toString().indexOf(str[i]);
                int end = star + str[i].length();
    
                // 设置不同字符串的点击事件
                if (clickListener != null) {
                    builder.setSpan(new Clickable(clickListener, i), star, end,
                            Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
                }
    
                // 设置不同字符串的颜色
                builder.setSpan(new ForegroundColorSpan(color[i]), star, end,
                        Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
                TestLog.i(TAG, TestLog.isDebug() ? "start = " + star + ", end = " + end : "");
                //设置下划线
                if (isUnderLine != null && isUnderLine.length > i && isUnderLine[i]) {                  
                    TextPaint paint = new TextPaint();
                    Field field = TextPaint.class.getDeclaredField("underlineColor");
                    field.setAccessible(true);
                    field.set(paint, Color.BLACK);
                    UnderlineSpan underLineSpan = new UnderlineSpan();
                    underLineSpan.updateDrawState(paint);
                    builder.setSpan(underLineSpan, star, end, 0);
                    TestLog.d("test", "UnderlineSpan");
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
        if (clickListener != null) {//没有点击事件的时候 不设置点击事件
            tv.setHighlightColor(Color.TRANSPARENT);// 设置点击后的颜色为透明,否则会一直出现高亮
            tv.setClickable(true);
            tv.setMovementMethod(LinkMovementMethod.getInstance());//这一句和textView的Grivity center冲突而导致不显示
        }
        tv.setText(builder);
    }
    

    问题解决

    通过和之前类似功能对比和尝试,发现这次新的TextView设置了gravity属性,去掉后就可以正常显示了,难道是gravity属性和设置SpannableString冲突?测试后又发现如果设置设置了gravity属性但是调用如上方法时,传入的自定义点击事件为NULL时,也可以正常显示,看来可以再缩小问题原因的范围。

    多次测试验证后发现:同时设置gravity属性和setMovementMethod(LinkMovementMethod.getInstance());就会出现文本显示不全的问题。先记录一下,具体原理性的原因,之后再学习源码了解。

    相关文章

      网友评论

          本文标题:AndroidText设置SpannableString后,文本

          本文链接:https://www.haomeiwen.com/subject/jmriixtx.html