TextView自动换行以及内容过长全部显示--终极解决办法

androidstarjack的博客地址:
http://blog.csdn.net/androidstarjack/article/details/58616154

最近在写项目的时候要求内容过长加省略号或者是右边有箭头,点击显示全部内容,下方有想向上的箭头,点击底部箭头进行收回,单行显示。

  • #### TextView显示一行,点击展开显示全部,再次点击单行显示
  • #### 解决TextView显示 自动换行
    话不多说,先上效果图:

Markdown

在Android TextView中有个内容过长加省略号的属性,即ellipsize,用法如下:
在xml中:
  • android:ellipsize=”end”   省略号在结尾
  • android:ellipsize=”start”   省略号在开头
  • android:ellipsize=”middle” 省略号在中间
  • android:ellipsize=”marquee” 跑马灯
  • 最好加一个TextView显示行数的约束,例如:

    android:singleline=”true”或者android:lines=”2”

在java文件中:
  • tv.setEllipsize(TextUtils.TruncateAt.valueOf(“END”));
  • tv.setEllipsize(TextUtils.TruncateAt.valueOf(“START”));
  • tv.setEllipsize(TextUtils.TruncateAt.valueOf(“MIDDLE”));
  • tv.setEllipsize(TextUtils.TruncateAt.valueOf(“MARQUEE”));

最好加一个TextView显示行数的约束,例如:
tv.setSingleLine(true);
不仅对于textview有此属性,对于editext也有,不过它不支持marquee。
- ### TextView显示一行,点击展开显示全部,再次点击单行显示
主要代码:


    /**
     * TextView显示一行,点击展开显示全部,再次点击单行显示
     * 传入集合
     * @param list
     * @param tv_content_contact
     * @param ll_arrow_right
     * @param tv_arrow_contact_bottom
     * @param ic_title_contactleft
     * @param ll_contact_content
     */
    public static void setMyConactTextConMsg(List<Student> list, final TextView tv_content_contact, final LinearLayout ll_arrow_right, final TextView tv_arrow_contact_bottom,
                                             TextView ic_title_contactleft, LinearLayout ll_contact_content) {
        if(list != null){
            if(list != null){
                if(list.size() > 0){
                    ll_contact_content.setVisibility(View.VISIBLE);
                }else{
                    return ;
                }
                StringBuilder sb = new StringBuilder();
                for (int i = 0; i <list.size() ; i++) {
                    if(sb.length() > 0 ){
                        sb.append(",");
                    }
                    sb.append(list.get(i).getDes());
                }

                tv_content_contact.setText(sb.toString());
                ic_title_contactleft.setText("签约人: ");//设置title
                tv_content_contact.setMaxLines(1);
                int textViewContentLength  = DensityUtil.getScreenIntWidth(MyApplication.getContext()) - DensityUtil.dip2px(MyApplication.getContext(),30+70+10) ;
                Paint  paint =  tv_content_contact.getPaint();
                float realLength = paint.measureText(sb.toString());
                if(realLength > textViewContentLength+DensityUtil.dip2px(MyApplication.getContext(),30 - 10)){//  实际长度 > TextView的长度
                    ll_arrow_right.setVisibility(View.VISIBLE);
                    tv_arrow_contact_bottom.setVisibility(View.GONE);
                    tv_content_contact.setMaxLines(1);
                }else{
                    ll_arrow_right.setVisibility(View.GONE);
                    tv_arrow_contact_bottom.setVisibility(View.GONE);
                    tv_content_contact.setMaxLines(1);
                }
            }
            ll_arrow_right.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    tv_content_contact.setMaxLines(Integer.MAX_VALUE);
                    ll_arrow_right.setVisibility(View.GONE);
                    tv_arrow_contact_bottom.setVisibility(View.VISIBLE);
                }
            });
            tv_arrow_contact_bottom.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    tv_content_contact.setMaxLines(1);
                    ll_arrow_right.setVisibility(View.VISIBLE);
                    tv_arrow_contact_bottom.setVisibility(View.GONE);
                }
            });
        }
    }
    /**
     * TextView显示一行,点击展开显示全部,再次点击单行显示
     * 传入字符串
     * @param resulrStr
     * @param tv_content_contact
     * @param tv_arrow_contact_bottom
     * @param ic_title_contactleft
     */
    public static void setMyResultTextConMsg(String resulrStr, final JustifyTextView tv_content_contact,   final TextView tv_arrow_contact_bottom,
                                             TextView ic_title_contactleft) {
        if(!TextUtils.isEmpty(resulrStr)){
            tv_content_contact.setText(resulrStr);
            Paint  paint =  tv_content_contact.getPaint();
            float realLength = paint.measureText(resulrStr.toString());
            ic_title_contactleft.setText("签约人: ");//设置title
            tv_content_contact.setMaxLines(2);
            tv_content_contact.setMaxLines(2);
            tv_arrow_contact_bottom.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    tv_content_contact.setMaxLines(Integer.MAX_VALUE);
                    tv_arrow_contact_bottom.setVisibility(View.GONE);

                }
            });
            tv_content_contact.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    tv_content_contact.setMaxLines(2);
                    tv_content_contact.setEllipsize(TextUtils.TruncateAt.END);
                    tv_arrow_contact_bottom.setVisibility(View.VISIBLE);
                }
            });
        }
    }

MainActivity中的代码:

/**
 * 类功能描述:</br>
 * TextView显示一行,点击展开显示全部,再次点击单行显示
 * @author yuyahao
 * @version 1.0 </p> 修改时间:</br> 修改备注:</br>
 */
