Home » Android » Vertical fling scrolling of text line in Android

Vertical fling scrolling of text line in Android

Posted by: admin June 15, 2020 Leave a comment

Questions:

I have implemented the editor code from the Android Note Pad sample code. Now I would like to add the ability to vertically fling scrolls the lines of text. An example of what I want to accomplish is the fling scrolling of the option lines in the Andorid

I Googled for examples of scroller and fling but I can not find anything that fits what I need to to. I have not found anything that even remotely fits what I am trying to do.

How to&Answers:

I have developed the answer to my question through blood, sweat and tears. I will post it here in hope that it will help someone else. The following methods are placed within the LinedEditText class from the Android Note Pad sample code.

============================

    public void InitScroller(Context context) {
        mScroller = new Scroller(context);       // Get a scroller object
        mScrollY = 0 ;                          // Set beginning of program as top of screen.
        mMinScroll = getLineHeight ()/2;            // Set minimum scroll distance
        mFlingV = 750;                         // Minimum fling velocity

    }

 @Override
 public boolean onTouchEvent(MotionEvent event) {
     super.onTouchEvent(event);

  if (mVelocityTracker == null) {                       // If we do not have velocity tracker
         mVelocityTracker = VelocityTracker.obtain();   // then get one
     }
     mVelocityTracker.addMovement(event);               // add this movement to it

  final int action = event.getAction();  // Get action type
  final float y = event.getY();          // Get the displacement for the action

  switch (action) {

     case MotionEvent.ACTION_DOWN:          // User has touched screen
         if (!mScroller.isFinished()) {     // If scrolling, then stop now
             mScroller.abortAnimation();
         }
         mLastMotionY = y;                  // Save start (or end) of motion
         mScrollY = this.getScrollY();              // Save where we ended up
         mText.setCursorVisible (true);
         didMove = false;

         break;

     case MotionEvent.ACTION_MOVE:          // The user finger is on the move
         didMove = true;
         final int deltaY = (int) (mLastMotionY - y);  // Calculate distance moved since last report
         mLastMotionY = y;                             // Save the start of this motion

         if (deltaY < 0) {                              // If user is moving finger up screen
             if (mScrollY > 0) {                        // and we are not at top of text
                 int m = mScrollY - mMinScroll;         // Do not go beyond top of text
                 if (m < 0){
                     m = mScrollY; 
                 }else m = mMinScroll;

              scrollBy(0, -m);                           // Scroll the text up
             }
         } else 
             if (deltaY > 0) {                           // The user finger is moving up
                 int max = getLineCount() * getLineHeight () - sHeight;   // Set max up value
                 if (mScrollY < max-mMinScroll){
                     scrollBy(0, mMinScroll);           // Scroll up
                 }
             }
         postInvalidate();
         break;

     case MotionEvent.ACTION_UP:                       // User finger lifted up
         final VelocityTracker velocityTracker = mVelocityTracker;      // Find out how fast the finger was moving
         velocityTracker.computeCurrentVelocity(mFlingV);          
         int velocityY = (int) velocityTracker.getYVelocity();

         if (Math.abs(velocityY) > mFlingV){                                // if the velocity exceeds threshold
             int maxY = getLineCount() * getLineHeight () - sHeight;        // calculate maximum Y movement
             mScroller.fling(0, mScrollY, 0, -velocityY, 0, 0, 0, maxY);    // Do the filng
         }else{
             if (mVelocityTracker != null) {                                // If the velocity less than threshold
                 mVelocityTracker.recycle();                                // recycle the tracker
                 mVelocityTracker = null;
             }
         }
         break;
     }

     mScrollY = this.getScrollY();              // Save where we ended up

  return true ;                                 // Tell caller we handled the move event
 }



 public void computeScroll() {                  // Called while flinging to execute a fling step
     if (mScroller.computeScrollOffset()) {      
         mScrollY = mScroller.getCurrY();       // Get where we should scroll to 
         scrollTo(0, mScrollY);                 // and do it
         postInvalidate();                      // the redraw the sreem
     }
 }

Answer:

This is a simpler version, which is basically the same at the scoller level. It’s not perfect but gives another way of looking at it.

final TextView textview = ((TextView) VIEW.findViewById(R.id.text));
final Scroller scroller = new Scroller(CONTEXT);

textview.setText(TEXT);
textview.setMovementMethod(new ScrollingMovementMethod());
textview.setScroller(scroller);
textview.setOnTouchListener(new View.OnTouchListener() {

    // Could make this a field member on your activity
    GestureDetector gesture = new GestureDetector(CONTEXT, new GestureDetector.SimpleOnGestureListener() {
        @Override
        public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
            scroller.fling(0, textview.getScrollY(), 0, (int)-velocityY, 0, 0, 0, (textview.getLineCount() * textview.getLineHeight()));
            return super.onFling(e1, e2, velocityX, velocityY);
        }

    });

    @Override
    public boolean onTouch(View v, MotionEvent event) {
        gesture.onTouchEvent(event);
        return false;
    }
});