我需要在特定框内的画布上绘制文本。我已经在使用DynamicLayout来自动计算和折断线条以适应盒子宽度。现在我需要自动椭圆化文本以适应盒子高度。
我怎样才能做到这一点?它不一定需要高度(像素),它可以是最大行数。
示例:
“这是一个适合框内的示例文本”
实际结果:
------------
|This is a |
|text to |
|fit inside|
------------
the box
预期结果:
------------
|This is a |
|text to |
|fit in... |
------------
我像这样创建DynamicLayout:
textLayout = new DynamicLayout(mText, mTextPaint, 100, Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
然后我画这样:
canvas.save();
canvas.translate(500, 500 - textLayout.getHeight() / 2);
textLayout.draw(canvas);
canvas.restore();
答案 0 :(得分:3)
我知道框内的行数(mMaxLines
),我扩展了DynamicLayout并且我覆盖了一些方法:
@Override
public int getLineCount() {
if (super.getLineCount() - 1 > mMaxLines) {
return mMaxLines;
}
return super.getLineCount() - 1;
}
@Override
public int getEllipsisCount(int line) {
if (line == mMaxLines - 1 && super.getLineCount() - 2 > line) {
return 1;
}
return 0;
}
@Override
public int getEllipsisStart(int line) {
if (line == mMaxLines - 1 && super.getLineCount() - 2 > line) {
return getLineEnd(line) - getLineStart(line) - 1;
}
return 0;
}
然后我得到以下结果:
------------
|This is a |
|text to |
|fit in... |
------------
答案 1 :(得分:0)
请在DynamicLayout中添加参数。 DynamicLayout(CharSequence base,CharSequence显示,TextPaint paint,int width,Layout.Alignment align,float spacingmult,float spacingadd,boolean includepad,TextUtils.TruncateAt ellipsize,int ellipsizedWidth);
答案 2 :(得分:0)
对于未来的读者,请尝试使用此StaticLayoutWithMaxLines backport:
import android.os.Build;
import android.text.Layout.Alignment;
import android.text.StaticLayout;
import android.text.TextDirectionHeuristic;
import android.text.TextDirectionHeuristics;
import android.text.TextPaint;
import android.text.TextUtils.TruncateAt;
import android.util.Log;
import java.lang.reflect.Constructor;
public class StaticLayoutWithMaxLines {
private static final String LOGTAG = StaticLayoutWithMaxLines.class.getSimpleName();
private static final String TEXT_DIR_CLASS = "android.text.TextDirectionHeuristic";
private static final String TEXT_DIRS_CLASS = "android.text.TextDirectionHeuristics";
private static final String TEXT_DIR_FIRSTSTRONG_LTR = "FIRSTSTRONG_LTR";
private static boolean sInitialized;
private static Constructor<StaticLayout> sConstructor;
private static Object[] sConstructorArgs;
private static Object sTextDirection;
public static synchronized void ensureInitialized() {
if (sInitialized) {
return;
}
try {
final Class<?> textDirClass;
if (Build.VERSION.SDK_INT >= 18) {
textDirClass = TextDirectionHeuristic.class;
sTextDirection = TextDirectionHeuristics.FIRSTSTRONG_LTR;
} else {
final ClassLoader loader = StaticLayoutWithMaxLines.class.getClassLoader();
textDirClass = loader.loadClass(TEXT_DIR_CLASS);
final Class<?> textDirsClass = loader.loadClass(TEXT_DIRS_CLASS);
sTextDirection = textDirsClass.getField(TEXT_DIR_FIRSTSTRONG_LTR)
.get(textDirsClass);
}
final Class<?>[] signature = new Class[] {
CharSequence.class,
int.class,
int.class,
TextPaint.class,
int.class,
Alignment.class,
textDirClass,
float.class,
float.class,
boolean.class,
TruncateAt.class,
int.class,
int.class
};
// Make the StaticLayout constructor with max lines public
sConstructor = StaticLayout.class.getDeclaredConstructor(signature);
sConstructor.setAccessible(true);
sConstructorArgs = new Object[signature.length];
} catch (NoSuchMethodException e) {
Log.e(LOGTAG, "StaticLayout constructor with max lines not found.", e);
} catch (ClassNotFoundException e) {
Log.e(LOGTAG, "TextDirectionHeuristic class not found.", e);
} catch (NoSuchFieldException e) {
Log.e(LOGTAG, "TextDirectionHeuristics.FIRSTSTRONG_LTR not found.", e);
} catch (IllegalAccessException e) {
Log.e(LOGTAG, "TextDirectionHeuristics.FIRSTSTRONG_LTR not accessible.", e);
} finally {
sInitialized = true;
}
}
public static boolean isSupported() {
if (Build.VERSION.SDK_INT < 14) {
return false;
}
ensureInitialized();
return (sConstructor != null);
}
public static synchronized StaticLayout create(CharSequence source, int bufstart, int bufend,
TextPaint paint, int outerWidth, Alignment align,
float spacingMult, float spacingAdd,
boolean includePad, TruncateAt ellipsize,
int ellipsisWidth, int maxLines) {
ensureInitialized();
try {
sConstructorArgs[0] = source;
sConstructorArgs[1] = bufstart;
sConstructorArgs[2] = bufend;
sConstructorArgs[3] = paint;
sConstructorArgs[4] = outerWidth;
sConstructorArgs[5] = align;
sConstructorArgs[6] = sTextDirection;
sConstructorArgs[7] = spacingMult;
sConstructorArgs[8] = spacingAdd;
sConstructorArgs[9] = includePad;
sConstructorArgs[10] = ellipsize;
sConstructorArgs[11] = ellipsisWidth;
sConstructorArgs[12] = maxLines;
return sConstructor.newInstance(sConstructorArgs);
} catch (Exception e) {
throw new IllegalStateException("Error creating StaticLayout with max lines: " + e);
}
}
}
来自here. 的代码段
并像这样使用它:
canvas.save();
CharSequence text = YOUR TEXT HERE;
StaticLayout textLayout = StaticLayoutWithMaxLines.create(text, 0, text.length(),
mPaintText, canvas.getWidth(), Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false,
TextUtils.TruncateAt.END, canvas.getWidth(), 4);
canvas.translate(mViewCenterX, y + mItemHeight / 2 - textLayout.getHeight() / 2);
textLayout.draw(canvas);
canvas.restore();
答案 3 :(得分:-1)