大规模的EditText与选择 [英] EditText scale with selection

查看:352
本文介绍了大规模的EditText与选择的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have an EditText I want to zoom it, and scroll with setScaleX/setScaleY and it works fine - text is being edited in the right position.

但是,当我尝试选择文本 - 它绘制选择手柄像文本时不缩放位置。据了解错误

But when I try to select text - it draws selection handles to positions like when text is not scaled. It is known bug.

据预计的结果,因为手柄上绘制弹出窗口与视图的大小。

It's expected result because handles are drawn on popup window related to view size.

android.widget.Editor 所有的行动是针对该领域私人TextView的mTextView; 。如果我们将设置自己的编辑器反射,我不知道该怎么做私有方法,那没有重写。

All actions on android.widget.Editor are targeted to its field private TextView mTextView;. And if we will set own editor by reflection, I don't know what to do with private methods, that are no overridable.

另外选择手柄上绘制弹出窗口 android.widget.Editor.HandleView#HandleView 坐标计算的布局,我只需要 DynamicLayout ,但对我们来说没有什么区别。

Also selection handles are drawn on Popup window android.widget.Editor.HandleView#HandleView coordinates calculated in Layout and I need only DynamicLayout but it have no difference for our purposes.

方法 android.text.Layout#getPrimaryHorizo​​ntal(INT,布尔)是公共的,它的价值可以在规模成倍增加,但我们需要扩大并覆盖专用方法 android.widget.TextView#makeSingleLayout ,但是这是一个问题。

Method android.text.Layout#getPrimaryHorizontal(int, boolean) is public and its value can be multiplied on scale, but for that we need to extend and override private method android.widget.TextView#makeSingleLayout, but this is a problem.

同时,我们也能与所有需要重写的方法实现自己的布局,但我们可以覆盖所有的方法都标有 @hide 注释,并且没有字段可以有反射访问。

Also we could implement our own Layout with all required overriden methods, but all methods that we can override are marked with @hide annotation and there are no fields that can be accessed with a reflection.

下面的截图显示了规模上的2个

Next screenshot appears for scaled on 2x

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

PS: context of the task is an Editor with pinch-to-zoom edit text. Relayout of text with calculation of size is not a solution. Because I need Portable Document on each screen size.

推荐答案

您可以做到这一点使用<一个href="https://github.com/android/platform_frameworks_base/blob/master/core/java/android/text/style/MetricAffectingSpan.java">MetricAffectingSpan.这里是一个类举例吧:

You can do that using MetricAffectingSpan. Here is a class exemplifying it:

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);
        }
    }
}

参考:<一href="http://alvinalexander.com/java/jwarehouse/android/core/java/android/text/style/AbsoluteSizeSpan.java.shtml">Java来源$ C ​​$ C仓库项目

您需要玩<一个href="http://developer.android.com/reference/android/text/style/MetricAffectingSpan.html">MetricAffectingSpan和<一href="http://developer.android.com/reference/android/text/style/CharacterStyle.html">wrap(CharacterStyle CS)的 - 它允许的 CharacterStyle 的应用于给定跨区的单个区域

You need to play with MetricAffectingSpan and wrap(CharacterStyle cs) - which allows CharacterStyle to be applied to a single region of a given Spanned.

在你的子类,覆盖的 onTouch 的,并通过自己的价值观到的 ScaleGestureDetector 的。存储所检测到的规模为成员变量。

In your subclass, override onTouch and pass its values to a ScaleGestureDetector. Store the detected scale as a member variable.

覆盖的的OnDraw 的,并调用<一href="http://stackoverflow.com/questions/21546762/how-to-pinch-zoom-an-edittext-in-android">canvas.scale()与你的刻度值,通过打电话来的 super.onDraw 的之前。正如你可以注意到的 AbsoluteSizeSpan 的,使用的 AbsoluteSizeSpan(包裹SRC)的会得到你想要调整文本,那么你申请的 updateDrawState

Override onDraw, and call canvas.scale() with your scale value prior to calling through to super.onDraw. As you can notice in the AbsoluteSizeSpan, using AbsoluteSizeSpan(Parcel src) will get the text you wish to resize, then you apply updateDrawState.

这篇关于大规模的EditText与选择的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