Android Imitation Taobao product browsing interface picture scrolling effect _android

Source: Internet
Author: User
Tags gety

Use the mobile phone Taobao browsing merchandise details, the product picture is placed in the back, in the first ScrollView scroll to the bottom will be prompted, continue to drag to browse pictures. Imitate this effect write a come out is not difficult, as long as the definition of a layout management two ScrollView on the line, when the first ScrollView slide to the bottom, slide up again into the second ScrollView. The effect is as follows:

The areas to be noted are:

1, if it is manual sliding to the bottom of the need to press to continue to slide, automatic scrolling to the base does not need

2, in the process of sliding from the previous scrollview to the next scrollview a number of fingers will not lead to the changes in the layout of the changes, that is, multiple pointer sliding does not lead to move distance of the drastic changes.

The idea of this layout is:

Place two ScrollView in the layout, and set the Ontouchlistener for it, always judge the scrollview of the rolling distance, once the first ScrollView scroll to the bottom, then the identity can be dragged up, then start recording sliding distance Mmovelen , layout two ScrollView according to the Mmovelen; Likewise, listen for the second scrollview to scroll to the top to drag down.

OK, understand the principle can be seen after the code:

Package com.jingchen.tbviewer; 
Import Java.util.Timer; 
 
Import Java.util.TimerTask; 
Import Android.content.Context; 
Import Android.os.Handler; 
Import Android.os.Message; 
Import Android.util.AttributeSet; 
Import android.view.MotionEvent; 
Import Android.view.VelocityTracker; 
Import Android.view.View; 
Import Android.widget.RelativeLayout; 
 
