获取建议换行基于文本,字体和可用宽度宽度、换行、文本、字体

2023-09-07 01:24:40 作者:清影

我有我想手动绘制和布局的文本。 对于这个好看,我想用一个内置的方法建议根据我的文字,可用宽度和使用的字体和字体大小换行。 iOS的有 CTTypesetter.SuggestLineBreak 这不正是我所需要的。

I have a text I want to manually draw and layout. For this to look good, I would like to use a build-in method that suggests line breaks based on my text, the available width and the used font and font size. iOS has CTTypesetter.SuggestLineBreak which does exactly what I need.

有没有在Android的类似的东西?

Is there something similar in Android?

推荐答案

你应该使用StaticLayout,你以后只需要调用的draw(Canvas)的方法

you should use StaticLayout, all you need later is to call draw(Canvas) method

编辑:

这是创建一个真正的按钮自定义跨度:

this a custom span that creates a real Button:

abstract class ButtonSpan extends ReplacementSpan implements OnClickListener {
    Button mButton;
    ViewGroup mParent;
    FrameLayout.LayoutParams mParams;

    public ButtonSpan(ViewGroup parent, String text) {
        mParent = parent;
        mButton = new Button(parent.getContext(), null, android.R.attr.buttonStyleSmall);
        mButton.setText(text);
        mButton.setOnClickListener(this);
        mParams = new FrameLayout.LayoutParams(0, 0, Gravity.NO_GRAVITY);
    }

    @Override
    public int getSize(Paint paint, CharSequence text, int start, int end, FontMetricsInt fm) {
        mButton.setTextSize(paint.getTextSize());
        mButton.measure(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
        mParams.width = mButton.getMeasuredWidth();
        mParams.height = mButton.getMeasuredHeight();
//        if (fm != null) {
//            fm.top = fm.ascent = -button.getMeasuredHeight() / 2;
//            fm.bottom = fm.descent = button.getMeasuredHeight() / 2;
//        }
        return mButton.getMeasuredWidth();
    }

    @Override
    public void draw(Canvas canvas, CharSequence text, int start, int end, float x, int top, int y, int bottom, Paint paint) {
        mParams.setMargins((int) x, top, 0, 0);
        if (mButton.getParent() == null) {
            mParent.addView(mButton, mParams);
            AnimationSet set = new AnimationSet(true);
            Animation alpha = new AlphaAnimation(0, 1);
            int duration = 750;
            alpha.setDuration(duration);
            set.addAnimation(alpha);
            Animation scale = new ScaleAnimation(0, 1, 0, 1, mParams.width / 2, mParams.height / 2);
            scale.setDuration(duration);
            set.addAnimation(scale);
            mButton.startAnimation(set);
        }
    }
}

class MyButtonSpan extends ButtonSpan {
    public MyButtonSpan(ViewGroup parent, String text) {
        super(parent, text);
    }

    @Override
    public void onClick(View v) {
        Log.d(TAG, "onClick [" + ((Button) v).getText() + "]");
    }
}

测试code:

testing code:

ScrollView sv = new ScrollView(this);
setContentView(sv);

FrameLayout layout = new FrameLayout(this);
SpannableStringBuilder ssb = new SpannableStringBuilder();
ssb.append("Lorem ipsum dolor sit amet, consectetur adipiscing elit. "
    + "Proin ac nisl nisl. Nullam [feugiat] sapien non libero semper suscipit. "
    + "Nulla nec convallis velit, vel [tincidunt] augue. \n\n"
    + "Integer urna sapien, [faucibus] a ipsum nec, blandit euismod lectus. "
    + "Cras eget tincidunt eros. Cras commodo [tempus] lorem, eu fringilla diam ultricies vel. "
    + "Donec massa ante, [consequat] sit amet orci non, rutrum interdum dolor. \n\n"
    + "Nullam gravida enim sit amet sapien bibendum, sed gravida nisl varius. "
    + "Sed hendrerit metus nec purus tempor faucibus. [Quisque] hendrerit vehicula urna sed interdum. "
    + "Proin imperdiet urna ac quam [euismod], vitae posuere metus pharetra. "
    + "Donec euismod lorem vel malesuada mollis. ");
int cnt = ssb.length();
int start = 0;
for (int i = 0; i < cnt; i++) {
    char c = ssb.charAt(i);
    if (c == '[') {
        start = i;
    } else
    if (c == ']') {
        int end = i + 1;
        Object span = new MyButtonSpan(layout, ssb.subSequence(start + 1, end - 1).toString());
        ssb.setSpan(span, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
    }
}
TextView textView = new TextView(this);
textView.setTextSize(23);
textView.setTextColor(0xffeeeeee);
textView.setText(ssb);
layout.addView(textView);
sv.addView(layout);