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 widt
It looks like Paint.breakText will do the job.
you should use StaticLayout, all you need later is to call draw(Canvas) method
EDIT:
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() + "]");
}
}
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);