Android lineSpacingExtra 解决行间距兼容性问题

      当我们使用TextView显示多行的文字或者单行时,为了美观,一般会加上行间距,这时就会用到lineSpacingExtra这个属性。

Android 5.0以下,在这个系统里面会添加一个行间距,导致多余空白。

Adnroid 5.0以上,google修复这个问题,但是由于厂商定制不一样,导致一些5.1版本的手机也会出现同样的问题,oppo等

 解决思路:

    1.需要理解一下字体属性及测量,先看一下https://blog.csdn.net/g0ose/article/details/80547461这一篇博客

    2.那么从上面博客里面我们知道 , baseline,Descent这俩个属性

    我们是否可以这样想一下,baseline + Descent + linespace? + paddingbottom = 组件最下面高度

    3.自定义TextView

  按上面思路,我们先继承一个AppCompatTextView,

   

public class LastLineSpaceTextView extends AppCompatTextView {



    public LastLineSpaceTextView(Context context) {
        this(context, null);
    }

    public LastLineSpaceTextView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);

    }

    public LastLineSpaceTextView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }
}

我们需要到baseLine的高度,怎么去获取这个高度呢?看一下AppCompatTextView里面继承的TextView:

    1. TextView有这个方法getLineBounds(int line, Rect bounds)

      参数一:指定的行数的索引

      参数二:传入一个rect实例,返回指定行的边框数据

      返回值:所在行的baseline的y坐标

   那么我们是不是可以知道了baseline的高度呢?看下面代码:

  private Rect mLastLineRect;
  
  private void init() {
        mLastLineRect = new Rect();
    }
  int lastlineIndex = Math.min(getMaxLines(), getLineCount()) - 1;//获取最后一行的index
 int baseline = getLineBounds(lastlineIndex, mLastLineRect);//获取到高度
  

其中getLineCount()获取的是实际行数(并不是指展示行数),getMaxLines()获取最大行数。

那么当最大行数小于实际行数,取最大行数

那么baseline拿到了,下一步获取Descent

Layout layout = getLayout();
layout.getPaint().getFontMetricsInt().descent

那么这样paddingbottom:getPaddingBottom()获取到了

那么linesspace:getLineSpacingExtra();

获取最下面高度:

mLastLineRect.bottom//就是bottom的高度


搭配完毕;下面开始撸代码了;

重点在于


    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }

  下面我们需要设置高度:setMeasuredDimension(width,height);

需要的点在于height:重新设置高度

那么针对高度进行一个计算

import android.content.Context;
import android.graphics.Rect;
import android.support.annotation.Nullable;
import android.support.v7.widget.AppCompatTextView;
import android.text.Layout;
import android.util.AttributeSet;

public class LastLineSpaceTextView extends AppCompatTextView {

    private Rect mLastLineRect;
    private Rect mLastLineIndexRect;


    public LastLineSpaceTextView(Context context) {
        this(context, null);
    }

    public LastLineSpaceTextView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);

    }

    public LastLineSpaceTextView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    private void init() {
        mLastLineRect = new Rect();
        mLastLineIndexRect = new Rect();
    }




    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        setMeasuredDimension(getMeasuredWidth(), getMeasuredHeight() - calculateSpace());
    }


    private int calculateSpace() {
        int result = 0;
        //界面显示的最后一行的index
        int lastlineIndex = Math.min(getMaxLines(), getLineCount()) - 1;
        //获取实际的最后一行
        int lastLineNomalIndex = getLineCount() - 1;

        if (lastlineIndex >= 0) {
            Layout layout = getLayout();
            int baseline = getLineBounds(lastlineIndex, mLastLineRect);
            getLineBounds(lastLineNomalIndex, mLastLineIndexRect);
            int height = (mLastLineIndexRect.bottom - mLastLineRect.bottom);


            if (getMeasuredHeight() == getLayout().getHeight() - height) {
                if (getLineSpacingExtra() == 0) {
                    result = 0;
                } else {
                    result = mLastLineRect.bottom - (baseline + layout.getPaint().getFontMetricsInt().descent + getPaddingBottom());
                    if (getLineSpacingExtra() > result) {
                        result = 0;
                    } else {
                        result = (int) getLineSpacingExtra();
                    }
                }

            }

        }
        return result;
    }

}

代码如上:

直接使用这个TextView,属性设置就ok了

另外还有一种方式解决如这个博客:https://blog.csdn.net/etwge/article/details/72818859 

你可能感兴趣的:(安卓,android)