1, a few days ago in an app to see the sliding rebound effect, feel that the effect is very good, and then want to realize their own, in the online check is basically the next idea, I looked at a bit, decided to realize the idea to write down in detail, first look at the effect we achieve it.
It can be seen that this allows us to customize the ScrollView, through two judgments (head, bottom) to the dynamic will be scrollview inside the view downward translation, the general idea is this, the following directly put the code out, including the implementation of the steps and some important code has written comments
Package com.qianmo.myview2.view;/** * Created by Wangjitao on 2016/10/19 0019. * Support up and down bounce effect ScrollView * Below is the idea of implementation * 1, first through the Onfinishinflate () method to get to the view () in the ScrollView in the layout file behind the LinearLayout * 2, through the ontouchevent () to get the user's sliding time, in the Action_move method inside the judgment, call Isneedmove () method to determine whether the view is sliding to the top or bottom, if you use a Rect object to record the original view state, * The corresponding code is: Rect.set (View.getleft (), View.gettop (), View.getright (), View.getbottom ()); * Then translate the view down by 1/2 users sliding the distance, the corresponding code is as follows: * View.layout (View.getleft (), View.gettop ()-Deltay/2,view.getright (), View.getbott Om ()-DELTAY/2); * 3, when the user lifts the finger by judging rect.isempty () to determine whether to bounce back the animation, if necessary, call back the animation */import Android.content.context;import Android.graphics.rect;import Android.util.attributeset;import Android.view.motionevent;import Android.view.View; Import Android.view.animation.translateanimation;import Android.widget.scrollview;public class BounceScrollView Extends ScrollView {//child view (i.e. LinearLayout in the layout file behind us) private view view; The y-coordinate when clicked (the y-coordinate when tapping the screen) private float y; Rectangle (used to record the size of the view before panning, onlyis used to determine whether an animation is required.) Private rect rect = new rect (); Whether to start the calculation (the default is set to False) Private Boolean iscount = false; Public Bouncescrollview (context context, AttributeSet Attrs) {Super (context, attrs); /*** * Work is done based on the XML generation view. The function is called at the end of the build view, after all the child views have been added. Even if the subclass overrides the Onfinishinflate * method, the method of the parent class should be called to enable the method to execute. */@Override protected void Onfinishinflate () {if (Getchildcount () > 0) {//Why here is to get to No. 0 child's Vie What about W? Because ScrollView can only contain one view view = Getchildat (0); Super.onfinishinflate (); }}/*** * Monitor Touch * * @Override public boolean ontouchevent (motionevent ev) {if (view! = null) {commontouchevent (EV); } return super.ontouchevent (EV); }/*** * Touch event * * @param EV */public void commontouchevent (motionevent ev) {int action = EV . Getaction (); Switch (action) {case MotionEvent.ACTION_DOWN:break; Case MOTIONEVENT.ACTION_UP://Finger release, determine whether to reach the top, such as if (Isneedanimation ()) {Animat Ion (); Iscount = false; } break; /*** * Excludes the first move calculation, because the y-coordinate is not known for the first time and is not available in Motionevent.action_down, because this is the Myscrollview touch event passed to the LIS Tview child item above. So start with the second calculation. * However, we also want to initialize, that is, the first time to move the sliding distance to 0. Then the records are accurate and executed normally. * */Case MotionEvent.ACTION_MOVE:final Float PreY = y;//when pressed y-coordinate fl Oat Nowy = ev.gety ();//always y coordinate int deltay = (int) (prey-nowy);//sliding distance if (!iscount) { DeltaY = 0; It's going to be 0 here. } y = nowy; When scrolling to the top or bottom no longer scrolls, move the layout if (Isneedmove ()) {//Initialize the head rectangle if (rect.i Sempty ()) {//Save normal layout position Rect.set (View.getleft (), View.gettOP (), View.getright (), View.getbottom ()); }//Mobile layout (the situation where the layout is slipping is half the distance of the gesture flower) view.layout (View.getleft (), View.gettop ()-DELTAY/2 , View.getright (), View.getbottom ()-DELTAY/2); } Iscount = true; Break Default:break; }}/*** * Retraction animation */public void animation () {//Turn on Move animation (up, down translation has shifted distance) translateanimation Ta = new Translateanimation (0, 0, view.gettop (), rect.top); Ta.setduration (200); View.startanimation (TA); Set back to normal layout position view.layout (Rect.left, Rect.top, Rect.right, Rect.bottom); Rect.setempty (); }//Whether you need to turn on animation (by judging the Rect object) public boolean isneedanimation () {return!rect.isempty (); }/*** * Whether you need to move the layout inner.getmeasuredheight (): Gets the total height of the control * getheight (): Gets the height of the screen */public boolean IsNEedmove () {int offset = view.getmeasuredheight ()-getheight (); int scrolly = getscrolly (); 0 is the top, the back one is the bottom if (scrolly = = 0 | | scrolly = = offset) {return true; } return false; }}
Android--imitation iOS up and down bounce effect