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;
}
});
}
}
Solved the issue with restricting value of TextView.setTextSize(). It's my adapter class:
public class ReadBookRcAdapter extends RecyclerView.Adapter<ReadBookRcAdapter.ReadBookViewHolder> {
private Context mContext;
private ArrayList<ReadBookTextBlockModel> mTextViewBlocks;
private float mTextSize;
public ReadBookRcAdapter(Context context) {
this.mContext = context;
this.mTextViewBlocks = new ReadBookTextBlockModel(context).getTextBlocks();
mTextSize = 15.0f;
}
class ReadBookViewHolder extends RecyclerView.ViewHolder {
TextView mTextViewItem;
ReadBookViewHolder(@NonNull View itemView) {
super(itemView);
this.mTextViewItem = itemView.findViewById(R.id.readBookTextRow);
}
void bind(ReadBookTextBlockModel dataList){
if (mTextSize != 15.0f) mTextViewItem.setTextSize(mTextSize);
mTextViewItem.setText(dataList.getBlockText());
}
}
@NonNull
@Override
public ReadBookViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.rc_item_read_book, parent, false);
return new ReadBookViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull ReadBookViewHolder holder, int position) {
ReadBookTextBlockModel model = mTextViewBlocks.get(position);
holder.bind(model);
}
public void setTextSize(float scale){
float maxTextSize = 37.5f;
float minTextSize = 7.5f;
if((mTextSize == minTextSize && scale < 1.0f) || (mTextSize == maxTextSize && scale >= 1.0f))
return;
float newTextSize = mTextSize * scale;
newTextSize = Math.max(minTextSize, Math.min(newTextSize, maxTextSize));
mTextSize = newTextSize;
Log.e("mTextSize*scale", String.valueOf(mTextSize));
notifyDataSetChanged();
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With