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?