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.
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.
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.
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.
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.
Next screenshot appears for scaled on 2x
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.
You can do that using MetricAffectingSpan. Here is a class exemplifying it:
Reference: Java Source Code Warehouse project
You need to play with MetricAffectingSpan and wrap(CharacterStyle cs) - which allows CharacterStyle to be applied to a single region of a given Spanned.
In your subclass, override onTouch and pass its values to a ScaleGestureDetector. Store the detected scale as a member variable.
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.
Did you try to apply different styles to these elements? I think it should work with some conditioning.