【问题标题】:Get suggestion for line breaks based on text, font and available width根据文本、字体和可用宽度获取换行建议
【发布时间】:2014-03-22 21:44:16
【问题描述】:

我有一个想要手动绘制和布局的文本。 为了让它看起来不错,我想使用一种内置方法,该方法根据我的文本、可用宽度以及使用的字体和字体大小建议换行符。
iOS 有 CTTypesetter.SuggestLineBreak,这正是我所需要的。

Android 中有类似的东西吗?

【问题讨论】:

    标签: android


    【解决方案1】:

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

    编辑:

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

    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() + "]");
        }
    }
    

    测试代码:

    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);
    

    【讨论】:

    • 我不明白这将如何帮助我了解我的文本行的确切边界。这就是我需要的,因为我需要在文本中嵌入其他元素。
    • 所以使用 Spannable.setSpan 嵌入其他东西并调用 Layout.draw 在画布上绘制所有内容
    • 我可以用它在文本中嵌入按钮吗?如果是这样,你能举一个简短的例子吗?
    • 如果你的意思是按钮为 android.widget.Button,那么不,你不能这样做,但你可以使用 ClickableSpans
    • 谢谢。既然如此,我就按原计划走。
    【解决方案2】:

    看起来Paint.breakText 可以完成这项工作。

    【讨论】:

      猜你喜欢
      • 2010-10-28
      • 1970-01-01
      • 2014-02-16
      • 1970-01-01
      • 2021-09-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-09-02
      相关资源
      最近更新 更多