Android ViewPager dot indicator

  • 2021-12-13 09:23:23
  • OfStack

1 very common function, 1 ViewPager will automatically scroll, and there is a row of small dots black and white to indicate the current scroll progress

First, write an adapter for ViewPager. Here, all the elements in this adapter are ImageView for convenience


import android.content.Context;
import android.os.Handler;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.Interpolator;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.Scroller;
 
 
 
/**
 * Created by Administrator on 2016/2/24.
 */
public class HomeHomeBannerAdapter extends PagerAdapter{
    private Context context;
    private ImageView[] eventImageViews;
    private String[] eventUrls;
    int destWidth,destHeight;
 
 
    public HomeHomeBannerAdapter(Context context, String[] eventUrls,int destWidth,int destHeight) {
        this.context = context;
        this.eventUrls = eventUrls;
        this.destHeight = destHeight;
        this.destWidth = destWidth;
        initImageViews();
    }
 
    /**
     *  Initialization viewPager Some pictures in 
     */
    private void initImageViews(){
        if(eventUrls==null)return;
        eventImageViews = new ImageView[eventUrls.length];
        for (int i=0;i<eventUrls.length;i++) {
            eventImageViews[i] = new ImageView(context);
            eventImageViews[i].setLayoutParams(new LinearLayout.LayoutParams(destWidth, destHeight));
            eventImageViews[i].setPadding(0, 0, 0, 0);
            eventImageViews[i].setScaleType(ImageView.ScaleType.FIT_XY);
            JImageUtils.loadImageFromServerByUrl(context,eventImageViews[i],eventUrls[i]);
        }// Show pictures 
    }
 
    @Override
    public void destroyItem(ViewGroup container, int position, Object object) {
        if (eventImageViews != null && eventImageViews.length > position && position >= 0)
            container.removeView(eventImageViews[position]);
 
    }
 
    @Override
    public Object instantiateItem(ViewGroup container, int position) {
        container.addView(eventImageViews[position], 0);
        return eventImageViews[position];
    }
 
    @Override
    public int getCount() {return eventUrls==null?0:eventUrls.length;}
 
    @Override
    public boolean isViewFromObject(View arg0, Object arg1) {
        return arg0 == arg1;
    }
//ViewPager Listeners are integrated into internal classes 
    static public class EventViewPagerChangeListener implements ViewPager.OnPageChangeListener {
        LinearLayout llGuideGroup;
        int oldEventPosition;
        int currentItem;
 
        public EventViewPagerChangeListener(LinearLayout llGuideGroup){
            this.llGuideGroup = llGuideGroup;
        }
 
        @Override
        public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {}
 
        /**
         *  Control the white or black display of dots 
         * @param position
         */
        public void onPageSelected(int position) {
            llGuideGroup.getChildAt(oldEventPosition).setBackgroundResource(R.drawable.dot_normal);// Black dot 
            llGuideGroup.getChildAt(position).setBackgroundResource(R.drawable.dot_focused);// White dot 
            oldEventPosition = position;
            currentItem = position;
        }
 
        @Override
        public void onPageScrollStateChanged(int state) {
 
        }
    }
 
    /**
     *  Control viewpager Automatic sliding timing task 
     */
    public static class ScrollTask implements Runnable {
        EventViewPagerChangeListener listener;
        ViewPager vpEvent;
        int eventSize;
        Handler handler;
        public ScrollTask(EventViewPagerChangeListener listener,final ViewPager vpEvent, int eventSize){
            this.listener = listener;
            this.vpEvent = vpEvent;
            this.eventSize = eventSize;
            handler = new Handler();
        }
        public void run() {
            if(listener==null||vpEvent==null||eventSize==0)return;
            listener.currentItem = (listener.currentItem + 1) % eventSize;
            Log.i("Alex","currentItem Yes "+listener.currentItem);
            handler.post(new Runnable() {
                @Override
                public void run() {
                    vpEvent.setCurrentItem(listener.currentItem); //  Pass Handler Toggle pictures 
                }
            });
        }
    }
 
