gpt4 book ai didi

android - 处理非英文 Unicode(如中文、日文)时,目标 API 28 中不正确的 EditText 行间距行为

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:09:12 27 4
gpt4 key购买 nike

我们注意到,在 targetSdkVersion 28 期间,EditText 将在输入非英语 unicode(如中文、日语等)后倾向于“稍微下推”该行.

当代码为 targetSdkVersion 27 或以下时,不会发生这种行为。


使用targetSdkVersion 27,在模拟器API 28上运行

(输入非英文unicode前)

enter image description here

(输入非英文unicode后)

enter image description here

(确认间距OK)

enter image description here


使用targetSdkVersion 28,在模拟器API 28上运行

(输入非英文unicode前)

enter image description here

(输入非英文unicode后)

enter image description here

(确认间距有问题。输入后的行被下推)

enter image description here


这是我们使用的 XML 和代码。我们继承自androidx.appcompat.widget.AppCompatEditText,画线,让问题更明显。

<com.yocto.wenote.note.LinedEditText
android:id="@+id/body_edit_text"
android:gravity="top"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:layout_marginBottom="12dp"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/transparent"
android:scrollbars="vertical"
android:textSize="18sp"
android:singleLine="false"
android:lineSpacingMultiplier="1.4"
android:inputType="textMultiLine|textCapSentences"
android:textCursorDrawable="?attr/shorterCursor" />

LinedEditText.java

package com.yocto.wenote.note;

import android.content.Context;
import android.content.res.Resources;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.util.TypedValue;

import com.yocto.wenote.R;

/**
* Created by yccheok on 24/3/2018.
*/

public class LinedEditText extends androidx.appcompat.widget.AppCompatEditText {
private final Paint mPaint = new Paint();
private int noteLineColor;
private static final float DEFAULT_LINE_SPACING_EXTRA = 0.0f;
private static final float DEFAULT_LINE_SPACING_MULTIPLIER = 1.4f;

private void initResource() {
Context context = getContext();
TypedValue typedValue = new TypedValue();
Resources.Theme theme = context.getTheme();
theme.resolveAttribute(R.attr.noteLineColor, typedValue, true);
noteLineColor = typedValue.data;
}

public LinedEditText(Context context) {
super(context);
initResource();
initPaint();
}

public void setNoteLineColor(int noteLineColor) {
this.noteLineColor = noteLineColor;
}

public LinedEditText(Context context, AttributeSet attrs) {
super(context, attrs);
initResource();
initPaint();
}

public LinedEditText(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initResource();
initPaint();
}

private void initPaint() {
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setColor(noteLineColor);
mPaint.setStrokeWidth(1);
}

@Override
protected void onDraw(Canvas canvas) {
int left = getLeft();
int right = getRight();
int paddingTop = getPaddingTop();
int paddingBottom = getPaddingBottom();
int paddingLeft = getPaddingLeft();
int paddingRight = getPaddingRight();
final int heightWithScrollY = getHeight() + getScrollY();
int lineHeight = getLineHeight();
int count = (heightWithScrollY-paddingTop-paddingBottom) / lineHeight;

mPaint.setColor(noteLineColor);
mPaint.setTypeface(this.getTypeface());

final float originalLineHeight;
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN) {
originalLineHeight = lineHeight / getLineSpacingMultiplier();
} else {
originalLineHeight = lineHeight / DEFAULT_LINE_SPACING_MULTIPLIER;
}

for (int i = 0; i < count; i++) {
float baseline = lineHeight * (i + 1) + paddingTop - mPaint.descent() - (lineHeight - originalLineHeight);
canvas.drawLine(
left + paddingLeft,
baseline,
right - paddingRight,
baseline,
mPaint
);
}

super.onDraw(canvas);
}

// https://stackoverflow.com/questions/49467579/workaround-for-edittext-ignoring-linespacingmultiplier
@Override
protected void onTextChanged(CharSequence text, int start, int lengthBefore, int lengthAfter) {
super.onTextChanged(text, start, lengthBefore, lengthAfter);

if (lengthBefore != lengthAfter) {
float add;
float mul;

if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN) {
add = getLineSpacingExtra();
mul = getLineSpacingMultiplier();
} else {
add = DEFAULT_LINE_SPACING_EXTRA;
mul = DEFAULT_LINE_SPACING_MULTIPLIER;
}

setLineSpacing(0f, 1f);
setLineSpacing(add, mul);
}
}

}

请注意,如果您使用targetSdkVersion 28,但在模拟器API 27上运行,也不会出现此问题。

有什么解决方法的建议吗?

p/s 我在 https://issuetracker.google.com/issues/131284662 提交了一个问题

最佳答案

好吧,我设法通过以下方式做到了。我的 onDraw 函数:

@Override
protected void onDraw(Canvas canvas) {
int left = getLeft();
int right = getRight();
int paddingTop = getPaddingTop();
int paddingBottom = getPaddingBottom();
int paddingLeft = getPaddingLeft();
int paddingRight = getPaddingRight();
final int heightWithScrollY = getHeight() + getScrollY();
Log.d("Height Of View: ",String.valueOf(heightWithScrollY));
int lineHeight = getLineHeight();
Log.d("LineHeight: ",String.valueOf(lineHeight));
int count = (heightWithScrollY-paddingTop-paddingBottom) / lineHeight;
Log.d("Count: ",String.valueOf(count));
mPaint.setColor(noteLineColor);
mPaint.setTypeface(this.getTypeface());
Log.d("Descent: ",String.valueOf(mPaint.descent()));

for(int i=lineHeight;i<=count*lineHeight;i+=lineHeight)
{
float baseline = i + paddingTop + mPaint.descent();
canvas.drawLine(left+paddingLeft,baseline,right-paddingRight,baseline,mPaint);
Log.d("XYXY:",String.valueOf(left+paddingLeft)+" "+String.valueOf(baseline)+" "+String.valueOf(right-paddingRight));
}
super.onDraw(canvas);
}

我用 View 作为

 <com.yocto.wenote.note.LinedEditText
android:id="@+id/body_edit_text"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:gravity="top"
android:layout_marginBottom="12dp"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="vertical"
android:textSize="18sp"
android:singleLine="false"
android:lineSpacingMultiplier="1.4"
android:inputType="textMultiLine|textCapSentences"/>

最后但并非最不重要的是,我在我的 build.gradle 依赖项中使用了这个实现(我个人认为使用这个 alpha05 版本帮助它解决了这个问题,但我还没有检查过)

dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'androidx.appcompat:appcompat:1.1.0-alpha05'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test:runner:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1'
}

关于android - 处理非英文 Unicode(如中文、日文)时,目标 API 28 中不正确的 EditText 行间距行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55845977/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com