android 多行文本显示的textView

package com.zhangyue.iReader.common.view;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.view.View;

import com.zhangyue.iReader.common.util.Util;

import java.util.List;

/**
 * =======================================================================================
 * 作    者:caoxinyu
 * 创建日期:2018/4/27.
 * 类的作用:多行textVIew
 * 修订历史:
 * =======================================================================================
 */
public class MultiItemTextView extends View{

    private Paint mLinePaint;//划线的paint
    private Paint mTextPaint;// 文字画笔
    private Paint.FontMetricsInt mFontMetricsInt;

    private List<String> mStrList;
    private int mHeight =0;
    private int mLineHeight;
    private int mPaddingTB;
    private int[] mBeforHeight;//之前所有的item列表的高度
    private int[] mCurItemHeight;// 当前item 的高度
    private int[] mCurItemTextHeight;// 当前文字的高度
    private int[] mCurItemLineNum;//当前item 的行号
    private Rect mTempBounds;
    private int mMaxText;// 当前一行可以放多少个文字
    private int mLineSpace;//多行的时候  两行之间的间距
    private int mRightPadding = 0;
    public MultiItemTextView(Context context) {
        super(context);
        init(context);
    }

    public MultiItemTextView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init(context);
    }

    public MultiItemTextView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context);
    }

    private void init(Context context) {
        initPaint(context);
        initDistance(context);
    }

    private void initPaint(Context context) {
        mLinePaint = new Paint();
        mTextPaint = new Paint();
        mTextPaint.setAntiAlias(true);
        mTextPaint.setTextSize(Util.dipToPixel2(getContext(),13));
        mFontMetricsInt = mTextPaint.getFontMetricsInt();
        mLinePaint.setAntiAlias(true);
        mLinePaint.setColor(Color.parseColor("#EEEEEE"));
        mTextPaint.setColor(Color.parseColor("#FF222222"));
        mLineHeight = Util.dipToPixel(getContext(), 0.67f);
    }

    private void initDistance(Context context) {
        mTempBounds = new Rect();
        mLineSpace = Util.dipToPixel(context,2);
        mPaddingTB = Util.dipToPixel(getContext(), 16);
        mRightPadding = Util.dipToPixel2(context,10);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        int startY;
        if (mStrList == null) {
            return;
        }
        for (int i = 0; i < mStrList.size(); i++) {
            if (i ==0) {
                startY = 0;
            }else {
                startY = mBeforHeight[i-1];
            }
            canvas.drawLine(0, startY,getWidth(),mLineHeight+ startY,mLinePaint);

            int textStartY = startY+ mCurItemHeight[i] / 2 + mCurItemTextHeight[i] / 2 - mFontMetricsInt.descent;
            String text = mStrList.get(i);
            if (mCurItemLineNum[i] >1) {
                for (int j = 0; j < mCurItemLineNum[i]; j++) {
                    textStartY = startY+ mPaddingTB +(mTempBounds.height())*(j+1)+j* mLineSpace - mFontMetricsInt.descent;
                    String substring = text.substring(j * mMaxText, mMaxText*(j+1) > text.length() ? text.length(): mMaxText*(j+1));
                    canvas.drawText(substring,0,textStartY,mTextPaint);
                }
            }else {
                canvas.drawText(text,0,textStartY,mTextPaint);
            }
            if (i == mStrList.size()-1){
                canvas.drawLine(0,mHeight-mLineHeight,getWidth(),mHeight,mLinePaint);
            }
        }
    }

    public void setTextSize(int textSize) {
        mTextPaint.setTextSize(Util.dipToPixel2(getContext(),  textSize));
    }

    public void setTextColor(int color) {
        mTextPaint.setColor(color);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int width = MeasureSpec.getSize(widthMeasureSpec) -mRightPadding;
        if (width ==0) {
            return;
        }

        for (int i = 0; i < mStrList.size(); i++) {
            String text = mStrList.get(i);
            mTextPaint.getTextBounds(text,0, text.length(), mTempBounds);
            float textWidth = mTextPaint.measureText(text);

            int line =1;
            if (textWidth > width) {
                float oneCharLength = textWidth / text.length();
                mMaxText = (int) (width / oneCharLength);//一行最大可以放置的文字数
                line= text.length() / mMaxText;
                if (text.length() % mMaxText !=0) {//如果不能整除 说明还剩余一行
                    line+=1;
                }
                int itemHeight = mPaddingTB * 2 + mTempBounds.height()*line +(line-1)* mLineSpace;
                mCurItemHeight[i] =itemHeight;
                mCurItemTextHeight[i] = mTempBounds.height()*line;
                mHeight += itemHeight;
                mBeforHeight[i]=mHeight;
            }else {
                int itemHeight = mPaddingTB * 2 + mTempBounds.height();
                mCurItemHeight[i] =itemHeight;
                mCurItemTextHeight[i] = mTempBounds.height();
                mHeight += itemHeight;
                mBeforHeight[i]=mHeight;
            }
            mCurItemLineNum[i] = line;
        }
        setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec),mHeight);
    }

    public void setStrList(List<String> strList) {
        if (strList == null && strList.size()==0) {
            return;
        }
        mStrList = strList;
        mBeforHeight =new int[mStrList.size()];
        mCurItemHeight =new int[mStrList.size()];
        mCurItemTextHeight =new int[mStrList.size()];
        mCurItemLineNum =new int[mStrList.size()];
        invalidate();
    }
}

直接调用setStrList 设置字符串就可以了。

原文地址:https://www.cnblogs.com/caoxinyu/p/10568547.html