1

I am trying to scale a TextView with a pinch-zoom gesture. I have the pinch zoom working, but as the text scales it becomes somewhat pixelated. I assume this is because the actual font size is not scaling. However, when I try to put setTextSize() anywhere inside the onTouch() method, it scales very choppy with little lines appearing/disappearing on the edge of the TextView and the text disappearing when scale sufficiently large. I have the TextView inside a LinearLayout, and the pinch zoom scales the LinearLayout.

Here is the layout xml:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#FF000000" >

<LinearLayout
    android:id="@+id/textLayout"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="vertical" >

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:gravity="top"
        android:text="texthere" />

</LinearLayout>

<View
    android:id="@+id/touchView"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" />

</FrameLayout>

Here is the touch listener java:

scaleView.setOnTouchListener(new View.OnTouchListener(){
        public boolean onTouch(View v, MotionEvent event){
            float viewWidth = mTextView.getWidth();
            float viewHeight = mTextView.getHeight();
            switch (event.getAction() & MotionEvent.ACTION_MASK) {
            case MotionEvent.ACTION_DOWN:
                mode = DRAG;
                x_0 = mTextView.getX();//+50;
                y_0 = mTextiew.getY();//+50;
                initialTouchRawX = event.getRawX();
                initialTouchRawY = event.getRawY();
                currentScale = mTextView.getScaleX();
                break;
            case MotionEvent.ACTION_POINTER_DOWN:
                oldDist2 = spacing(event);
                if (oldDist2 > 10f) {
                    mode = ZOOM;
                }
                break;
            case MotionEvent.ACTION_UP:
            case MotionEvent.ACTION_POINTER_UP:
                mode = NONE;
                break;
            case MotionEvent.ACTION_MOVE:
                float xmin = x_0 - viewWidth/2*(currentScale-1);
                float xmax = x_0 + viewWidth + viewWidth/2*(currentScale-1);
                float ymin = y_0 - viewHeight/2*(currentScale-1) + viewShift;
                float ymax = y_0 + viewHeight + viewHeight/2*(currentScale-1) + viewShift;
                if (mode == DRAG && initialTouchRawX >= xmin && initialTouchRawX <= xmax && initialTouchRawY >= ymin && initialTouchRawY <= ymax ) { 
                    float mShiftX = -(initialTouchRawX - x_0);
                    float mShiftY = -(initialTouchRawY - y_0);
                    mTextView.setX((float) event.getRawX()+mShiftX);
                    mTextView.setY((float) event.getRawY()+mShiftY);
                } else if (mode == ZOOM) {
                    float newDist2 = spacing(event);
                    if (newDist2 > 10f) {
                        newScale = newDist2 / oldDist2 * currentScale;
                        mTextView.setScaleX(newScale);
                        mTextView.setScaleY(newScale);
                        //***I've tried setting the font size here***
                    }
                }
                break;
            }
            //***I've tried setting the font size here***
            //*** Now I write the scaling float to shared preferences here
            return true; 
        }
    });

I am confounded about where and how to actually scale the font size. I've indicated in the code where I have tried implementing setFontSize(). I mean, it did work, for the most part, but like I mentioned above, it was very bad quality with text disappearing and the lines sometimes appearing on the edge of the TextView. Any hints are much appreciated.

=== EDIT: ===

I've implemented a custom TextView below:

public class ScaleTextView extends TextView {

public ScaleTextView(Context context) {
    this(context, null);
}

public ScaleTextView(Context context, AttributeSet attrs) {
    this(context, attrs, 0);
}

public ScaleTextView(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
    updateTextSize(context);
}

public void updateTextSize(Context context) {
    getTypeface();
    float currentTextSize = getTextSize();
    SharedPreferences otherSettings = context.getSharedPreferences("settings", 0);
    float newScale = otherSettings.getFloat("key_scaling", 1f);
    setTextSize(newScale * currentTextSize); 
}

}

So this helps somewhat except that the font size is now different for portrait and landscape, and this causes the scaling to change each time orientation is changed. The text still disappears once scale sufficiently large and there are lines on the edge of the textview sometimes. Maybe there is a betterway to pass the scaling variable to the custom ScaleTextView class?

jdods
  • 323
  • 7
  • 18
  • you need to have custom textview or provide a custom font size based on your scaling http://stackoverflow.com/questions/15991521/custom-font-in-android-for-whole-application/15991573#15991573 – Raghunandan Apr 15 '13 at 04:55
  • Hm... ok, so if I create a custom TextView, say ScaleTextView.java, then how do I pass the scaling as set by the pinch-zoom gesture to that custom TextView class? – jdods Apr 15 '13 at 15:46
  • I created a method updateTextSize() inside ScaleTextView.java and I have that call shared preferences, where I have the scaling gesture write the new scaling when the gesture stops. It didn't work. The font size in landscape at a 1.0 scaling is different than when in portrait. So this is working somewhat, but not completely. Any other suggestions? – jdods Apr 15 '13 at 15:55

0 Answers0