There are texts on my static layout, the layout is an item in a Recyclerview. The touch event of the Recyclerview class controls the pinch zoom to the text with ScaleGestureDetector. The zooming senario is, when the user action move the screen of Recyclerview, getting the screenshot of the recyclerview and displaying the image over the Recyclerview, and the user zooming to the image. When the action up, applying new text size that coming from scaling to the items. The new text size is should be same with when the zooming to image displaying text size. For this I use RelativeSizeSpan and float scaler value. I want to limit the total text size changing but it just doesn't happen.
The real problem is, the pinch zoom can be done more than once and it is necessary to collect the scaling that each of them because the pinch zoom reseting each action pointer up. (mScaleFactor = 1.0f) And the all of scaling shouldn't cross the specified limit. (MAX_ZOOM and MIN_ZOOM)
Recyclerview:
private ScaleListener mScaleListener;
private ScaleGestureDetector mScaleGestureDetector;
@Override
public boolean onTouchEvent(MotionEvent event) {
int action = event.getAction() & MotionEvent.ACTION_MASK;
if(event.getPointerCount() == 2 && (action == MotionEvent.ACTION_MOVE || action == MotionEvent.ACTION_POINTER_UP)) {
if(mScaleGestureDetector == null){
mScaleListener = new ScaleListener(mRecyclerview, mContext);
mScaleGestureDetector = new ScaleGestureDetector(mContext, mScaleListener);
} return mScaleGestureDetector.onTouchEvent(event);
}
}
Adapter:
private void changeTextSize(float mScaleFactor){
...
float newFontSize = (relativeSizeSpan.getSizeChange() * mScaleFactor);
...
}
ScaleListener:
public class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener {
private static final float MAX_ZOOM = 2.5f;
private static final float MIN_ZOOM = 0.5f;
private float mScaleFactor = 1.0f;
private ImageView mScreenShotView;
private Context mContext;
private View mView;
public ScaleListener(View mView, Context mContext) {
this.mView = mView;
this.mContext = mContext;
init();
}
private void init(){
int mWidth = mView.getWidth();
int mHeight = mView.getHeight();
if(mWidth == 0 || mHeight == 0) return;
mScreenShotView = new ImageView(mContext);
mScreenShotView.setLayoutParams(new ViewGroup.LayoutParams(mWidth, mHeight));
ViewGroup mPhysicalParentLayout = (ViewGroup) mView.getParent();
mPhysicalParentLayout.addView(mScreenShotView, mPhysicalParentLayout.indexOfChild(mView));
}
@Override
public boolean onScaleBegin(ScaleGestureDetector detector) {
mScreenShotView.setBackgroundDrawable(new BitmapDrawable(Kit.getScreenshot(mView)));
mScreenShotView.setAlpha(1f); mView.setAlpha(0f);
return true;
}
@Override
public boolean onScale(ScaleGestureDetector scaleGestureDetector){
mScaleFactor *= scaleGestureDetector.getScaleFactor();
mScaleFactor = Math.max(MIN_ZOOM, Math.min(mScaleFactor, MAX_ZOOM));
mScreenShotView.setScaleX(mScaleFactor);
mScreenShotView.setScaleY(mScaleFactor);
return true;
}
@Override
public void onScaleEnd(ScaleGestureDetector detector) {
((ReadBookRcAdapter)Objects.requireNonNull(((RecyclerView)mView).getAdapter())).changeTextSize(mScaleFactor);
mScreenShotView.animate().alpha(0f).setDuration(300).setListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationStart(Animator animation) {
mView.animate().alpha(1f).setDuration(300).setListener(null);
}
@Override
public void onAnimationEnd(Animator animation) {
mScreenShotView.setScaleX(1.0f);
mScreenShotView.setScaleY(1.0f);
mScaleFactor = 1.0f;
}
});
}
}
