Android uses Viewpager for left and right loop sliding and carousel effects

Source: Internet
Author: User

Viewpager is a common Android component, but usually we do not use the Viewpager to achieve the left and right infinite loop sliding, when sliding to the boundary will see a page can not be animated, may affect the user experience. In addition, some culture viewpager (such as Viewpager for display ads or announcements) may require the effect of automatic carousel, where users can see information on other pages without swiping.

For this I looked at some of the existing network on the implementation of some examples of such effects, but are not very satisfied, after repeated experiments, summed up here and share to everyone, hope to be helpful.


The realization of the cyclic sliding effect: pageradapter

We know that the viewpager comes with a very good sliding effect, so we don't have to deal with this slide at all, only to handle the display of the content. The display of the content is controlled by adapter, so the focus here is the adapter. For simplicity's sake, each view in this example is directly a picture. Here is the code for adapter:

Private class Imageadapter extends pageradapter{private arraylist<imageview> viewlist;        Public Imageadapter (arraylist<imageview> viewlist) {this.viewlist = viewlist;        } @Override public int getcount () {//set to maximum so that the user cannot see the boundary return integer.max_value;        } @Override public boolean isviewfromobject (View arg0, Object arg1) {return arg0==arg1; } @Override public void Destroyitem (ViewGroup container, int position, Object objec T) {//warning: Do not call Removeview} @Override public Object Instantiateitem (VIEWG             Roup container, int position) {///to Viewpager page number modulo remove the item to be displayed in the View list position%= viewlist.size ();             if (position<0) {position = Viewlist.size () +position;             } ImageView view = Viewlist.get (position); If the view is already in the previousAdded to a parent component, you must remove first, or you will throw illegalstateexception.             Viewparent VP =view.getparent ();                 if (Vp!=null) {ViewGroup parent = (viewgroup) VP;             Parent.removeview (view);               } container.addview (view);           Add listeners here if necessary return view; }      }


Here are a few places to note:

  • GetCount ()   return value of method: This value is directly related to Viewpager " Boundary ", so when we set it to integer. max_value After the user basically can not see this boundary (estimated that the battery has been sliding here to hang the bar o_o). Of course, it is usually possible to set it to 100 times times the actual number of content, and one of the previous implementations was to do so.

  • Instantiateitem ()   Method Position: Because we set the count to  integer. max_value , so the value range of this position is very large, but we actually want to display the content is not so much (often only a few), so there is certainly a modulo operation. However, there is a problem with a simple modulo: if you consider the case where the user is sliding to the left, the position may appear negative. So we need to deal with negative values again, so that they fall within the correct interval.

  • Instantiateitem () methods The processing of parent components: usually we will addview directly, but if you write this directly, you will throw illegalstateexception. Assuming there are three view, the exception is triggered when the user slides to the fourth , because we are trying to add a view with a parent component to another component . However, if it is written directly as follows:

(ViewGroup) View.getparent (). Removeview (view);


It will also throw NullPointerExceptionbecause the component does not have a parent component at the beginning. Therefore, a judgement is required. That's the code above.

    • Destroyitem ()   method: Because we are in instantiateitem () The remove logic has been processed in the method, so there is no need to deal with it. In fact, the experiment shows that if you add a call to remove, there is a case where the contents of the Viewpager are empty.


Implementation of the Carousel effect: Update with Handler

Here I define a handler to handle the Viewpager of the carousel. The so-called "carousel" effect is achieved by toggling the displayed page every time (here is 3 seconds). By controlling each page to play in a certain sequence, the effect of the carousel is achieved. To do this, we can use the handler sendemptymessagedelayed () method to implement timed updates, and

Note The user may also manually swipe the Viewpager with the carousel effect , so I think the user wants to view the specified page at this time, and this should be the time to cancel the carousel. Here is the implementation of this handler:

private static class ImageHandler extends handler{/** * Request to update the displayed view.        */protected static final int msg_update_image = 1;         /** * Request to pause the carousel.        */protected static final int msg_keep_silent = 2;         /** * Request to resume Carousel.        */protected static final int msg_break_silent = 3;         /** * Record the latest page number, when the user manually swipe to record a new page number, otherwise the Carousel page error.         * For example, if on the first page, originally prepared to play the second page, and when the user swipe to the end, * should play the first page, if continue to follow the original second page playback, there is a logical problem.                 */protected static final int msg_page_changed = 4;                 Carousel interval protected static final long Msg_delay = 3000;        Use weak references to avoid handler leaks. The generic parameters here can be either activity or fragment, such as private weakreference<mainactivity> weakreference;                 private int currentitem = 0;        Protected ImageHandler (weakreference<mainactivity> wk) {weakreference = wk; } @Override public void Handlemessage (MeSsage msg) {super.handlemessage (msg);            LOG.D (Log_tag, "Receive message" + Msg.what);            Mainactivity activity = Weakreference.get ();            if (activity==null) {//activity has been recycled, no more UI return is required;            }//Check Message Queuing and remove unsent messages, mainly to avoid problems such as duplication of messages in complex environments.            if (Activity.handler.hasMessages (msg_update_image)) {activity.handler.removeMessages (msg_update_image);                } switch (msg.what) {case msg_update_image:currentitem++;                Activity.viewPager.setCurrentItem (CurrentItem);                Prepare for the next play activity.handler.sendEmptyMessageDelayed (Msg_update_image, Msg_delay);            Break            Case Msg_keep_silent://The break is paused as long as the message is not sent;                Case MSG_BREAK_SILENT:activity.handler.sendEmptyMessageDelayed (Msg_update_image, Msg_delay);            Break Case MSg_page_changed://Record the current page number to avoid playback when the page is not displayed correctly.                CurrentItem = MSG.ARG1;            Break            Default:break; }         }    }



Integration code: Mainactivity

The following is the code for mainactivity, which mainly loads the view and initializes the Viewpager settings. Because the amount of code is less, the important part has been annotated, do not repeat the

public class Mainactivity extends Activity {private static final String Log_tag = "mainactivity";    Private ImageHandler handler = new ImageHandler (new weakreference<mainactivity> (this));     Private Viewpager Viewpager;        @Override protected void OnCreate (Bundle savedinstancestate) {super.oncreate (savedinstancestate);        Setcontentview (R.layout.activity_main);        Initialize the contents of the Iewpager Viewpager = (viewpager) Findviewbyid (R.id.main_viewpager);        Layoutinflater Inflater = Layoutinflater.from (this);        ImageView View1 = (ImageView) inflater.inflate (R.layout.item, NULL);        ImageView view2 = (ImageView) inflater.inflate (R.layout.item, NULL);        ImageView view3 = (ImageView) inflater.inflate (R.layout.item, NULL);        View1.setimageresource (R.drawable.ics);        View2.setimageresource (R.drawable.jellybean);        View3.setimageresource (R.drawable.kitkat); arraylist<imageview> views = new arraylist<imageview> ();       Views.add (View1);        Views.add (VIEW2);        Views.add (VIEW3);        Viewpager.setadapter (new Imageadapter (views)); Viewpager.setonpagechangelistener (New Viewpager.onpagechangelistener () {//CurrentItem field with adapter            To set. @Override public void onpageselected (int arg0) {handler.sendmessage (Message.obtain (Handler, Ima            gehandler.msg_page_changed, arg0, 0));                         } @Override public void onpagescrolled (int arg0, float arg1, int arg2) {} Overwrite this method to achieve the pause and resume of the carousel @Override public void onpagescrollstatechanged (int arg0) {switch (arg0) {case ViewPager.SCROLL_STATE_DRAGGING:handler.sendEmpty                    Message (imagehandler.msg_keep_silent);                Break Case ViewPager.SCROLL_STATE_IDLE:handler.sendEmptyMessageDelayed (Imagehandler.msg_updatE_image, Imagehandler.msg_delay);                Break                Default:break;        }            }        }); Viewpager.setcurrentitem (INTEGER.MAX_VALUE/2);//default in the middle, so that the user does not see the boundary//start Carousel effect handler.sendemptymessagedelayed (Imag    Ehandler.msg_update_image, Imagehandler.msg_delay); }//end of Oncreate}//end of Mainactivity


Welcome everyone to visit my personal website Meng Meng's IT People

Android uses Viewpager for left and right loop sliding and carousel effects

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.