    public static class FixedSpeedScroller extends Scroller {
        private static final int mDuration = 400;
        private int eventCount;
 
        public FixedSpeedScroller(Context context, Interpolator interpolator,int eventCount) {
            super(context, interpolator);
            this.eventCount = eventCount;
        }
 
        @Override
        public void startScroll(int startX, int startY, int dx, int dy, int duration) {
            if (duration % 100 == 0 && duration > 0) {
                //" Now it's automatic stroke "
                if (duration / 100 == eventCount) super.startScroll(startX, startY, dx, dy, 1);// If it is the last 1 Zhang 
                else super.startScroll(startX, startY, dx, dy, mDuration);
 
            } else {
                // " Now it's a manual stroke "
                super.startScroll(startX, startY, dx, dy, 80);
            }
        }
    }
}

There is a listener in the inner class of the adapter above, and there is a member LinearLayout llGuideGroup in this listener. This linear layout contains several small dots. The following is the definition of this layout:


<RelativeLayout
        android:id="@+id/rlEvents"
        android:layout_width="match_parent"
        android:layout_height="200dp"
        android:visibility="gone">
 
        <android.support.v4.view.ViewPager
            android:id="@+id/vpEvent"
            android:layout_width="match_parent"
            android:layout_height="200dp"
            android:background="@color/black666666" />
 
        <LinearLayout
            android:id="@+id/llGuideGroup"
            android:layout_width="match_parent"
            android:layout_height="10dp"
            android:layout_alignParentBottom="true"
            android:layout_marginBottom="10dp"
            android:layout_centerHorizontal="true"
            android:gravity="center"
            android:orientation="horizontal" >
 
        </LinearLayout>
</RelativeLayout>

Set the number of dots and initialize the listener


/**
     *  Toward 1 Small dots are added to the linear layout, and the specific control logic is in listener Li 
     * @param llGuideGroup
     * @param count  How many dots do you want to add 
     */
    public EventViewPagerChangeListener addViewPagerDots(LinearLayout llGuideGroup,ViewPager vpEvents,int count){
        if(llGuideGroup==null||vpEvents==null||count<1)return null;
        LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(15, 15);
        lp.leftMargin = 5;
        lp.rightMargin = 5;
        for(int i=0;i<count;i++){
            ImageView imageView = new ImageView(llGuideGroup.getContext());
            imageView.setLayoutParams(lp);
            imageView.setBackgroundResource(i==0?R.drawable.dot_focused:R.drawable.dot_normal);
            llGuideGroup.addView(imageView);
        }
        // A monitor that controls the display of small dots 
        EventViewPagerChangeListener listener = new EventViewPagerChangeListener(llGuideGroup);
        vpEvents.addOnPageChangeListener(listener);
        return listener;
    }

Timing page switching through multithreading


HomeHomeBannerAdapter.EventViewPagerChangeListener listener = producer.addViewPagerDots(holder.llGuideGroup,holder.viewPager,eventUrls.length);// Add small dots for indication 
                    //  When Activity After being displayed, every 3 Second switch 1 Sub-picture display 
                    ScheduledExecutorService scheduledExecutorService = Executors.newSingleThreadScheduledExecutor();
                    scheduledExecutorService.scheduleAtFixedRate(new HomeHomeBannerAdapter.ScrollTask(listener,holder.viewPager,eventUrls.length), 3, 3, TimeUnit.SECONDS);

Setting a custom scroll to reduce the switching speed of viewPager


/**
     *  To ViewPager Set a custom scroll to reduce the default scroll speed 
     * @param vpEvent
     */
    public void setViewPagerScroller(ViewPager vpEvent){
        if(vpEvent==null)return;
        Field mField;
        Scroller mScroller;
        try {
            mField = ViewPager.class.getDeclaredField("mScroller");
            mField.setAccessible(true);
            mScroller = new HomeHomeBannerAdapter.FixedSpeedScroller(vpEvent.getContext(), new AccelerateInterpolator(),vpEvent.getChildCount());
            try {
                mField.set(vpEvent, mScroller);
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        }
    }

Related articles: