有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java EditText可选择缩放

我有一个EditText我想把它放大,用setScaleX/setScaleY滚动,效果很好-文本正在正确的位置编辑

但当我尝试选择文本时,它会将选择手柄绘制到文本未缩放时的位置。它被称为bug

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

安卓.widget.Editor的所有操作都针对其字段private TextView mTextView;。如果我们将通过反射设置自己的编辑器,我不知道如何处理私有方法,这些方法是不可重写的

此外,选择手柄绘制在弹出窗口安卓.widget.Editor.HandleView#HandleView坐标上,在布局中计算,我只需要DynamicLayout,但这与我们的目的没有区别

方法安卓.text.Layout#getPrimaryHorizontal(int, boolean)是公共的,它的值可以按比例乘以,但为此我们需要扩展和重写私有方法安卓.widget.TextView#makeSingleLayout,但这是一个问题

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

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

enter image description here

PS:任务的上下文是一个编辑器,可以通过收缩来缩放编辑文本。通过计算大小来重新显示文本不是一个解决方案。因为我需要每个屏幕大小的便携文件


共 (2) 个答案

  1. # 1 楼答案

    您是否尝试对这些元素应用不同的样式?我认为它应该配合一些条件作用

    <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>
    
  2. # 2 楼答案

    你可以用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 Source Code Warehouse project

    您需要使用MetricAffectingSpanwrap(CharacterStyle cs),这允许CharacterStyle应用于给定范围的单个区域

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

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