Import Android.widget.ScrollView; 
 
  /** * contains two scrollview containers * * * @author chenjing * */public class Scrollviewcontainer extends Relativelayout { 
  /** * Automatic slip/public static final int auto_up = 0; 
  /** * Auto Drop * * public static final int auto_down = 1; 
  /** * Animation Complete * * public static final int done = 2; 
 
  /** * Animation speed/public static final float SPEED = 6.5f; 
 
  Private Boolean ismeasured = false; 
 
  /** * used to calculate the speed of hand sliding * * Private velocitytracker VT; 
  private int mviewheight; 
 
  private int mviewwidth; 
  Private View TopView; 
 
  Private View Bottomview; PrivaTe Boolean canpulldown; 
  Private Boolean Canpullup; 
 
  private int state = done; 
  /** * Records the current display of which view,0 is topview,1 is bottomview * * private int mcurrentviewindex = 0; 
  /** * Hand sliding distance, this is the main control layout variable * * Private float Mmovelen; 
  Private MyTimer Mtimer; 
  private float mlasty; /** * Another condition to control whether the layout is changed, mevents==0 layout can be dragged, Mevents==-1 can discard the upcoming first move event, * This is the key to remove the drastic changes in the drag/private int m 
 
  Events; Private Handler Handler = new Handler () {@Override public void Handlemessage (msg) {if (mmovel 
          En!= 0) {if (state = = auto_up) {Mmovelen-= SPEED; 
            if (Mmovelen <=-mviewheight) {mmovelen =-mviewheight; 
            state = done; 
          Mcurrentviewindex = 1; 
          ' Else if ' (state = = Auto_down) {Mmovelen + = SPEED; 
            if (Mmovelen >= 0) {mmovelen = 0; 
            state = done; 
         Mcurrentviewindex = 0; } else {mtimer.cancel (); 
    } requestlayout (); 
 
  } 
 
  }; 
    Public Scrollviewcontainer {Super (context); 
  Init (); 
    Public Scrollviewcontainer (context, AttributeSet attrs) {Super (context, attrs); 
  Init (); Scrollviewcontainer (context, AttributeSet attrs, int defstyle) {Super (context, Attrs, Defstyle 
    ); 
  Init (); 
  private void Init () {Mtimer = new MyTimer (handler); @Override public boolean dispatchtouchevent (motionevent ev) {switch (ev.getactionmasked ()) {case Mot 
      IONEVENT.ACTION_DOWN:IF (vt = NULL) VT = Velocitytracker.obtain (); 
      else Vt.clear (); 
      Mlasty = Ev.gety (); 
      Vt.addmovement (EV); 
      mevents = 0; 
    Break Case MotionEvent.ACTION_POINTER_DOWN:case MOTIONEVENT.ACTION_POINTER_UP://More than one finger when pressed or raised to discard the upcoming first event move to prevent multiple drag Drag the bug mevents =-1; 
    Break 
      Case MotionEvent.ACTION_MOVE:vt.addMovement (EV); 
        if (canpullup && mcurrentviewindex = = 0 && mevents = = 0) {Mmovelen = = (Ev.gety ()-mlasty); 
          Prevent upper and lower bounds if (Mmovelen > 0) {mmovelen = 0; 
        Mcurrentviewindex = 0; 
          else if (Mmovelen <-mviewheight) {Mmovelen =-mviewheight; 
 
        Mcurrentviewindex = 1; 
        } if (Mmovelen < 8) {//Prevent event Conflict ev.setaction (Motionevent.action_cancel); } else if (canpulldown && mcurrentviewindex = 1 && mevents = = 0) {Mmovelen = = (ev.gety 
        ()-mlasty); 
          Prevent upper and lower bounds if (Mmovelen <-mviewheight) {Mmovelen =-mviewheight; 
        Mcurrentviewindex = 1; 
          else if (Mmovelen > 0) {mmovelen = 0; 
        Mcurrentviewindex = 0; } if (Mmovelen > 8-mviewheight) {//Prevent event Conflict ev.setaction (Motionevent.action_cancel); 
      } else mevents++; 
      Mlasty = Ev.gety (); 
      Requestlayout (); 
    Break 
      Case MotionEvent.ACTION_UP:mLastY = Ev.gety (); 
      Vt.addmovement (EV); 
      Vt.computecurrentvelocity (700); 
      Gets the velocity of the Y-direction float myv = vt.getyvelocity (); 
      if (Mmovelen = = 0 | | | mmovelen = =-mviewheight) break; if (Math.Abs (MYV) < 500) {//the speed is less than a certain value as a static release, this time two view to which move depending on the distance of the slide if (Mmovelen <=-mviewheight 
        /2) {state = auto_up; 
        else if (Mmovelen >-MVIEWHEIGHT/2) {state = Auto_down; 
        } else {//lift finger speed direction determines where two view moves if (Myv < 0) state = auto_up; 
      else state = Auto_down; 
      } mtimer.schedule (2); 
      try {vt.recycle (); 
      catch (Exception e) {e.printstacktrace (); 
 
    } break; } suPer.dispatchtouchevent (EV); 
  return true; @Override protected void OnLayout (Boolean changed, int l, int t, int r, int b) {topview.layout (0, int) MM 
    Ovelen, Mviewwidth, Topview.getmeasuredheight () + (int) mmovelen); Bottomview.layout (0, Topview.getmeasuredheight () + (int) Mmovelen, mviewwidth, Topview.getmeasuredheight () + (int 
  ) Mmovelen + bottomview.getmeasuredheight ()); @Override protected void onmeasure (int widthmeasurespec, int heightmeasurespec) {super.onmeasure (widthmeas 
    Urespec, Heightmeasurespec); 
 
      if (!ismeasured) {ismeasured = true; 
      Mviewheight = Getmeasuredheight (); 
 
      Mviewwidth = Getmeasuredwidth (); 
      TopView = Getchildat (0); 
 
      Bottomview = Getchildat (1); 
      Bottomview.setontouchlistener (Bottomviewtouchlistener); 
    Topview.setontouchlistener (Topviewtouchlistener); } private Ontouchlistener Topviewtouchlistener = new Ontouchlistener () {
 
    @Override public boolean Ontouch (View V, motionevent event) {ScrollView SV = (scrollview) v; if (sv.getscrolly () = = (Sv.getchildat (0). Getmeasuredheight ()-SV. Getmeasuredheight ()) && Mcurrentview 
      Index = = 0) Canpullup = true; 
      else Canpullup = false; 
    return false; 
  } 
  }; Private Ontouchlistener Bottomviewtouchlistener = new Ontouchlistener () {@Override public boolean Ontouch (Vie 
      W V, motionevent event) {ScrollView SV = (scrollview) v; 
      if (sv.getscrolly () = = 0 && mcurrentviewindex = 1) Canpulldown = true; 
      else Canpulldown = false; 
    return false; 
 
  } 
  }; 
    Class MyTimer {private Handler Handler; 
    private timer timer; 
 
    Private MyTask Mtask; 
      Public MyTimer (Handler Handler) {this.handler = Handler; 
    Timer = new timer (); 
} public void schedule (long period) {if (mtask!= null) {        Mtask.cancel (); 
      Mtask = null; 
      } mtask = new MyTask (handler); 
    Timer.schedule (mtask, 0, period); 
        public void Cancel () {if (mtask!= null) {mtask.cancel (); 
      Mtask = null; 
 
      } class MyTask extends TimerTask {private Handler Handler; 
      Public MyTask (Handler Handler) {this.handler = Handler; 
      @Override public void Run () {handler.obtainmessage (). Sendtotarget (); 

 } 
 
    } 
  } 
 
}

The notes are well written and there are a few key points to be told :
1, because here for two scrollview set Ontouchlistener, so in other places can not be set, otherwise it will be in vain.

The layout parameters of 2 and two ScrollView are unified by Mmovelen.

3, the variable mevents has two functions: one is to prevent manual sliding to the bottom or the top of the slide while continuing to change the layout, you must press to continue to slide; the second is to set the mevents to 1 at the new pointer down or up to discard the first move event that will come. Prevent the Mmovelen from appearing in upheaval. Why is there upheaval? Since it is assumed that only one finger is sliding at first, the coordinates of the record are the event coordinates of this pointer, when another finger presses a pointer that causes the event, the coordinates of the moving event may become the coordinates of the new pointer. At this time the difference between the calculation and the previous coordinates will be drastic changes, the distance is two pointer distance. So to discard this move event, let the Mlasty value record the coordinates of this pointer and then start to compute the Mmovelen. It's the same when pointer up.

Understanding these points, it looks like there is no difficulty, the amount of code is very small.

Layout of mainactivity:

<relativelayout xmlns:android= "http://schemas.android.com/apk/res/android" android:layout_width= "match_parent "android:layout_height=" match_parent "> <com.jingchen.tbviewer.scrollviewcontainer Android:layout_widt H= "Match_parent" android:layout_height= "match_parent" > <scrollview android:layout_width= "match_p" Arent "android:layout_height=" match_parent "> <relativelayout android:layout_width=" Wrap_co Ntent "android:layout_height=" wrap_content "> <linearlayout android:id=" @+id/imagesla Yout "android:layout_width=" match_parent "android:layout_height=" Wrap_content "Android:gr" Avity= "Center_horizontal" android:orientation= "vertical" > <imageview android:l  Ayout_width= "Wrap_content" android:layout_height= "wrap_content" android:background= "@drawable/h" /> <imagevIew android:layout_width= "wrap_content" android:layout_height= "Wrap_content" Androi 
            d:background= "@drawable/i"/> <imageview android:layout_width= "Wrap_content" 
            android:layout_height= "Wrap_content" android:background= "@drawable/j"/> <imageview Android:layout_width= "Wrap_content" android:layout_height= "Wrap_content" Android:backgrou nd= "@drawable/k"/> <imageview android:layout_width= "Wrap_content" Android:la yout_height= "Wrap_content" android:background= "@drawable/L"/> <imageview and Roid:layout_width= "Wrap_content" android:layout_height= "wrap_content" android:background= "@drawa 
          ble/m "/> </LinearLayout> <textview android:layout_width=" Match_parent " Android:layout_height= "60DP" android:layout_below= "@id/imageslayout" android:background= "#eeeeee" Android:gra vity= "center" android:text= "continue to drag, see more Beauty" android:textsize= "20sp"/> </relativelayout&gt 
    ; </ScrollView> <scrollview android:layout_width= "match_parent" android:layout_height= "match_p 
        Arent "android:background=" #000000 "> <linearlayout android:layout_width=" match_parent " android:layout_height= "Match_parent" android:gravity= "center_horizontal" android:orientation= "vert" ical "> <imageview android:layout_width=" wrap_content "android:layout_height=" Wrap_ Content "android:background=" @drawable/A "/> <imageview android:layout_width=" Wrap_ Content "android:layout_height=" wrap_content "android:background=" @drawable/b "/> < 
      ImageView    Android:layout_width= "Wrap_content" android:layout_height= "wrap_content" android:background= "@dr Awable/c "/> <imageview android:layout_width=" wrap_content "android:layout_height=" Wrap_content "android:background=" @drawable/d "/> <imageview android:layout_width=" 
 
        Wrap_content "android:layout_height=" wrap_content "android:background=" @drawable/e "/> <imageview android:layout_width= "wrap_content" android:layout_height= "Wrap_content" a Ndroid:background= "@drawable/F"/> <imageview android:layout_width= "Wrap_content" a ndroid:layout_height= "Wrap_content" android:background= "@drawable/g"/> </LinearLayout> &l 
 T;/scrollview> </com.jingchen.tbviewer.ScrollViewContainer> </RelativeLayout>

I put a few pictures in the ScrollView.
Code for Mainactivity:

Package com.jingchen.tbviewer; 
 
Import android.app.Activity; 
Import Android.os.Bundle; 
Import Android.view.Menu; 
 
public class Mainactivity extends activity 
{ 
  @Override 
  protected void onCreate (Bundle savedinstancestate) 
  { 
    super.oncreate (savedinstancestate); 
    Setcontentview (R.layout.activity_main); 
  } 
 
  @Override Public 
  Boolean oncreateoptionsmenu (Menu menu) 
  { 
    getmenuinflater (). Inflate (R.menu.main, menu); 
    return true; 
  } 
 

The above is the entire content of this article, I hope to help you learn.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.