Подтвердить что ты не робот

Шкала EditText с выбором

У меня есть EditText Я хочу увеличить его и прокручивать с помощью setScaleX/setScaleY, и он отлично работает - текст редактируется в правильной позиции.

Но когда я пытаюсь выбрать текст - он рисует дескрипторы выделения в позиции, например, когда текст не масштабируется. Известно ошибка.

Ожидаемый результат, потому что ручки рисуются во всплывающем окне, связанном с размером представления.

Все действия на android.widget.Editor нацелены на его поле private TextView mTextView;. И если мы будем настраивать собственный редактор отражением, я не знаю, что делать с частными методами, которые не являются допустимыми.

Также отображаются образы выделения в окне всплывающих окон android.widget.Editor.HandleView#HandleView, рассчитанные в макете, и мне нужно только DynamicLayout, но это не имеет никакого значения для наших целей.

Метод android.text.Layout#getPrimaryHorizontal(int, boolean) является общедоступным, и его значение можно умножить на масштаб, но для этого нам нужно расширить и переопределить частный метод android.widget.TextView#makeSingleLayout, но это проблема.

Также мы могли бы реализовать наш собственный макет со всеми необходимыми методами переопределения, но все методы, которые мы можем переопределить, отмечены аннотацией @hide и нет полей, к которым можно получить доступ с отражением.

Следующий снимок экрана для масштабирования на 2x

enter image description here

PS: контекст задачи - это редактор с текстом редактирования с фиксированным увеличением. Ретрансляция текста с вычислением размера не является решением. Потому что мне нужен Portable Document для каждого размера экрана.

4b9b3361

Ответ 1

Вы можете сделать это, используя 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. Храните обнаруженную шкалу в качестве переменной-члена.

Отмените onDraw и вызовите canvas.scale() с вашим значением шкалы перед вызовом super.onDraw. Как вы можете заметить в AbsoluteSizeSpan, использование AbsoluteSizeSpan (Parcel src) получит текст, который вы хотите изменить, затем примените updateDrawState.

Ответ 2

Вы пытались применить к этим элементам разные стили? Я думаю, что он должен работать с некоторой обусловленностью.

<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>