自适应textView宽高调节textSize的view

最近项目里面RecyclerView做4列显示文字标签,但是按UI给的标注设置后,标签还是可能不止占一行,一些小屏手机时就不是预期效果了,于是自己摸索了一个view来根据宽高调节textSize:


自适应textView宽高调节textSize的view_第1张图片
image.png

代码贴出来,可能还不是很完善,一个思路:

/**
   * use to do 如果限定textView的宽度,则根据宽度显示文字,字体大小改变
   * 绘制只在居中绘制的样式,其他样式需要自己完善
   *
   * @author zhangdong on 2018/2/11 0011.
   * @version 1.0
   * @see .
   * @since 1.0
   */
public class WrapContentTextView extends AppCompatTextView {

    private static final String TAG = "WrapContentTextView";
    private Paint mPaint;
    private Boolean isWrapContent = false;//是否开启根据view的宽高调节字体大小

    public void setWrapContent(Boolean wrapContent) {
        isWrapContent = wrapContent;
        invalidate();
    }

    public Boolean getWrapContent() {
        return isWrapContent;
    }

    public WrapContentTextView(Context context) {
        super(context);
        init();
    }

    public WrapContentTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
        TypedArray typedArray = context.getTheme()
                            .obtainStyledAttributes(attrs, R.styleable.WrapContentTextView, 0, 0);
        isWrapContent = typedArray.getBoolean(R.styleable.WrapContentTextView_isWrapContent, false);
        typedArray.recycle();
        init();
    }

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

    private void init() {
        mPaint = new Paint();
        mPaint.setAntiAlias(true);
        float density = getResources().getDisplayMetrics().density;
        Log.d(TAG, "onDraw: ------- 屏幕密度系数density = " + density);
    }

    @Override
    protected void onDraw(Canvas canvas) {

        if (isWrapContent) {
            int width = getWidth();
            int height = getHeight();
            Log.d(TAG, "onDraw: ------- View的width = " + width + "; View的height = " + height);

            CharSequence text = getText();

            if (!TextUtils.isEmpty(text)) {
                //文字的字数
                int length = text.length();

                //view的内边距
                int paddingLeft = getPaddingLeft();
                int paddingRight = getPaddingRight();
                int paddingTop = getPaddingTop();
                int paddingBottom = getPaddingBottom();

                Log.d(TAG, "onDraw: ------- paddingLeft = " + paddingLeft +
                        "; paddingTop = " + paddingTop +
                        "; paddingRight = " + paddingRight +
                        "; paddingBottom = " + paddingBottom);

                //文字可绘制的宽高
                int textWidth = width - paddingLeft - paddingRight;
                int textHeight = height - paddingTop - paddingBottom;

                //一个字可绘制的宽度
                int oneWidth = textWidth / length;

                //一个字可绘制的宽度与可绘制的高度取最小的值
                int textSize = Math.min(oneWidth, textHeight);

                Log.d(TAG, "onDraw: ------- 文字长度:" + length +
                        "; 可绘制的textWidth = " + textWidth +
                        "; oneWidth = " + oneWidth +
                        "; 可绘制的textHeight = " + textHeight);

                //当前文字的size
                float size = getTextSize();
                float measureText = getPaint().measureText(text, 0, length);
                Log.d(TAG, "onDraw: ------- 初始文字的size = " + size +
                        "; 初始文字的宽measureText = " + measureText);

                //获取当前文字的高度
                Paint.FontMetrics fontMetrics = getPaint().getFontMetrics();
                float tHeight = fontMetrics.bottom - fontMetrics.top;

                Log.d(TAG, "onDraw: ------- 初始文字的fontMetrics.bottom= " + fontMetrics.bottom +
                        "; 初始文字的fontMetrics.top= " + fontMetrics.top +
                        "; 初始文字的高度tHeight= " + tHeight);

                float newSize = 0;
                //新的文字大小根据宽度比例关系得到
                float newSizeW = size * textSize * length / measureText;
                //新的文字大小根据高度比例关系得到
                float newSizeH = size * textHeight / tHeight;

                Log.d(TAG, "onDraw: ------- 根据宽度比例关系得到newSizeW= " + newSizeW +
                        "; 根据高度比例关系得到newSizeH= " + newSizeH);

                newSize = Math.min(newSizeW, newSizeH);

                Log.d(TAG, "onDraw: ------- 取最小的文字大小设置给画笔newSize : " + newSize);

                mPaint.setTextSize(newSize);
                mPaint.setColor(getCurrentTextColor());

                Rect textRect = new Rect();
                mPaint.getTextBounds(text.toString(), 0, length, textRect);

                Paint.FontMetrics mPaintFontMetrics = mPaint.getFontMetrics();
                float top = mPaintFontMetrics.top;
                float bottom = mPaintFontMetrics.bottom;

                //文字绘制的x轴起点
                int startX = (width - textRect.width() + paddingLeft - paddingRight) / 2;

                //文字绘制的中心
                int textCenterY = textHeight + paddingTop - textHeight / 2;
                //文字绘制的基线 BaseLine
                int startY = (int) (textCenterY - (bottom - top) / 2 - top);

                Log.d(TAG, "onDraw: ------- textRect.width()= " + textRect.width() +
                        "; textRect.height()= " + textRect.height());
                Log.d(TAG, "onDraw: ------- 绘制的起点:X = " + startX + "; Y = " + startY);

                canvas.drawText(text, 0, length, startX, startY, mPaint);

            }
        } else super.onDraw(canvas);
    }
}

需要的自定义属性:是否需要view根据宽高改变textSize

  
        
  

使用:

 

这一句代码是控制的:

app:isWrapContent="true"

当然也可以在代码里面动态设置,调用方法:

public void setWrapContent(Boolean wrapContent) {
    isWrapContent = wrapContent;
    invalidate();
}

eg:

wrapContentTextView.setText("好的的一个家,哎呀我大中华");
wrapContentTextView.setWrapContent(true);

运行效果还不错:


自适应textView宽高调节textSize的view_第2张图片
image.png

你可能感兴趣的:(自适应textView宽高调节textSize的view)