java - 带选择的 EditText 缩放

标签 java android editor pinchzoom spanned

我有一个 EditText 我想缩放它,并使用 setScaleX/setScaleY 滚动,它工作正常 - 正在编辑文本正确的位置。

但是当我尝试选择文本时 - 它会将选择句柄绘制到位置,例如文本未缩放时。已知bug .

这是预期的结果,因为 handle 是在与 View 大小相关的弹出窗口上绘制的。

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

选择句柄也绘制在弹出窗口 android.widget.Editor.HandleView#HandleView 布局中计算的坐标上,我只需要 DynamicLayout 但它对我们没有区别目的。

方法 android.text.Layout#getPrimaryHorizo​​ntal(int, boolean) 是公共(public)的,它的值可以按比例增加,但为此我们需要扩展和覆盖私有(private)方法 android。 widget.TextView#makeSingleLayout,但这是个问题。

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

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

enter image description here

PS:任务的上下文是一个带有捏拉缩放编辑文本的编辑器。计算大小的文本重新布局不是解决方案。因为我需要每个屏幕尺寸的可移植文档。

最佳答案

您可以使用 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 应用于给定 Spanned 的单个区域。

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

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

关于java - 带选择的 EditText 缩放,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22201331/

相关文章:

xml - 使用 Android 生成的 ant 构建文件时如何为 JAR 指定 lib 文件夹?

javascript - 设计 html 编辑器预览功能背后的理论

java - 用于编写Java程序的代码编辑器软件

java - 无返回类型的错误

java - Jetty SslConnectionFactory 下一个协议(protocol)

java - 使用基本身份验证和 ssl 调用 soap ws 时出错

java - 使用单个或优化查询进行批量插入

android - Fresco:如何设置 SimpleDraweeView failureImage tint 颜色?

android - 方向更改后 fragment saveInstanceState 变为空

php - 在 PhpStorm 中快速插入相对路径