Android uses ViewPager to achieve left-side circular sliding and carousel effects. androidviewpager

Source: Internet
Author: User

Android uses ViewPager to achieve left-side circular sliding and carousel effects. androidviewpager

ViewPager is a common android component. However, when we use ViewPager, we cannot achieve infinite circular sliding between left and right. When sliding to the border, we will see an animation that cannot flip pages, this may affect the user experience. In addition, ViewPager in some regions (for example, ViewPager that displays advertisements or announcements) may need automatic carousel effect, that is, the user can see other page information without sliding.

For this reason, I have read some examples on the Internet about the implementation of this effect, but they are not very satisfied. After repeated experiments, I will summarize and share them with you here, hoping to help you.


Implementation of cyclic sliding effect: PagerAdapter

We know that the sliding effect of ViewPager is very good, so we basically do not need to handle this slide, but only process the display of the content. The display of content is controlled by the Adapter, so the focus here is the Adapter. For simplicity, each View in this example is an image. The following is the Adapter code:

Private class ImageAdapter extends PagerAdapter {private ArrayList <ImageView> viewlist; public ImageAdapter (ArrayList <ImageView> viewlist) {this. viewlist = viewlist;} @ Override public int getCount () {// you cannot see the return Integer boundary. MAX_VALUE ;}@ Override public boolean isViewFromObject (View arg0, Object arg1) {return arg0 = arg1 ;}@ Override public void destroyItem (ViewGroup container, int posit Ion, Object object) {// Warning: Do not call removeView here} @ Override public Object instantiateItem (ViewGroup container, int position) {// modulo the ViewPager page number and retrieve the position % = viewlist of the items to be displayed in the View list. size (); if (position <0) {position = viewlist. size () + position;} ImageView view = viewlist. get (position); // if the View has already been added to a parent component, you must remove it first; otherwise, an IllegalStateException is thrown. ViewParent vp = view. getParent (); if (vp! = Null) {ViewGroup parent = (ViewGroup) vp; parent. removeView (view);} container. addView (view); // add listeners here if necessary return view ;}}


Note the following points:

  • Return Value of the getCount () method: this value is directly related to the "boundary" of ViewPager, so when we set it to Integer. after MAX_VALUE, the user basically cannot see this boundary (it is estimated that the battery has been suspended when it slides here ). Of course, it is also possible to set it to 100 times the actual number of content, which is the same as a previous implementation.

  • Processing of instantiateItem () method position: Because we set count to Integer. MAX_VALUE, so the value range of this position is very large, but the content we actually want to display is certainly not so much (usually only a few items), so here there will certainly be a modulo operation. However, a simple modulo may cause a problem: when the user slides left, the position may have a negative value. Therefore, we need to re-process the negative value so that it falls within the correct range.

  • Processing of the instantiateItem () method parent component: We usually directly addView, but if we write this directly here, IllegalStateException will be thrown. If there are three views in total, this exception is triggered when the user slides to the Fourth, because we try to add a view with a parent component to another component. However, if it is written as follows:

(ViewGroup)view.getParent().removeView(view);


Then NullPointerException is thrown because the component does not have a parent component at the beginning. Therefore, a judgment is required. That is, the above Code.

  • DestroyItem () method: because we have processed the remove logic in the instantiateItem () method, we do not need to process it here. In fact, the experiment shows that if the remove call is added here, the ViewPager content will be blank.


Implementation of carousel effect: update with Handler

Here I define a Handler to process ViewPager carousel. The so-called "Carousel" effect is like this: Switch the displayed page at a certain time (3 seconds here. Loop playback is achieved by controlling the playback of pages in a certain order. Therefore, we can use the sendEmptyMessageDelayed () method of Handler to implement timed update and

Note that the user may also manually slide the ViewPager with the carousel effect. Therefore, I think the user wants to view the specified page at this time, and the carousel should be canceled at this time. The following is the implementation of the Handler:

Private static class ImageHandler extends Handler {/*** requests to update the display View. */Protected static final int MSG_UPDATE_IMAGE = 1;/*** pause the carousel request. */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 you manually slide it, you must record the new page number. Otherwise, the carousel page will fail. * For example, if you are currently playing the second page on the first page, and the user slides to the last page, * the first page should be played, if you continue playing the second page, There is a logic problem. */Protected static final int MSG_PAGE_CHANGED = 4; // The carousel interval protected static final long MSG_DELAY = 3000; // use weak references to prevent Handler leakage. the Generic parameters here can be private WeakReference such as Fragment <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) {// the Activity has been recycled. You do not need to process the UI's return;} // check the message queue and remove unsent messages, this mainly avoids duplicated 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 activity. handler. sendEmptyMessageDelayed (MSG_UPDATE_IMAGE, MSG_DELAY); break; case MSG_KEEP_SILENT: // break is suspended if no message is sent; case MSG_BREAK_SILENT: activity. handler. sendEmptyMessageDe Layed (MSG_UPDATE_IMAGE, MSG_DELAY); break; case MSG_PAGE_CHANGED: // record the current page number to avoid incorrect page display during playback. CurrentItem = msg. arg1; break; default: break ;}}}



Integration code: MainActivity

The following is the MainActivity code, which mainly loads the View and initializes the ViewPager. Because the amount of code is relatively small and important parts have been annotated, I will not go into details.

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 content of iewPager viewPager = (ViewPager) findV IewById (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 () {// configure it with the currentItem field of the Adapter. @ Override public void onPageSelected (int arg0) {handler. sendMessage (Message. obtain (handler, ImageHandler. MSG_PAGE_CHANGED, arg0, 0) ;}@ Override public void onPageScrolled (int arg0, float arg1, int arg2) {}// Override this method to pause and restore the carousel effect @ Override public void onPageScrollStateChanged (int arg0) {switch (arg0) {case ViewPager. SCROLL_STATE_DRAGGING: handler. sendEmptyMessage (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); // The default value is in the middle, so that the user cannot see the boundary // start the carousel effect handler. sendEmptyMessageDelayed (ImageHandler. MSG_UPDATE_IMAGE, ImageHandler. MSG_DELAY);} // end of onCreate} // end of MainActivity


Welcome to my personal website

Related Article

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.