studio reales proyectos programacion libro introducción incluye herramientas fundamentos fuente español código con avanzado aplicaciones java android editor pinchzoom spanned

java - reales - Escala EditText con selección



libro de android studio en español pdf (2)

Tengo un texto de EditText . Quiero ampliarlo y desplazarme con setScaleX / setScaleY y funciona setScaleY : el texto se está editando en la posición correcta.

Pero cuando intento seleccionar texto, dibuja los controles de selección en posiciones como cuando el texto no se escala. Se sabe de bug .

Es el resultado esperado porque los controles se dibujan en una ventana emergente relacionada con el tamaño de la vista.

Todas las acciones en android.widget.Editor están dirigidas a su campo private TextView mTextView; . Y si establecemos nuestro propio editor por reflexión, no sé qué hacer con los métodos privados, que no son reemplazables.

También los android.widget.Editor.HandleView#HandleView selección se dibujan en la ventana emergente android.widget.Editor.HandleView#HandleView coordenadas se calculan en el diseño y solo necesito DynamicLayout pero no tiene ninguna diferencia para nuestros propósitos.

El método android.text.Layout#getPrimaryHorizontal(int, boolean) es público y su valor se puede multiplicar en la escala, pero para eso necesitamos extender y anular el método privado android.widget.TextView#makeSingleLayout , pero esto es un problema.

También podríamos implementar nuestro propio diseño con todos los métodos de invalidación requeridos, pero todos los métodos que podemos invalidar están marcados con @hide anotación y no hay campos a los que se pueda acceder con una reflexión.

La siguiente captura de pantalla aparece para la escala en 2x

PD: el contexto de la tarea es un Editor con texto de edición de pellizco para hacer zoom. Relayout de texto con cálculo de tamaño no es una solución. Porque necesito Documento Portátil en cada tamaño de pantalla.


¿Intentaste aplicar diferentes estilos a estos elementos? Creo que debería funcionar con algún condicionamiento.

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


Puedes hacerlo usando MetricAffectingSpan . Aquí hay una clase que lo ejemplifica:

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

Referencia: Proyecto Java Source Code Warehouse.

MetricAffectingSpan jugar con MetricAffectingSpan y wrap (CharacterStyle cs) , que permite que CharacterStyle se aplique a una sola región de un Spanned determinado.

En su subclase, anule onTouch y pase sus valores a un ScaleGestureDetector . Almacenar la escala detectada como una variable miembro.

Sobrescriba onDraw y llame a canvas.scale() con su valor de escala antes de llamar a super.onDraw . Como puede observar en AbsoluteSizeSpan , al usar AbsoluteSizeSpan (Parcel src) obtendrá el texto que desea redimensionar, luego aplica updateDrawState .