Making address: https://github.com/xuerui1993/AutoViewPager

Automatic rotation chart is common android development controls, if in the need to develop, each place to write, so it is more time-consuming, laborious, might as well encapsulate into a custom control, in the need to use so that only to set up the data can be, so that in the subsequent development not only save time, but also can better troubleshooting. Github address above provides the source code, need more detailed understanding can go to read the source code.





1507193217(1).jpg

Implement custom attributes

While this is not difficult, it is a common feature of custom controls

  1. Start by inheriting the control from RelativeLayout and declaring it in the values folder attrs.xml file
    <declare-styleable name="AutoViewpager">
        <attr name="dotSize" format="dimension"/>
        <attr name="dotSrc" format="reference"/>
        <attr name="duration" format="integer"/>
        <attr name="isAuto" format="boolean"/>
        <attr name="dotPosition" format="enum">
            <enum name="left" value="0"/>
            <enum name="center" value="1"/>
            <enum name="right" value="2"/>
        </attr>
    </declare-styleable>
Copy the code
  1. Reads the properties
TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.AutoViewpager); mDuration = ta.getInteger(R.styleable.AutoViewpager_duration, NORMAL_DURATION); mDotSize = ta.getDimensionPixelSize(R.styleable.AutoViewpager_dotSize, DOT_NORAML_SIZE); mIsAuto = ta.getBoolean(R.styleable.AutoViewpager_isAuto, true); mDrawable = ta.getDrawable(R.styleable.AutoViewpager_dotSrc); mDotPosition = ta.getInteger(R.styleable.AutoViewpager_dotPosition, 2); // Release the resource ta.recycle();Copy the code
  1. Use the read properties in the code
Note: When a dot uses a Drawable image, the selected property of the image is involved, so each dot needs to use a new Drawable, so it needs to use a clone of the image. Otherwise, a selected Drawable object will cause all images to be selected. The dot cannot be selected.
Drawable newDrawable = mDrawable.getConstantState().newDrawable();
imageView.setImageDrawable(newDrawable);
Copy the code

2. Set the Viewpager adapter

  1. To allow infinite rotation, the getCount() method returns the maximum value of an Integer

    @Override public int getCount() { if (mList ! = null) { return Integer.MAX_VALUE; } return 0; }Copy the code
  2. Make the ImageLoader interface to be externally implemented to load images and reduce the reliance on third-party libraries

    public interface ImageLoader extends Serializable { void displayImage(Context context, String url, ImageView imageView);  void clearMemoryCache(); }Copy the code

3. Set image and image click event in Adapter’s instantiateItem method, position % mlist.size () for infinite rotation;

@Override public Object instantiateItem(ViewGroup container, final int position) { final int picPosition = position % mList.size(); // Positon % mlist.size (); ImageView imageView = new ImageView(mContext); imageView.setScaleType(ImageView.ScaleType.CENTER_CROP); String url = mList.get(picPosition); If (mImageloader==null){throw new IllegalArgumentException(" ImageLoader class is null "); } mImageloader.displayImage(mContext,url,imageView); imageView.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { if (mItemClickListener ! = null) { mItemClickListener.OnItemClickListener(picPosition); }}}); container.addView(imageView); return imageView; }Copy the code
Note: In order to implement infinite rotation, you need to create a new ImageView object, otherwise the ViewpagerAdapter will throw an exception
ImageView imageView = new ImageView(mContext);
Copy the code

Initialize the dot

Private void initDotContaner (a List < String > List) {/ / set the dot position in control RelativeLayout. LayoutParams LayoutParams = (RelativeLayout.LayoutParams) mLlDot.getLayoutParams(); switch (mDotPosition) { case 0: layoutParams.addRule(RelativeLayout.ALIGN_LEFT); break; case 1: layoutParams.addRule(RelativeLayout.CENTER_HORIZONTAL); break; case 2: layoutParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT); break; } mLlDot.removeAllViews(); ArrayList<ImageView> imageList = new ArrayList<>(); for (int i = 0; i < list.size(); i++) { ImageView imageView = new ImageView(getContext()); if (mDotDrawableRes ! = 0) {/ / the code set up mDotDrawableRes set will be the priority imageView. SetImageResource (R.d rawable. Dot_selector); } else { if (mDrawable ! = null) {/ / set up in the layout, shows the layout of Drawable newDrawable = mDrawable. GetConstantState () newDrawable (); imageView.setImageDrawable(newDrawable); / / clone dots and set} else {/ / if haven't set, set the default imageView. SetImageResource (R.d rawable. Dot_selector); } } LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(mDotSize, mDotSize); imageList.add(imageView); if (i ! = 0) { params.leftMargin = mDotSize; } else {// By default the first dot is selected mCurrentDot = imageView; imageView.setSelected(true); } imageView.setLayoutParams(params); mLlDot.addView(imageView); // Add a dot}}Copy the code

Fourthly, let the picture start to rotate

  1. To start the slide left and right, select the image as the middle of the Integer’s maximum value

    Int middle = integer. MAX_VALUE / 2; int extra = middle % mCount; mViewPager.setCurrentItem(middle-extra);Copy the code
  2. Do a timed task to start the image rotation

    class SwitchPagerTask extends Handler implements Runnable { @Override public void run() { int currentItem = mViewPager.getCurrentItem(); if (currentItem == mAdvertAdapter.getCount() - 1) { mViewPager.setCurrentItem(0); } else { mViewPager.setCurrentItem(currentItem + 1); } // On a post, the loop executes postDelayed(this, mDuration); Duration} /** * public void start() {removeCallbacks(this); // In a post loop, postDelayed(this, START_DURATION); } /** * public void stop() {removeCallbacks(this); }}Copy the code

3. Set the dots were selected, you need to set up to monitor viewpager sliding state, mViewPager. AddOnPageChangeListener (this);

@Override public void onPageSelected(int position) { position = position % mLabelList.size(); if (mLabelList ! = null && mLabelList.size() > position) { mTvLabel.setText(mLabelList.get(position) + ""); } mCurrentDot.setSelected(false); ImageView imageView = (ImageView) mLlDot.getChildAt(position); imageView.setSelected(true); mCurrentDot = imageView; }Copy the code

Five, perfect details

  1. In sliding touch to instant viewpager shuffling, monitored viewpager touch events, mViewPager. SetOnTouchListener (this);

    @Override public boolean onTouch(View v, MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: if (mSwitchPagerTask ! = null) { mSwitchPagerTask.stop(); } break; case MotionEvent.ACTION_MOVE: if (mSwitchPagerTask ! = null) { mSwitchPagerTask.stop(); } break; case MotionEvent.ACTION_UP: if (mSwitchPagerTask ! = null) { mSwitchPagerTask.start(); } break; } return false; }Copy the code
  2. To prevent memory leaks, add the Ondestroy() method of AutoViewPager

     public void onDestory() {
         mSwitchPagerTask.stop();
         mSwitchPagerTask = null;
         mViewPager.removeOnPageChangeListener(this);
         mItemClickListener = null;
     }
    Copy the code

You can add dependencies to the gradle configuration in AndroidStudio if you want

Here’s an article I wrote on how to publish your GitHub open source library.