EditText按比例缩放

我有一个EditText我想要放大,并与setScaleX / setScaleY滚动,它工作正常 – 文本正在编辑在正确的位置。

但是,当我尝试select文本 – 它将绘制select手柄的位置,如文本不缩放。 这是已知的错误 。

这是预期的结果,因为句柄是在与视图大小相关的popup窗口上绘制的。

android.widget.Editor上的所有操作都是针对其字段private TextView mTextView; 。 如果我们通过反思来设置自己的编辑器,我不知道如何处理私有方法,这是不可覆盖的。

另外,在popup窗口android.widget.Editor.HandleView#HandleView坐标上绘制的select手柄是在Layout中计算出来的,我只需要DynamicLayout但是对于我们的目的来说它没有区别。

方法android.text.Layout#getPrimaryHorizontal(int, boolean)是公开的,它的值可以在规模上相乘,但是为此我们需要扩展和重载私有方法android.widget.TextView#makeSingleLayout ,但这是一个问题。

我们也可以使用所有需要的重写方法来实现我们自己的布局,但是我们可以重写的所有方法都用@hide注解标记,并且没有可以通过reflection访问的字段。

下一个屏幕截图显示为2倍缩放

在这里输入图像说明

PS:任务的上下文是一个捏合缩放编辑文本的编辑器。 重新计算大小的文本不是一个解决scheme。 因为我需要每个屏幕尺寸的便携式文档。

Solutions Collecting From Web of "EditText按比例缩放"

您可以使用MetricAffectingSpan来做到这一点 。 这是一个例证它的类:

 package android.text.style; import android.os.Parcel; import android.text.ParcelableSpan; import android.text.TextPaint; import android.text.TextUtils; public class AbsoluteSizeSpan extends MetricAffectingSpan implements ParcelableSpan { private final int mSize; private boolean mDip; /** * Set the text size to <code>size physical pixels. */ public AbsoluteSizeSpan(int size) { mSize = size; } /** * Set the text size to <code>size physical pixels, * or to <code>size device-independent pixels if * <code>dip is true. */ public AbsoluteSizeSpan(int size, boolean dip) { mSize = size; mDip = dip; } public AbsoluteSizeSpan(Parcel src) { mSize = src.readInt(); mDip = src.readInt() != 0; } public int getSpanTypeId() { return TextUtils.ABSOLUTE_SIZE_SPAN; } public int describeContents() { return 0; } public void writeToParcel(Parcel dest, int flags) { dest.writeInt(mSize); dest.writeInt(mDip ? 1 : 0); } public int getSize() { return mSize; } public boolean getDip() { return mDip; } @Override public void updateDrawState(TextPaint ds) { if (mDip) { ds.setTextSize(mSize * ds.density); } else { ds.setTextSize(mSize); } } @Override public void updateMeasureState(TextPaint ds) { if (mDip) { ds.setTextSize(mSize * ds.density); } else { ds.setTextSize(mSize); } } } 

参考: Java源代码仓库项目

您需要使用MetricAffectingSpan和wrap(CharacterStyle cs) – 它允许CharacterStyle应用于给定Spanned的单个区域。

在您的子类中,重写onTouch并将其值传递给ScaleGestureDetector 。 将检测到的比例存储为成员variables。

覆盖onDraw ,并在调用super.onDraw之前,用scale值调用canvas.scale() 。 正如你可以注意到在AbsoluteSizeSpan中 ,使用AbsoluteSizeSpan(Parcel src)将得到你想要调整的文本,然后你应用updateDrawState

你有没有尝试对这些元素应用不同的风格? 我认为它应该与一些条件。

 <item name="android:textSelectHandle">@drawable/text_select_handle_middle</item> <item name="android:textSelectHandleLeft">@drawable/text_select_handle_left</item> <item name="android:textSelectHandleRight">@drawable/text_select_handle_right</item>