安卓API28以上自定义EditText的行间距不相等
由于之前用的一个便签应用在我换新手机后不兼容了,目前也没发现类似的便签应用,就花了半个月时间研究了下安卓程序开发,真实一把辛酸一把泪,坑的我这个javaer当场死亡。我特么绝壁再也不碰这辣鸡玩意了。
References:
- https://stackoverflow.com/questions/55845977/incorrect-edittext-line-spacing-behavior-in-target-api-28-when-dealing-with-non/56212644
- https://issuetracker.google.com/issues/131284662
- https://developer.android.com/reference/android/widget/TextView#attr_android:fallbackLineSpacing
给EditText添加下划线这个功能太常见了,基本上有多行文本编辑的地方都能看到,大多数实现方式就是自定义一个EditText重写onDraw方法自己画线,这里也不例外,然而在我给EditText加下划线的时候发生了这样的事:
换了多行之后不但线画的不准,偏移了,在一行内输入中英文时甚至会改变行高,我特么直接吐了,这让人还怎么划线。这里不管怎么计算ascent、decent、leading、fontMetrics这些乱七八糟的都没用。然后查了很久才找到问题所在,还得多亏了StackOverflow上的这位兄台,Google官方居然还大言不惭说这是Feature,不是Bug,我特么直接一脱鞋扔过去。你家的Google Keep都有这个问题。
不过你不想修就不想修吧,好在给出了解决方案,就是将android:fallbackLineSpacing
属性设置为false
。可以在代码中设置,也可以在XML中设置,都一样。
以下为自定义EditText部分的代码:
public class LinedEditText extends AppCompatEditText {
private Paint paint = new Paint();
// 文本行高
private int lineHeight;
private final float startX = 0.0f;
public LinedEditText(Context context, AttributeSet attrs) {
super(context, attrs);
paint.setStyle(Paint.Style.STROKE);
paint.setColor(Color.rgb(208, 208, 218));
paint.setTextSize(getTextSize());
lineHeight = getLineHeight();
setGravity(Gravity.TOP); // 使文本框的显示方式为从上到下
// 这是个巨坑: https://issuetracker.google.com/issues/131284662
setFallbackLineSpacing(false);
}
@Override
public void onDraw(Canvas canvas) {
// 下划线绘制在文字底部,需要设置 lineSpacingExtra 的行间距,才能有空余区域显示出来。
final float lineSpacingExtra = getLineSpacingExtra() / 2 + 1;
final float stopX = getWidth();
// 超过一屏能显示的文本内容没有有下划线
int actualLineCount = getLineCount();
int screenCount = (int) Math.ceil(getHeight() / lineHeight);
int linesToDraw = Math.max(actualLineCount, screenCount) + 1;
for (int i = 0; i < linesToDraw; i++) {
float baseline = lineHeight * i - lineSpacingExtra;
canvas.drawLine(startX, baseline, stopX, baseline, paint);
}
super.onDraw(canvas); // 画出光标才能编辑文本
}
}
对应的XML为:
<com.racecoder.simplememo.view.LinedEditText
android:id="@+id/add_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@+id/add_timebar"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:background="@null"
android:hint="@string/write_content_hint"
android:textColorHint="@color/edit_hint_text"
android:inputType="none|text|textMultiLine|textNoSuggestions"
android:lineSpacingExtra="18dp"
android:scrollbars="vertical"
android:textColor="@color/edit_text"
android:textSize="@dimen/Edit_Content_TextSize">
<requestFocus />
</com.racecoder.simplememo.view.LinedEditText>
最终修复后效果:
仅有一条评论