Java自学者论坛

 找回密码
 立即注册

手机号码,快捷登录

恭喜Java自学者论坛(https://www.javazxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,会员资料板块,购买链接:点击进入购买VIP会员

JAVA高级面试进阶训练营视频教程

Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程Go语言视频零基础入门到精通Java架构师3期(课件+源码)
Java开发全终端实战租房项目视频教程SpringBoot2.X入门到高级使用教程大数据培训第六期全套视频教程深度学习(CNN RNN GAN)算法原理Java亿级流量电商系统视频教程
互联网架构师视频教程年薪50万Spark2.0从入门到精通年薪50万!人工智能学习路线教程年薪50万大数据入门到精通学习路线年薪50万机器学习入门到精通教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程MySQL入门到精通教程
查看: 517|回复: 0

解决android系统TextView自动换行不美观问题

[复制链接]
  • TA的每日心情
    奋斗
    3 天前
  • 签到天数: 789 天

    [LV.10]以坛为家III

    2049

    主题

    2107

    帖子

    72万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    722638
    发表于 2021-6-13 08:20:28 | 显示全部楼层 |阅读模式

    android系统中的textview会在行尾是连串的数字、字母或者标点符号时提前换行,其实word中也是会提前换行的,但是PC端毕竟字符占的空间比例比较小,手机字符占的比例就很大,所以有时候系统自带textview显示行尾会有很大的空白比例,非常难看。所以我们在这种情况下有必要做一个控件用来显示文本。

    public class AutoBreakTextView extends TextView {

    public static int m_iTextHeight; // 文本的高度
    public static int m_iTextWidth;// 文本的宽度

    private Paint mPaint = null;
    private String string = "";
    private float LineSpace = 0;// 行间距
    private int padding;

    public AutoBreakTextView(Context context, AttributeSet set) {
    super(context, set);

    WindowManager manager = (WindowManager) context
    .getSystemService(Context.WINDOW_SERVICE);
    DisplayMetrics dm = new DisplayMetrics();
    manager.getDefaultDisplay().getMetrics(dm);
    System.out.println("width------>" + dm.widthPixels);
    System.out.println("density-------------->" + dm.density);
    m_iTextWidth = (int) (dm.widthPixels - 2 * padding - (10 * 4 * dm.density)) + 1;
    float textSize = this.getTextSize();
    padding = this.getPaddingLeft();
    System.out.println("width------------>" + m_iTextWidth);
    System.out.println("textSize------------>" + textSize);
    mPaint = new Paint();
    mPaint.setAntiAlias(true);
    mPaint.setTextSize(textSize);
    mPaint.setColor(Color.GRAY);
    }

    @Override
    protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);

    char ch;
    int w = 0;
    int istart = 0;
    int m_iFontHeight;
    int m_iRealLine = 0;
    int x = padding;
    int y = padding;

    Vector m_String = new Vector();

    FontMetrics fm = mPaint.getFontMetrics();
    m_iFontHeight = (int) Math.ceil(fm.descent - fm.top) + (int) LineSpace;// 计算字体高度(字体高度+行间距)

    for (int i = 0; i < string.length(); i++) {
    ch = string.charAt(i);
    float[] widths = new float[1];
    String srt = String.valueOf(ch);
    mPaint.getTextWidths(srt, widths);

    if (ch == '\n') {
    m_iRealLine++;
    m_String.addElement(string.substring(istart, i));
    istart = i + 1;
    w = 0;
    } else {
    w += (int) (Math.ceil(widths[0]));
    if (w > m_iTextWidth) {
    m_iRealLine++;
    m_String.addElement(string.substring(istart, i));
    istart = i;
    i--;
    w = 0;
    } else {
    if (i == (string.length() - 1)) {
    m_iRealLine++;
    m_String.addElement(string.substring(istart,
    string.length()));
    }
    }
    }
    }
    canvas.setViewport(m_iTextWidth, m_iTextHeight);
    for (int i = 0, j = 1; i < m_iRealLine; i++, j++) {
    canvas.drawText((String) (m_String.elementAt(i)), x, y
    + m_iFontHeight * j, mPaint);
    }
    }

    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    int measuredHeight = measureHeight(heightMeasureSpec);
    int measuredWidth = measureWidth(widthMeasureSpec);
    System.out.println("measuredHeight------->" + measuredHeight);
    this.setMeasuredDimension(measuredWidth, measuredHeight);
    this.setLayoutParams(new LinearLayout.LayoutParams(measuredWidth,
    measuredHeight));
    }

    private int measureHeight(int measureSpec) {
    int specMode = MeasureSpec.getMode(measureSpec);
    int specSize = MeasureSpec.getSize(measureSpec);
    // Default size if no limits are specified.
    initHeight();
    int result = m_iTextHeight;
    Log.e("measureHeight---------------->", result + "");
    return result;
    }

    private void initHeight() {
    m_iTextHeight = 0;

    FontMetrics fm = mPaint.getFontMetrics();
    int m_iFontHeight = (int) Math.ceil(fm.descent - fm.top)
    + (int) LineSpace;
    int line = 0;
    int istart = 0;

    int w = 0;
    for (int i = 0; i < string.length(); i++) {
    char ch = string.charAt(i);
    float[] widths = new float[1];
    String srt = String.valueOf(ch);
    mPaint.getTextWidths(srt, widths);

    if (ch == '\n') {
    line++;
    istart = i + 1;
    w = 0;
    } else {
    w += (int) (Math.ceil(widths[0]));
    if (w > m_iTextWidth) {
    line++;
    istart = i;
    i--;
    w = 0;
    } else {
    if (i == (string.length() - 1)) {
    line++;
    }
    }
    }
    }
    m_iTextHeight = (line) * m_iFontHeight;
    Log.e("m_iTextHeight--------------------->", m_iTextHeight + "");
    }

    private int measureWidth(int measureSpec) {
    int specMode = MeasureSpec.getMode(measureSpec);
    int specSize = MeasureSpec.getSize(measureSpec);

    // Default size if no limits are specified.
    int result = 500;
    if (specMode == MeasureSpec.AT_MOST) {
    // Calculate the ideal size of your control
    // within this maximum size.
    // If your control fills the available space
    // return the outer bound.
    result = specSize;
    } else if (specMode == MeasureSpec.EXACTLY) {
    // If your control can fit within these bounds return that value.
    result = specSize;
    }
    return result;
    }

    public void setText(String text) {
    string = text;
    initHeight();
    invalidate();
    requestLayout();
    }
    }

     

    没有用到自定义属性,代码不太完美,以后改进

    需要注意的是:

    canvas.drawText(String str,int x,int y,Paint paint)中的x,y不能是左上角,而是一行的左下角,因为canvas绘制文本是根据基线为基准的

    基线如图中baseLine

    哎...今天够累的,签到来了1...
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|小黑屋|Java自学者论坛 ( 声明:本站文章及资料整理自互联网,用于Java自学者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2024-9-9 04:54 , Processed in 1.055259 second(s), 29 queries .

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

    快速回复 返回顶部 返回列表