public class MainActivity2 extends Activity {
    @Bind(R.id.tv_arrow_contact_bottom)
    TextView tv_arrow_contact_bottom;
    @Bind(R.id.ll_arrow_right)
    LinearLayout ll_arrow_right;
    @Bind(R.id.tv_content_contact)
    TextView tv_content_contact;
    @Bind(R.id.ic_title_contactleft)
    TextView ic_title_contactleft;
    @Bind(R.id.ll_contact_content)
    LinearLayout ll_contact_content;

    @Bind(R.id.tv_arrow_contact_bottom1)
    TextView tv_arrow_contact_bottom1;
    @Bind(R.id.tv_content_contact1)
    JustifyTextView tv_content_contact1;
    @Bind(R.id.ic_title_contactleft1)
    TextView ic_title_contactleft1;
    @Bind(R.id.ll_contact_content1)
    LinearLayout ll_contact_content1;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main2);
        ButterKnife.bind(this);
        List<Student> list = ServiceData.getCityDefaultPosition2();
        DealUiUtils.setMyConactTextConMsg(list,tv_content_contact,ll_arrow_right,tv_arrow_contact_bottom,ic_title_contactleft,ll_contact_content);
        String resultStr = ServiceData.getMyResult();
        DealUiUtils.setMyResultTextConMsg(resultStr,tv_content_contact1,tv_arrow_contact_bottom1,ic_title_contactleft1);
    }
}
  • #### 解决TextView显示 自动换行
    据说好像系统级别的BUG,终于找到了textview自动换行导致混乱的原因了—-半角字符与全角字符混乱所致!一般情况下,我们输入的数字、字母以及英文标点都是半角,所以占位无法确定。它们与汉字的占位大大的不同,由于这个原因,导致很多文字的排版都是参差不齐的。

没解决之前:

Markdown

解决之后:

Markdown

这里是重新自定义TextView:

/**
 * 类功能描述:</br>
 *解决TextView显示自动换行问题
 * @author 
 * @version 1.0 </p> 修改时间:</br> 修改备注:</br>
 */

public class JustifyTextView extends TextView {

    private int mLineY;
    private int mViewWidth;
    public static final String TWO_CHINESE_BLANK = "  ";

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

    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        super.onLayout(changed, left, top, right, bottom);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        TextPaint paint = getPaint();
        paint.setColor(getCurrentTextColor());
        paint.drawableState = getDrawableState();
        mViewWidth = getMeasuredWidth();
        String text = getText().toString();
        mLineY = 0;
        mLineY += getTextSize();
        Layout layout = getLayout();

        // layout.getLayout()在4.4.3出现NullPointerException
        if (layout == null) {
            return;
        }

        Paint.FontMetrics fm = paint.getFontMetrics();

        int textHeight = (int) (Math.ceil(fm.descent - fm.ascent));
        textHeight = (int) (textHeight * layout.getSpacingMultiplier() + layout.getSpacingAdd());

        for (int i = 0; i < layout.getLineCount(); i++) {
            int lineStart = layout.getLineStart(i);
            int lineEnd = layout.getLineEnd(i);
            float width = StaticLayout.getDesiredWidth(text, lineStart, lineEnd, getPaint());
            String line = text.substring(lineStart, lineEnd);
            if (needScale(line) && i < layout.getLineCount() -1) {
                drawScaledText(canvas, lineStart, line, width);
            } else {
                canvas.drawText(line, 0, mLineY, paint);
            }
            mLineY += textHeight;
        }
    }

    private void drawScaledText(Canvas canvas, int lineStart, String line, float lineWidth) {
        float x = 0;
        if (isFirstLineOfParagraph(lineStart, line)) {
            String blanks = "  ";
            canvas.drawText(blanks, x, mLineY, getPaint());
            float bw = StaticLayout.getDesiredWidth(blanks, getPaint());
            x += bw;

            line = line.substring(3);
        }

        int gapCount = line.length() - 1;
        int i = 0;
        if (line.length() > 2 && line.charAt(0) == 12288 && line.charAt(1) == 12288) {
            String substring = line.substring(0, 2);
            float cw = StaticLayout.getDesiredWidth(substring, getPaint());
            canvas.drawText(substring, x, mLineY, getPaint());
            x += cw;
            i += 2;
        }

        float d = (mViewWidth - lineWidth) / gapCount;
        for (; i < line.length(); i++) {
            String c = String.valueOf(line.charAt(i));
            float cw = StaticLayout.getDesiredWidth(c, getPaint());
            canvas.drawText(c, x, mLineY, getPaint());
            x += cw + d;
        }
    }

    private boolean isFirstLineOfParagraph(int lineStart, String line) {
        return line.length() > 3 && line.charAt(0) == ' ' && line.charAt(1) == ' ';
    }

    private boolean needScale(String line) {
        if (line == null || line.length() == 0) {
            return false;
        } else {
            return line.charAt(line.length() - 1) != '\n';
        }
    }

}

当然网上有很多解决办法。这个JustifyTextView会根据屏幕宽度以及字体大小,动态调整字体的间距来填充满一行English。

总结总会有收获。相信自己。

如果你觉得此文对您有所帮助,欢迎入群 QQ交流群 :232203809
微信公众号:终端研发部
Markdown

(欢迎关注学习和交流)

猜你喜欢

转载自blog.csdn.net/androidstarjack/article/details/58616154
今日推荐