The android development tutorial USES threads to implement the view smooth scrolling example

  • 2020-05-30 21:00:38
  • OfStack

Recently, I have been thinking about the pull-down refresh effect for a long time, and then I got to the step of pulling down the whole view through onTouch method. The next step is to pull down and let go to slide back. The net looked for a long time, did not find the detailed pull-down refresh example, only oneself slowly ponder over. Yesterday and today, studied for two days, pulled down after rolling back the effect finally made today! Happy. Now let's share my implementation method and some of my experience.
I look at the example of a great god, online is found in onTouch use View scrollTo (int int) method, to make the whole view of scroll down, I tried to use setTranslationY () to roll back the view, the first is no problem, but after a few more rolling, the view is, in fact already very "high" place, want to pull a long distance to see content. So the rollback must also be done using the scrollTo(int, int) method.
But scrollTo(int, int) executes instantaneously, and the method name will scroll to, in effect, "teleport to," so you need to teleport it step by step to make it look like it's rolling over...

Because I have to go running later, and there is no need to explain a lot of points, I will directly go to the code to show you, comments are written, the point will be separately mentioned 1, more detailed explanation and experience is waiting for me to pull down the realization of the refresh one day.


/**
     * @desc     Smooth scrolling 
     * @param    v         Views that need to be manipulated 
     * @param    fromY     The starting Y coordinates 
     * @param    toY         Termination of Y coordinates 
     * @param    fps         Frame rate 
     * @param    durtion     Animation completion time (milliseconds)     
     * */
    private void smoothScroll(View v, int fromY, int toY, int fps, long durtion) {  
        smoothScrollThread = new SmoothScrollThread(v, fromY, toY, durtion, fps);
        smoothScrollThread.run();
    }

    /**
     * @desc     Smooth scrolling thread, which is used to recursively call itself to achieve smooth scrolling of a view 
     * */
    class SmoothScrollThread implements Runnable {    
        // Views that need to be manipulated 
        private View v = null;      
        // The original Y coordinates 
        private int fromY = 0;  
        // The target Y coordinates 
        private int toY = 0;      
        // Animation execution time (milliseconds) 
        private long durtion = 0;      
        // Frame rate 
        private int fps = 60;       
        // Interval time (milliseconds), interval time  = 1000 /  Frame rate 
        private int interval = 0;   
        // Startup time, -1  Means not started 
        private long startTime = -1;
        / Decelerating interpolator 
        private DecelerateInterpolator decelerateInterpolator = null;

        /**
         * @desc     Construction method, do a good job 1 Once the configuration 
         * */
        public SmoothScrollThread(View v, int fromY, int toY, long durtion, int fps) {
            this.v = v;
            this.fromY = fromY;
            this.toY = toY;
            this.durtion = durtion;
            this.fps = fps;
            this.interval = 1000 / this.fps;       
            decelerateInterpolator = new DecelerateInterpolator();
        }
        @Override
        public void run() {
            // Judge first whether it is no 1 The second startup is the first 1 The startup timestamp is logged at the first startup, and that's about it 1 Once the assignment 
            if (startTime == -1) {
                startTime = System.currentTimeMillis();
            }          
            // Get a timestamp for the current moment 
            long currentTime = System.currentTimeMillis();      
            // Magnification, to expand the floating-point precision of division calculations 
            int enlargement = 1000;          
            // Figure out what percentage of the time the current moment runs to the entire animation 
            float rate = (currentTime - startTime) * enlargement / durtion;           
            // That ratio can't be anywhere near zero  0 - 1  Between, when you zoom in, you get  0 - 1000  between 
            rate = Math.min(rate, 1000);           
            // Take the progress of the animation through the interpolator to get the response ratio, multiply the start and target coordinates to get the distance the view should scroll at the current moment. 
            int changeDistance = (int) ((fromY - toY) * decelerateInterpolator.getInterpolation(rate / enlargement));            
            int currentY = fromY - changeDistance;           
            v.scrollTo(0, currentY);            
            if (currentY != toY) {
                postDelayed(this, this.interval);
            } else {
                return;
            }
        }   
        public void stop() {
            removeCallbacks(this);
        }
    }

1. Some key points:

1. The purpose of using threads is to recursively call itself, scrolling only 1 dot in each run() method, which is determined by frame rate and interpolators.

2. The interpolator is actually a function (function) in mathematics, input a floating-point number between 0 and 1 output floating-point number between 0 and 1, what is the output curve, looking is what interpolator, decelerate interpolator is slowdown, inside the plane rectangular coordinate system, uniform x value changes, y shaft changes are getting slower and slower.

3. The magnification factor (which is multiplied by 1000 there) is used to improve the accuracy, because it has been found from practice that dividing the number of milliseconds elapsed by the entire animation cycle gives a result of 0.0 - > 0.0 - > 0.0 - > 0.0 - > 1.0 - > 1.0 - > 1.0 - > 1.0 - > 1.0 - > 2.0 - > 2.0 - > 2.0, although it is a floating point number, but the precision is inexplicable to maintain in the units digit, multiplied by 1000, there will be a uniform change between 0 and 1000, at this time to remove 1000, you can get a uniform change between 0.000 and 1.000.

Another weird thing is that the values of MotionEvent.getY () and scrollTo(int,int) don't seem to be in the same coordinate system. This needs to be further analyzed and studied.


Related articles: