Search code examples
androidtextviewscrollviewpinchzoom

Zoomable TextView in ScrollView


I would like to make a TextView that can change the size of it's text based on pinch zooming. The TextView is inside a ScrollView. I've got the TextView to zoom when pinching BUT only when you move your fingers almost perfectly horizontally. If there is a vertical component to the pinch-zoom it defaults to scrolling instead of zooming

Is there a way to disable the scrolling of the ScrollView when there is more than 1 pointer on it then re-enable scrolling when the pointer count returns to 1 or 0? Is the best way to create a CustomScrollView widget or is there an easier way?


Solution

  • Inspired by this answer https://stackoverflow.com/a/14577399/2014236

    scaleGD = new ScaleGestureDetector(this, new simpleOnScaleGestureListener());
    mTextView.setOnTouchListener(new OnTouchListener() {
    
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            if(event.getPointerCount() == 1){
                //stuff for 1 pointer
            }else{ //when 2 pointers are present
                switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    // Disallow ScrollView to intercept touch events.
                    v.getParent().requestDisallowInterceptTouchEvent(true);
                    scaleGD.onTouchEvent(event);
                    break;
    
                case MotionEvent.ACTION_MOVE:
                    // Disallow ScrollView to intercept touch events.
                    v.getParent().requestDisallowInterceptTouchEvent(true);
                    scaleGD.onTouchEvent(event);
                    break;
    
                case MotionEvent.ACTION_UP:
                    // Allow ScrollView to intercept touch events.
                    v.getParent().requestDisallowInterceptTouchEvent(false);
                    break;
                }
            }
            return true;
        }
    });
    

    EDIT:

    //later in the code
    public class simpleOnScaleGestureListener extends SimpleOnScaleGestureListener {
    
        @Override
        public boolean onScale(ScaleGestureDetector detector) {
            float size = codedText.getTextSize();
            float factor = detector.getScaleFactor();
            int increase = 0;
            if(factor > 1.0f)
                increase = 2;
            else if(factor < 1.0f)
                increase = -2;
    
            size += increase;
    
            codedText.setTextSize(TypedValue.COMPLEX_UNIT_PX, size);
            plainText.setTextSize(TypedValue.COMPLEX_UNIT_PX, size);            
            try {
                Thread.sleep(200);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            //remembering the favourable text size
            Editor edit = sp.edit();
            edit.putFloat("TXTSIZE", size);
            edit.commit();
            return true;
        }
    }
    

    By no means perfect but does a good enough job for me - feel free to make improvements.