自定义控件 - StaticLayout文本换行

发布时间:2023年12月26日

最近在修改 WheelView 自定义控件,因为原始效果单行效果,现在需要支持换行效果,故接触到了 StaticLayout ,先行记录

在 Android 自定义控件中,当我们调用 drawText 绘制 Text 时,假设 Text 为超长字符串(文本宽度超过屏幕宽度)也只会显示一行,超出部分会隐藏在屏幕之外~

而 Google 为了适配多行 Text 显示效果,就提供了 StaticLayout 工具类用于处理文字换行的问题

StaticLayout 基础

很多人可能会想到TextView为何支持换行?嗯… 有没有可能TextView内部也使用了 StaticLayout?

还不够完善,完善过后,会补入效果图,同时将近期修改的WheelView也记录一波

StaticLayout 相关构造参数

在这里插入图片描述

具体函数

在这里插入图片描述

StaticLayout 参数解释

    @Deprecated
    public StaticLayout(CharSequence source, int bufstart, int bufend, TextPaint paint, int outerwidth, Layout.Alignment align, float spacingmult, float spacingadd, boolean includepad, TextUtils.TruncateAt ellipsize, int ellipsizedWidth) {
        super((CharSequence)null, (TextPaint)null, 0, (Layout.Alignment)null, 0.0F, 0.0F);
        throw new RuntimeException("Stub!");
    }
  • CharSequence source: 需要分行的字符串
  • int bufstart: 需要分行的字符串从第几的位置开始
  • int bufend :需要分行的字符串到哪里结束
  • TextPaint paint: 画笔对象
  • int outerwidth: layout的宽度,超出时换行
  • Alignment align layout的对其方式:ALIGN_CENTER, ALIGN_NORMAL, ALIGN_OPPOSITE 三种

位于 Layout

在这里插入图片描述

  • float spacingmult: 相对行间距,相对字体大小,1.5f表示行间距为1.5倍的字体高度。
  • float spacingadd: 在基础行距上添加多少
  • boolean includepad,
  • TextUtils.TruncateAt ellipsize: 从什么位置开始省略
  • int ellipsizedWidth: 超过多少开始省略

单行绘制

在这里插入图片描述

package com.example.staticlayoutdemo;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.text.StaticLayout;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;

import androidx.annotation.Nullable;

public class AloneLineTextView extends View {
    private Paint paint;
    private String contentText;
    private int measureWidth;

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

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

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

    private void init() {
        paint = new Paint();
        paint.setAntiAlias(true);
        paint.setColor(Color.RED);
        paint.setStrokeWidth(10f);
        paint.setTextSize(38f);
        paint.setStyle(Paint.Style.FILL);
    }

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

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        if (contentText == null || contentText.isEmpty()) {
            contentText = "AloneLineTextView 首次绘制";
        }
        //测量文本宽度
        Rect rect = new Rect();
        paint.getTextBounds(contentText, 0, contentText.length(), rect);
        int contentSize = rect.width();
        Log.e("tag", "屏幕宽度:" + measureWidth);
        Log.e("tag", "文本宽度:" + contentSize);

        canvas.drawText(contentText, 50, 200, paint);
    }

    void setContextText(String content) {
        contentText = content;
        postInvalidate();
    }
}


多行绘制

package com.example.staticlayoutdemo;

import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.text.Layout;
import android.text.StaticLayout;
import android.text.TextPaint;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;

import androidx.annotation.Nullable;

public class MoreLinesTextView extends View {
    private TextPaint textPaint;
    private String contentText;
    private int measureWidth;

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

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

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

    private void init() {
        textPaint = new TextPaint();
        textPaint.setAntiAlias(true);
        textPaint.setColor(Color.RED);
        textPaint.setStrokeWidth(10f);
        textPaint.setTextSize(38f);
        textPaint.setStyle(Paint.Style.FILL);
    }

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

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        if (contentText == null ||contentText.isEmpty()) {
            contentText = "MoreLinesTextView 首次绘制";
        }
        //测量文本宽度
        Rect rect = new Rect();
        textPaint.getTextBounds(contentText, 0, contentText.length(), rect);
        int contentSize = rect.width();
        Log.e("tag", "屏幕宽度:" + measureWidth);
        Log.e("tag", "文本宽度:" + contentSize);

//        canvas.save();
//        canvas.translate(0, 50);
        @SuppressLint("DrawAllocation") StaticLayout staticLayout = new StaticLayout(contentText, textPaint, getWidth(), Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
        staticLayout.draw(canvas);
//        canvas.restore();
    }

    void setContextText(String content) {
        contentText = content;
        postInvalidate();
    }
}
文章来源:https://blog.csdn.net/qq_20451879/article/details/135147159
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。