TextView 自动换行,每行排满的自定义TextView,附答案+考点

本文介绍了一个自定义的MTextView,适用于移动开发中的Android平台。该TextView能够实现图文混排,并确保每行文字都能排满,提供了一个解决自动换行问题的方法。代码中使用了缓存测量数据、TextPaint和ArrayList等技术来处理文本内容和测量字符宽度。
摘要由CSDN通过智能技术生成
  • @date 2019-08-06.
  • module:图文混排TextView,请使用{@link #setMText(CharSequence)}
  • description:
    */

public class MTextView extends android.support.v7.widget.AppCompatTextView {
/**
* 缓存测量过的数据
/
private static HashMap<String, SoftReference> measuredData =
new HashMap<String, SoftReference>();
private static int hashIndex = 0;
/
*
* 存储当前文本内容,每个item为一行
/
ArrayList contentList = new ArrayList ();
private Context context;
/
*
* 用于测量字符宽度
/
private TextPaint paint = new TextPaint();
/
*
* 用于测量span高度
/
private Paint.FontMetricsInt mSpanFmInt = new Paint.FontMetricsInt();
/
*
* 临时使用,以免在onDraw中反复生产新对象
*/
private FontMetrics mFontMetrics = new FontMetrics();

// private float lineSpacingMult = 0.5f;
private int textColor = Color.BLACK;
// 行距
private float lineSpacing;
private int lineSpacingDP = 5;
/**
 * 段间距,-1为默认
 */
private int paragraphSpacing = -1;
/**
 * 最大宽度
 */
private int maxWidth;
/**
 * 只有一行时的宽度
 */
private int oneLineWidth = -1;
/**
 * 已绘的行中最宽的一行的宽度
 */
private float lineWidthMax = -1;
/**
 * 存储当前文本内容,每个item为一个字符或者一个SpanObject
 */
private ArrayList<Object> obList = new ArrayList<Object>();
/**
 * 是否使用默认{@link #onMeasure(int, int)}和
 * {@link #onDraw(android.graphics.Canvas)}
 */
private boolean useDefault = false;
protected CharSequence text = "";

private int minHeight;
/**
 * 用以获取屏幕高宽
 */
private DisplayMetrics displayMetrics;
/**
 * {@link android.text.style.BackgroundColorSpan}用
 */
private Paint textBgColorPaint = new Paint();
/**
 * {@link android.text.style.BackgroundColorSpan}用
 */
private Rect textBgColorRect = new Rect();

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

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

public MTextView(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
    init(context);
}

public void init(Context context) {
    this.context = context;
    paint.setAntiAlias(true);
    lineSpacing = dip2px(context, lineSpacingDP);
    minHeight = dip2px(context, 30);

    displayMetrics = new DisplayMetrics();
}

public static int px2sp(Context context, float pxValue) {
    final float fontScale = context.getResources().getDisplayMetrics().scaledDensity;
    return (int) (pxValue / fontScale + 0.5f);
}

/**
 * 根据手机的分辨率从 dp 的单位 转成为 px(像素)
 */
public static int dip2px(Context context, float dpValue) {
    final float scale = context.getResources().getDisplayMetrics().density;
    return (int) (dpValue * scale + 0.5f);
}

@Override
public void setMaxWidth(int maxpixels) {
    super.setMaxWidth(maxpixels);
    maxWidth = maxpixels;
}

@Override
public void setMinHeight(int minHeight) {
    super.setMinHeight(minHeight);
    this.minHeight = minHeight;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值