Browse Source

2.5.0 (#35)

* Fix bug #33.

* Optimize Issue #20.

* Optimize BannerViewPager.

* Optimize Indicator.

* Add Kotlin sample in README.
zhpanvip 5 years ago
parent
commit
34dc506a69
37 changed files with 1147 additions and 629 deletions
  1. 38 6
      README.md
  2. 3 1
      app/build.gradle
  3. 0 129
      app/src/main/java/com/example/zhpan/circleviewpager/activity/WelcomeActivity.java
  4. 115 0
      app/src/main/java/com/example/zhpan/circleviewpager/activity/WelcomeActivity.kt
  5. 9 20
      app/src/main/java/com/example/zhpan/circleviewpager/fragment/HomeFragment.java
  6. 1 14
      app/src/main/java/com/example/zhpan/circleviewpager/fragment/IndicatorFragment.java
  7. 0 15
      app/src/main/java/com/example/zhpan/circleviewpager/fragment/PageFragment.java
  8. 4 0
      app/src/main/java/com/example/zhpan/circleviewpager/net/ApiService.java
  9. 1 1
      app/src/main/java/com/example/zhpan/circleviewpager/view/FigureIndicatorView.java
  10. 7 4
      app/src/main/java/com/example/zhpan/circleviewpager/viewholder/NetViewHolder.java
  11. 1 0
      app/src/main/res/layout/activity_welcome.xml
  12. 2 1
      app/src/main/res/layout/item_header_view.xml
  13. 6 4
      app/src/main/res/layout/item_net.xml
  14. 190 251
      bannerview/src/main/java/com/zhpan/bannerview/BannerViewPager.java
  15. 3 3
      bannerview/src/main/java/com/zhpan/bannerview/adapter/BannerPagerAdapter.java
  16. 0 5
      bannerview/src/main/java/com/zhpan/bannerview/annotation/Visibility.java
  17. 2 2
      bannerview/src/main/java/com/zhpan/bannerview/constants/IndicatorGravity.java
  18. 1 1
      bannerview/src/main/java/com/zhpan/bannerview/constants/IndicatorSlideMode.java
  19. 1 1
      bannerview/src/main/java/com/zhpan/bannerview/constants/IndicatorStyle.java
  20. 3 3
      bannerview/src/main/java/com/zhpan/bannerview/constants/PageStyle.java
  21. 4 4
      bannerview/src/main/java/com/zhpan/bannerview/constants/TransformerStyle.java
  22. 1 1
      bannerview/src/main/java/com/zhpan/bannerview/holder/ViewHolder.java
  23. 97 77
      bannerview/src/main/java/com/zhpan/bannerview/indicator/BaseIndicatorView.java
  24. 14 13
      bannerview/src/main/java/com/zhpan/bannerview/indicator/CircleIndicatorView.java
  25. 38 32
      bannerview/src/main/java/com/zhpan/bannerview/indicator/DashIndicatorView.java
  26. 4 1
      bannerview/src/main/java/com/zhpan/bannerview/indicator/IIndicator.java
  27. 79 0
      bannerview/src/main/java/com/zhpan/bannerview/manager/AttributeController.java
  28. 33 0
      bannerview/src/main/java/com/zhpan/bannerview/manager/BannerManager.java
  29. 271 0
      bannerview/src/main/java/com/zhpan/bannerview/manager/BannerOptions.java
  30. 167 0
      bannerview/src/main/java/com/zhpan/bannerview/manager/IndicatorOptions.java
  31. 0 3
      bannerview/src/main/java/com/zhpan/bannerview/transform/pagestyle/BasePageTransformer.java
  32. 0 3
      bannerview/src/main/java/com/zhpan/bannerview/transform/pagestyle/NonPageTransformer.java
  33. 4 13
      bannerview/src/main/java/com/zhpan/bannerview/utils/BannerUtils.java
  34. 0 8
      bannerview/src/main/java/com/zhpan/bannerview/utils/PositionUtils.java
  35. 46 13
      bannerview/src/main/java/com/zhpan/bannerview/view/CatchViewPager.java
  36. 2 0
      build.gradle
  37. BIN
      download/app.apk

+ 38 - 6
README.md

@@ -205,6 +205,31 @@ public class NetViewHolder implements ViewHolder<BannerData> {
 
 ### 5.BannerViewPager参数配置
 
+Kotlin示例:
+
+```
+    private lateinit var mViewPager: BannerViewPager<CustomBean, CustomPageViewHolder>
+    
+    private fun initViewPager() {
+            mBannerViewPager = findViewById(R.id.bannerView)
+            mBannerViewPager.setCanLoop(false)
+                .setIndicatorSlideMode(IndicatorSlideMode.SMOOTH)
+                .setIndicatorMargin(0, 0, 0, ConvertUtils.dp2px(40f))
+                .setIndicatorGravity(IndicatorGravity.CENTER)
+                .setHolderCreator { CustomPageViewHolder() }
+                .setOnPageChangeListener(
+                    object : OnPageChangeListenerAdapter() {
+                        override fun onPageSelected(position: Int) {
+                            pageSelect(position)
+                        }
+                    }
+                )
+                .create(res.toList())
+        }
+```    
+
+Java示例:
+
 ```
     private BannerViewPager<BannerData, NetViewHolder> mBannerViewPager;
     ...
@@ -226,10 +251,11 @@ public class NetViewHolder implements ViewHolder<BannerData> {
                 }).create(mList);
         }
 ```
-
 ### 6.开启与停止轮播
 
-如果开启了自动轮播功能,请务必在onDestroy中停止轮播,以免出现内存泄漏。
+***2.5.0之后版本无需自行在Activity或Fragment中管理stopLoop和startLoop方法,但这两个方法依旧保留对外开放***
+
+~~如果开启了自动轮播功能,请务必在onDestroy中停止轮播,以免出现内存泄漏。~~
 
 ```
 	@Override
@@ -239,7 +265,7 @@ public class NetViewHolder implements ViewHolder<BannerData> {
     		mViewpager.stopLoop();
     }
 ```
-为了节省性能也可以在onStop中停止轮播,在onResume中开启轮播:
+~~为了节省性能也可以在onStop中停止轮播,在onResume中开启轮播:~~
 
 ```
     @Override
@@ -256,6 +282,7 @@ public class NetViewHolder implements ViewHolder<BannerData> {
             mBannerViewPager.startLoop();
     }
 ```
+
 ### 7.高级功能---自定义IndicatorView
 
 在内置Indicator不满足需求时可以通过自定义IndicatorView实现。
@@ -324,7 +351,7 @@ public class FigureIndicatorView extends BaseIndicatorView {
     }
 }
 ```
-** (2)设置自定义指示器 **
+**(2)设置自定义指示器**
 
 ```
     FigureIndicatorView indicatorView = new FigureIndicatorView(mContext);
@@ -352,13 +379,18 @@ public class FigureIndicatorView extends BaseIndicatorView {
 
  - [x] 增添更多Indicator样式(2.3.+)
  - [x] 支持一屏显示多页 (2.4.0)
- - [x] 将v2.4.3版本中着重优化提升性能
+ - [x] v2.4.3版本着重优化提升性能
+ - [ ] v2.5.0优化整理Indicator,尽量修复Indicator SMOOTH模式下滑动问题
  - [ ] ViewPager更换为ViewPager2 (3.0.0)
  - [ ] 目前Indicator部分代码比较乱,还有很大很大的优化空间,后续版本将持续优化
  
 
 
-[更多详情请点击此处](https://juejin.im/post/5d6bce24f265da03db0790d1)
+##  更多详情请参看以下链接
+
+[《打造一个丝滑般自动轮播无限循环Android库》](https://juejin.im/post/5d6bce24f265da03db0790d1)
+[《BannerViewPager源码解析》](https://juejin.im/post/5d74d3faf265da03b5747015)
+
 
 ## 感谢
 

+ 3 - 1
app/build.gradle

@@ -1,5 +1,6 @@
 apply plugin: 'com.android.application'
-
+apply plugin: 'kotlin-android'
+apply plugin: 'kotlin-android-extensions'
 android {
     compileSdkVersion 28
     buildToolsVersion '28.0.3'
@@ -55,4 +56,5 @@ dependencies {
     implementation project(path: ':ideahttp')
     api 'com.jakewharton:butterknife:10.2.0'
     annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.0'
+    implementation 'androidx.core:core-ktx:1.0.2'
 }

+ 0 - 129
app/src/main/java/com/example/zhpan/circleviewpager/activity/WelcomeActivity.java

@@ -1,129 +0,0 @@
-package com.example.zhpan.circleviewpager.activity;
-
-
-import android.animation.AnimatorSet;
-import android.animation.ObjectAnimator;
-import android.os.Bundle;
-import android.view.View;
-import android.view.animation.DecelerateInterpolator;
-import android.widget.TextView;
-import android.widget.Toast;
-
-import com.example.zhpan.circleviewpager.R;
-import com.example.zhpan.circleviewpager.bean.CustomBean;
-import com.example.zhpan.circleviewpager.viewholder.CustomPageViewHolder;
-import com.zhpan.bannerview.BannerViewPager;
-import com.zhpan.bannerview.adapter.OnPageChangeListenerAdapter;
-import com.zhpan.bannerview.constants.IndicatorSlideMode;
-import com.zhpan.bannerview.constants.TransformerStyle;
-import com.zhpan.bannerview.holder.HolderCreator;
-import com.zhpan.bannerview.utils.BannerUtils;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Random;
-
-import butterknife.BindView;
-import butterknife.ButterKnife;
-import butterknife.OnClick;
-
-public class WelcomeActivity extends BaseDataActivity implements
-        HolderCreator<CustomPageViewHolder> {
-
-    private BannerViewPager<CustomBean, CustomPageViewHolder> mViewPager;
-
-    private String[] des = {"在这里\n你可以听到周围人的心声", "在这里\nTA会在下一秒遇见你", "在这里\n不再错过可以改变你一生的人"};
-
-    private int[] transforms = {TransformerStyle.NONE, TransformerStyle.ACCORDION, TransformerStyle.STACK, TransformerStyle.DEPTH, TransformerStyle.ROTATE};
-
-    @BindView(R.id.btn_start)
-    TextView mTvStart;
-
-    @BindView(R.id.tv_describe)
-    TextView mTvDescription;
-
-    private static final int ANIMATION_DURATION = 1300;
-
-    @Override
-    protected void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        setContentView(R.layout.activity_welcome);
-        ButterKnife.bind(this);
-        setupViewPager();
-        updateUI(0);
-    }
-
-    @Override
-    protected void onDestroy() {
-        mViewPager.stopLoop();
-        super.onDestroy();
-    }
-
-    private void setupViewPager() {
-        mViewPager = findViewById(R.id.viewpager);
-        mViewPager.setAutoPlay(false)
-                .setCanLoop(false)
-                .setPageTransformerStyle(transforms[new Random().nextInt(5)])
-                .setScrollDuration(ANIMATION_DURATION)
-                .setIndicatorMargin(0, 0, 0, BannerUtils.dp2px(100))
-                .setIndicatorGap((int) getResources().getDimension(R.dimen.dp_10))
-                .setIndicatorColor(getResources().getColor(R.color.white),
-                        getResources().getColor(R.color.white_alpha_75))
-                .setIndicatorSlideMode(IndicatorSlideMode.SMOOTH)
-                .setIndicatorRadius((int) getResources().getDimension(R.dimen.dp_3), (int) getResources().getDimension(R.dimen.dp_4_5))
-                .setOnPageChangeListener(new OnPageChangeListenerAdapter() {
-                    @Override
-                    public void onPageSelected(int position) {
-                        updateUI(position);
-                    }
-                })
-                .setHolderCreator(this)
-                .create(getData());
-    }
-
-    @OnClick(R.id.btn_start)
-    public void onClick(View view) {
-        MainActivity.start(WelcomeActivity.this);
-        finish();
-    }
-
-    private void updateUI(int position) {
-        mTvDescription.setText(des[position]);
-        ObjectAnimator translationAnim = ObjectAnimator.ofFloat(mTvDescription, "translationX", -120, 0);
-        translationAnim.setDuration(ANIMATION_DURATION);
-        translationAnim.setInterpolator(new DecelerateInterpolator());
-        ObjectAnimator alphaAnimator1 = ObjectAnimator.ofFloat(mTvDescription, "alpha", 0, 1);
-        alphaAnimator1.setDuration(ANIMATION_DURATION);
-        AnimatorSet animatorSet = new AnimatorSet();
-        animatorSet.playTogether(translationAnim, alphaAnimator1);
-        animatorSet.start();
-
-        if (position == mViewPager.getList().size() - 1 && mTvStart.getVisibility() == View.GONE) {
-            mTvStart.setVisibility(View.VISIBLE);
-            ObjectAnimator
-                    .ofFloat(mTvStart, "alpha", 0, 1)
-                    .setDuration(ANIMATION_DURATION).start();
-        } else {
-            mTvStart.setVisibility(View.GONE);
-        }
-    }
-
-    private List<CustomBean> getData() {
-        List<CustomBean> list = new ArrayList<>();
-        for (int i = 0; i < mDrawableList.size(); i++) {
-            CustomBean customBean = new CustomBean();
-            customBean.setImageRes(mDrawableList.get(i));
-            customBean.setImageDescription(des[i]);
-            list.add(customBean);
-        }
-        return list;
-    }
-
-    @Override
-    public CustomPageViewHolder createViewHolder() {
-        CustomPageViewHolder customPageViewHolder = new CustomPageViewHolder();
-        customPageViewHolder.setOnSubViewClickListener((view, position) ->
-                Toast.makeText(WelcomeActivity.this, "Logo Clicked,Item: " + position, Toast.LENGTH_SHORT).show());
-        return customPageViewHolder;
-    }
-}

+ 115 - 0
app/src/main/java/com/example/zhpan/circleviewpager/activity/WelcomeActivity.kt

@@ -0,0 +1,115 @@
+package com.example.zhpan.circleviewpager.activity
+
+
+import android.animation.AnimatorSet
+import android.animation.ObjectAnimator
+import android.os.Bundle
+import android.view.View
+import android.view.animation.DecelerateInterpolator
+import android.widget.Toast
+import androidx.core.content.ContextCompat
+
+import com.example.zhpan.circleviewpager.R
+import com.example.zhpan.circleviewpager.bean.CustomBean
+import com.example.zhpan.circleviewpager.viewholder.CustomPageViewHolder
+import com.zhpan.bannerview.BannerViewPager
+import com.zhpan.bannerview.adapter.OnPageChangeListenerAdapter
+import com.zhpan.bannerview.constants.IndicatorSlideMode
+import com.zhpan.bannerview.constants.TransformerStyle
+import com.zhpan.bannerview.holder.HolderCreator
+import com.zhpan.bannerview.utils.BannerUtils
+
+import java.util.ArrayList
+import java.util.Random
+
+import butterknife.ButterKnife
+import butterknife.OnClick
+import kotlinx.android.synthetic.main.activity_welcome.*
+
+class WelcomeActivity : BaseDataActivity(), HolderCreator<CustomPageViewHolder> {
+
+    private lateinit var mViewPager: BannerViewPager<CustomBean, CustomPageViewHolder>
+
+    private val des = arrayOf("在这里\n你可以听到周围人的心声", "在这里\nTA会在下一秒遇见你", "在这里\n不再错过可以改变你一生的人")
+
+    private val transforms = intArrayOf(TransformerStyle.NONE, TransformerStyle.ACCORDION, TransformerStyle.STACK, TransformerStyle.DEPTH, TransformerStyle.ROTATE)
+
+    private val data: List<CustomBean>
+        get() {
+            val list = ArrayList<CustomBean>()
+            for (i in mDrawableList.indices) {
+                val customBean = CustomBean()
+                customBean.imageRes = mDrawableList[i]
+                customBean.imageDescription = des[i]
+                list.add(customBean)
+            }
+            return list
+        }
+
+    override fun onCreate(savedInstanceState: Bundle?) {
+        super.onCreate(savedInstanceState)
+        setContentView(R.layout.activity_welcome)
+        ButterKnife.bind(this)
+        setupViewPager()
+        updateUI(0)
+    }
+
+    private fun setupViewPager() {
+        mViewPager = findViewById(R.id.viewpager)
+        mViewPager.setAutoPlay(false)
+                .setCanLoop(false)
+                .setPageTransformerStyle(transforms[Random().nextInt(5)])
+                .setScrollDuration(ANIMATION_DURATION)
+                .setIndicatorMargin(0, 0, 0, BannerUtils.dp2px(100f))
+                .setIndicatorGap(resources.getDimension(R.dimen.dp_10).toInt())
+                .setIndicatorColor(ContextCompat.getColor(this, R.color.white),
+                        ContextCompat.getColor(this, R.color.white_alpha_75))
+                .setIndicatorSlideMode(IndicatorSlideMode.SMOOTH)
+                .setIndicatorRadius(resources.getDimension(R.dimen.dp_3).toInt(), resources.getDimension(R.dimen.dp_4_5).toInt())
+                .setOnPageChangeListener(object : OnPageChangeListenerAdapter() {
+                    override fun onPageSelected(position: Int) {
+                        updateUI(position)
+                    }
+                })
+                .setHolderCreator(this)
+                .create(data)
+    }
+
+    @OnClick(R.id.btn_start)
+    fun onClick(view: View) {
+        MainActivity.start(this)
+        finish()
+    }
+
+    private fun updateUI(position: Int) {
+        tv_describe!!.text = des[position]
+        val translationAnim = ObjectAnimator.ofFloat(tv_describe, "translationX", -120f, 0f)
+        translationAnim.duration = ANIMATION_DURATION.toLong()
+        translationAnim.interpolator = DecelerateInterpolator()
+        val alphaAnimator1 = ObjectAnimator.ofFloat(tv_describe, "alpha", 0f, 1f)
+        alphaAnimator1.duration = ANIMATION_DURATION.toLong()
+        val animatorSet = AnimatorSet()
+        animatorSet.playTogether(translationAnim, alphaAnimator1)
+        animatorSet.start()
+
+        if (position == mViewPager!!.list.size - 1 && btn_start!!.visibility == View.GONE) {
+            btn_start!!.visibility = View.VISIBLE
+            ObjectAnimator
+                    .ofFloat(btn_start, "alpha", 0f, 1f)
+                    .setDuration(ANIMATION_DURATION.toLong()).start()
+        } else {
+            btn_start!!.visibility = View.GONE
+        }
+    }
+
+    override fun createViewHolder(): CustomPageViewHolder {
+        val customPageViewHolder = CustomPageViewHolder()
+        customPageViewHolder.setOnSubViewClickListener { _, position -> Toast.makeText(this, "Logo Clicked,Item: $position", Toast.LENGTH_SHORT).show() }
+        return customPageViewHolder
+    }
+
+    companion object {
+
+        private const val ANIMATION_DURATION = 1300
+    }
+}

+ 9 - 20
app/src/main/java/com/example/zhpan/circleviewpager/fragment/HomeFragment.java

@@ -19,7 +19,8 @@ import com.example.zhpan.circleviewpager.viewholder.NetViewHolder;
 import com.scwang.smartrefresh.header.MaterialHeader;
 import com.scwang.smartrefresh.layout.SmartRefreshLayout;
 import com.zhpan.bannerview.BannerViewPager;
-import com.zhpan.bannerview.constants.IndicatorGravity;
+import com.zhpan.bannerview.constants.PageStyle;
+import com.zhpan.bannerview.utils.BannerUtils;
 import com.zhpan.idea.net.common.ResponseObserver;
 import com.zhpan.idea.utils.RxUtil;
 
@@ -106,16 +107,18 @@ public class HomeFragment extends BaseFragment {
 
     private void initBanner() {
         mBannerViewPager
-                .setInterval(3000)
-                .setCanLoop(false)
                 .setAutoPlay(true)
+                .setInterval(5000)
+                .setRevealWidth(BannerUtils.dp2px(10))
+                .setPageMargin(BannerUtils.dp2px(10))
+                .setPageStyle(PageStyle.MULTI_PAGE_OVERLAP)
                 .setIndicatorColor(getColor(R.color.red_normal_color), getColor(R.color.red_checked_color))
-                .setIndicatorGravity(IndicatorGravity.END)
-                .setScrollDuration(1000).setHolderCreator(NetViewHolder::new)
+                .setHolderCreator(NetViewHolder::new)
+                .setIndicatorMargin(0,0,0, (int) getResources().getDimension(R.dimen.dp_18))
                 .setOnPageClickListener(position -> {
                     BannerData bannerData = mBannerViewPager.getList().get(position);
                     Toast.makeText(mContext,
-                            "点击了position:" + position + " " + bannerData.getDesc(), Toast.LENGTH_SHORT).show();
+                            "点击了position:" + position + " " + bannerData.getTitle(), Toast.LENGTH_SHORT).show();
 
                 });
     }
@@ -125,18 +128,4 @@ public class HomeFragment extends BaseFragment {
         mBannerViewPager = view.findViewById(R.id.banner_view);
         return view;
     }
-
-    @Override
-    public void onStop() {
-        if (mBannerViewPager != null)
-            mBannerViewPager.stopLoop();
-        super.onStop();
-    }
-
-    @Override
-    public void onResume() {
-        if (mBannerViewPager != null)
-            mBannerViewPager.startLoop();
-        super.onResume();
-    }
 }

+ 1 - 14
app/src/main/java/com/example/zhpan/circleviewpager/fragment/IndicatorFragment.java

@@ -44,6 +44,7 @@ public class IndicatorFragment extends BaseFragment {
     @Override
     protected void initView(Bundle savedInstanceState, View view) {
         mViewPager.setIndicatorGap(BannerUtils.dp2px(6))
+                .setRoundCorner(BannerUtils.dp2px(6))
                 .setHolderCreator(() -> new ImageResourceViewHolder(0));
         initRadioGroup();
     }
@@ -117,18 +118,4 @@ public class IndicatorFragment extends BaseFragment {
     public void onClick(View view) {
         startActivity(new Intent(getActivity(), PhotoViewActivity.class));
     }
-
-    @Override
-    public void onStop() {
-        if (mViewPager != null)
-            mViewPager.stopLoop();
-        super.onStop();
-    }
-
-    @Override
-    public void onResume() {
-        super.onResume();
-        if (mViewPager != null)
-            mViewPager.stopLoop();
-    }
 }

+ 0 - 15
app/src/main/java/com/example/zhpan/circleviewpager/fragment/PageFragment.java

@@ -1,6 +1,5 @@
 package com.example.zhpan.circleviewpager.fragment;
 
-import android.graphics.Color;
 import android.os.Bundle;
 import android.view.LayoutInflater;
 import android.view.View;
@@ -105,18 +104,4 @@ public class PageFragment extends BaseFragment {
                 .setIndicatorView(indicatorView)
                 .create(mDrawableList);
     }
-
-    @Override
-    public void onStop() {
-        if (mViewPager != null)
-            mViewPager.stopLoop();
-        super.onStop();
-    }
-
-    @Override
-    public void onResume() {
-        super.onResume();
-        if (mViewPager != null)
-            mViewPager.startLoop();
-    }
 }

+ 4 - 0
app/src/main/java/com/example/zhpan/circleviewpager/net/ApiService.java

@@ -6,6 +6,7 @@ import java.util.List;
 
 import io.reactivex.Observable;
 import retrofit2.http.GET;
+import retrofit2.http.Headers;
 
 /**
  * <pre>
@@ -14,9 +15,12 @@ import retrofit2.http.GET;
  * </pre>
  */
 public interface ApiService {
+
+    @Headers("Cache-Control: public, max-age=" + 3600)
     @GET("banner/json")
     Observable<List<BannerData>> getBannerData();
 
+    @Headers("Cache-Control: public, max-age=" + 3600)
     @GET("article/list/0/json")
     Observable<ArticleWrapper> getArticle();
 }

+ 1 - 1
app/src/main/java/com/example/zhpan/circleviewpager/view/FigureIndicatorView.java

@@ -54,7 +54,7 @@ public class FigureIndicatorView extends BaseIndicatorView {
         canvas.drawCircle(getWidth() / 2, getHeight() / 2, radius, mPaint);
         mPaint.setColor(textColor);
         mPaint.setTextSize(textSize);
-        String text = currentPosition + 1 + "/" + pageSize;
+        String text = getCurrentPosition() + 1 + "/" + getPageSize();
         int textWidth = (int) mPaint.measureText(text);
         Paint.FontMetricsInt fontMetricsInt = mPaint.getFontMetricsInt();
         int baseline = (getMeasuredHeight() - fontMetricsInt.bottom + fontMetricsInt.top) / 2 - fontMetricsInt.top;

+ 7 - 4
app/src/main/java/com/example/zhpan/circleviewpager/viewholder/NetViewHolder.java

@@ -11,7 +11,9 @@ import com.example.zhpan.circleviewpager.R;
 import com.example.zhpan.circleviewpager.imageloader.ImageLoaderManager;
 import com.example.zhpan.circleviewpager.imageloader.ImageLoaderOptions;
 import com.example.zhpan.circleviewpager.net.BannerData;
+import com.example.zhpan.circleviewpager.view.CornerImageView;
 import com.zhpan.bannerview.holder.ViewHolder;
+import com.zhpan.bannerview.utils.BannerUtils;
 
 /**
  * <pre>
@@ -20,14 +22,15 @@ import com.zhpan.bannerview.holder.ViewHolder;
  * </pre>
  */
 public class NetViewHolder implements ViewHolder<BannerData> {
-    private ImageView mImageView;
-    private TextView mTextView;
+    private CornerImageView mImageView;
+//    private TextView mTextView;
 
     @Override
     public View createView(ViewGroup viewGroup, Context context, int position) {
         View view = LayoutInflater.from(context).inflate(R.layout.item_net, viewGroup, false);
         mImageView = view.findViewById(R.id.banner_image);
-        mTextView = view.findViewById(R.id.tv_describe);
+//        mTextView = view.findViewById(R.id.tv_describe);
+        mImageView.setRoundCorner(BannerUtils.dp2px(5));
         return view;
     }
 
@@ -35,6 +38,6 @@ public class NetViewHolder implements ViewHolder<BannerData> {
     public void onBind(Context context, BannerData data, int position, int size) {
         ImageLoaderOptions options = new ImageLoaderOptions.Builder().into(mImageView).load(data.getImagePath()).placeHolder(R.drawable.placeholder).build();
         ImageLoaderManager.getInstance().loadImage(options);
-        mTextView.setText(data.getTitle());
+//        mTextView.setText(data.getTitle());
     }
 }

+ 1 - 0
app/src/main/res/layout/activity_welcome.xml

@@ -30,6 +30,7 @@
         android:background="@drawable/bg_start"
         android:gravity="center_vertical"
         android:text="@string/start_now"
+        android:onClick="onClick"
         android:textColor="#FFFFFF"
         android:textSize="16sp"
         android:visibility="gone" />

+ 2 - 1
app/src/main/res/layout/item_header_view.xml

@@ -1,7 +1,8 @@
 <?xml version="1.0" encoding="utf-8"?>
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
-    android:layout_height="wrap_content">
+    android:layout_height="wrap_content"
+    android:orientation="vertical">
 
     <com.zhpan.bannerview.BannerViewPager
         android:id="@+id/banner_view"

+ 6 - 4
app/src/main/res/layout/item_net.xml

@@ -1,15 +1,17 @@
 <?xml version="1.0" encoding="utf-8"?>
 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
-    android:layout_height="wrap_content">
+    android:layout_height="wrap_content"
+    android:paddingTop="10dp"
+    android:paddingBottom="10dp">
 
-    <ImageView
+    <com.example.zhpan.circleviewpager.view.CornerImageView
         android:id="@+id/banner_image"
         android:layout_width="match_parent"
         android:layout_height="match_parent"
         android:scaleType="centerCrop" />
 
-    <LinearLayout
+    <!--<LinearLayout
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:layout_alignParentBottom="true"
@@ -27,6 +29,6 @@
             android:paddingBottom="5dp"
             android:textColor="#FFFFFF"
             android:textSize="16sp" />
-    </LinearLayout>
+    </LinearLayout>-->
 
 </RelativeLayout>

+ 190 - 251
bannerview/src/main/java/com/zhpan/bannerview/BannerViewPager.java

@@ -2,13 +2,12 @@ package com.zhpan.bannerview;
 
 import android.annotation.SuppressLint;
 import android.content.Context;
-import android.content.res.TypedArray;
-import android.graphics.Color;
 import android.os.Build;
 import android.os.Handler;
 
 import androidx.annotation.ColorInt;
 import androidx.annotation.Nullable;
+import androidx.viewpager.widget.PagerAdapter;
 import androidx.viewpager.widget.ViewPager;
 
 import android.util.AttributeSet;
@@ -26,9 +25,10 @@ import com.zhpan.bannerview.annotation.Visibility;
 import com.zhpan.bannerview.constants.IndicatorSlideMode;
 import com.zhpan.bannerview.constants.IndicatorStyle;
 import com.zhpan.bannerview.constants.PageStyle;
-import com.zhpan.bannerview.indicator.DashIndicatorView;
 import com.zhpan.bannerview.indicator.IIndicator;
 import com.zhpan.bannerview.indicator.IndicatorFactory;
+import com.zhpan.bannerview.manager.BannerManager;
+import com.zhpan.bannerview.manager.BannerOptions;
 import com.zhpan.bannerview.transform.pagestyle.ScaleInTransformer;
 import com.zhpan.bannerview.utils.BannerUtils;
 import com.zhpan.bannerview.adapter.BannerPagerAdapter;
@@ -36,7 +36,6 @@ import com.zhpan.bannerview.holder.HolderCreator;
 import com.zhpan.bannerview.holder.ViewHolder;
 import com.zhpan.bannerview.provider.ViewStyleSetter;
 import com.zhpan.bannerview.transform.PageTransformerFactory;
-import com.zhpan.bannerview.utils.PositionUtils;
 import com.zhpan.bannerview.view.CatchViewPager;
 
 import java.util.ArrayList;
@@ -55,87 +54,25 @@ import static com.zhpan.bannerview.transform.pagestyle.ScaleInTransformer.MAX_SC
 public class BannerViewPager<T, VH extends ViewHolder> extends RelativeLayout implements
         ViewPager.OnPageChangeListener {
 
-    private int interval;
-
     private int currentPosition;
 
-    private boolean isLooping;
-
-    private boolean isCanLoop;
-
-    private boolean isAutoPlay = false;
-
-    private int indicatorGravity;
-
-    private int indicatorNormalColor;
-
-    private int indicatorCheckedColor;
-
-    private int normalIndicatorWidth;
-
-    private int checkedIndicatorWidth;
-
     private OnPageClickListener mOnPageClickListener;
 
     private IIndicator mIndicatorView;
 
     private RelativeLayout mIndicatorLayout;
 
-    private int mPageMargin;
-
-    private int mRevealWidth;
-
-    private int mIndicatorStyle;
-
-    private int mIndicatorSlideMode;
-
     private CatchViewPager mViewPager;
 
     private List<T> mList;
 
-    private HolderCreator<VH> holderCreator;
-
-    private int indicatorGap;
+    private BannerManager mBannerManager;
 
-    private int indicatorHeight;
-
-    private boolean isCustomIndicator;
-
-    private int mPageStyle = PageStyle.NORMAL;
-
-    private IndicatorMargin mIndicatorMargin;
+    private HolderCreator<VH> holderCreator;
 
     private Handler mHandler = new Handler();
 
-    private Runnable mRunnable = new Runnable() {
-        @Override
-        public void run() {
-            if (mList.size() > 1) {
-                currentPosition = mViewPager.getCurrentItem() + 1;
-                if (isCanLoop) {
-                    if (currentPosition == MAX_VALUE - 1) {
-                        currentPosition = 0;
-                        mViewPager.setCurrentItem(currentPosition, false);
-                        mHandler.post(mRunnable);
-                    } else {
-                        mViewPager.setCurrentItem(currentPosition);
-                        mHandler.postDelayed(mRunnable, interval);
-                    }
-                } else {
-                    if (currentPosition >= MAX_VALUE) {
-                        stopLoop();
-                    } else {
-                        mViewPager.setCurrentItem(currentPosition);
-                        mHandler.postDelayed(mRunnable, interval);
-                    }
-                }
-            }
-        }
-    };
-    private int mIndicatorVisibility;
-    private int mScrollDuration;
-    private int mRoundCorner;
-    private boolean disableTouchScroll;
+    private Runnable mRunnable = this::handlePosition;
 
     public BannerViewPager(Context context) {
         this(context, null);
@@ -147,11 +84,12 @@ public class BannerViewPager<T, VH extends ViewHolder> extends RelativeLayout im
 
     public BannerViewPager(Context context, AttributeSet attrs, int defStyleAttr) {
         super(context, attrs, defStyleAttr);
-        init(attrs);
+        init(context, attrs);
     }
 
-    private void init(AttributeSet attrs) {
-        initAttrs(attrs);
+    private void init(Context context, AttributeSet attrs) {
+        mBannerManager = new BannerManager();
+        mBannerManager.initAttrs(context, attrs);
         initView();
     }
 
@@ -162,79 +100,18 @@ public class BannerViewPager<T, VH extends ViewHolder> extends RelativeLayout im
         mList = new ArrayList<>();
     }
 
-    private void initAttrs(AttributeSet attrs) {
-        if (attrs != null) {
-            TypedArray typedArray =
-                    getContext().obtainStyledAttributes(attrs, R.styleable.BannerViewPager);
-
-            interval = typedArray.getInteger(R.styleable.BannerViewPager_bvp_interval, 3000);
-            indicatorCheckedColor =
-                    typedArray.getColor(R.styleable.BannerViewPager_bvp_indicator_checked_color,
-                            Color.parseColor("#8C18171C"));
-            indicatorNormalColor =
-                    typedArray.getColor(R.styleable.BannerViewPager_bvp_indicator_normal_color,
-                            Color.parseColor("#8C6C6D72"));
-            normalIndicatorWidth = (int) typedArray.getDimension(R.styleable.BannerViewPager_bvp_indicator_radius,
-                    BannerUtils.dp2px(8));
-            isAutoPlay = typedArray.getBoolean(R.styleable.BannerViewPager_bvp_auto_play, true);
-            isCanLoop = typedArray.getBoolean(R.styleable.BannerViewPager_bvp_can_loop, true);
-            mPageMargin = (int) typedArray.getDimension(R.styleable.BannerViewPager_bvp_page_margin, 0);
-            mRoundCorner = (int) typedArray.getDimension(R.styleable.BannerViewPager_bvp_round_corner, 0);
-            mRevealWidth = (int) typedArray.getDimension(R.styleable.BannerViewPager_bvp_reveal_width, 0);
-            indicatorGravity = typedArray.getInt(R.styleable.BannerViewPager_bvp_indicator_gravity, 0);
-            mPageStyle = typedArray.getInt(R.styleable.BannerViewPager_bvp_page_style, 0);
-            mIndicatorStyle = typedArray.getInt(R.styleable.BannerViewPager_bvp_indicator_style, 0);
-            mIndicatorSlideMode = typedArray.getInt(R.styleable.BannerViewPager_bvp_indicator_slide_mode, 0);
-            mIndicatorVisibility = typedArray.getInt(R.styleable.BannerViewPager_bvp_indicator_visibility, 0);
-            mScrollDuration = typedArray.getInt(R.styleable.BannerViewPager_bvp_scroll_duration, 800);
-            typedArray.recycle();
-            indicatorGap = normalIndicatorWidth;
-            indicatorHeight = normalIndicatorWidth / 2;
-            checkedIndicatorWidth = normalIndicatorWidth;
-        }
-    }
-
-    private void initBannerData(List<T> list) {
-        if (list != null) {
-            mList.clear();
-            mList.addAll(list);
-            if (mList.size() > 0) {
-                if (mList.size() > 1) {
-                    if (isCustomIndicator && null != mIndicatorView) {
-                        initIndicator(mIndicatorView);
-                    } else {
-                        initIndicator(IndicatorFactory.createIndicatorView(getContext(), mIndicatorStyle));
-                    }
-                }
-                if (isCanLoop) {
-//                    currentPosition = mPageStyle == PageStyle.NORMAL ? 1 : 2;
-                    currentPosition = MAX_VALUE / 2 - ((MAX_VALUE / 2) % mList.size()) + 1;
-                }
-                setupViewPager();
-                setIndicatorValues();
-            }
-        }
+    @Override
+    protected void onDetachedFromWindow() {
+        stopLoop();
+        super.onDetachedFromWindow();
     }
 
-
-    private void setIndicatorValues() {
-        if (null != mIndicatorView) {
-            mIndicatorView.setPageSize(mList.size());
-            mIndicatorView.setCheckedColor(indicatorCheckedColor);
-            mIndicatorView.setNormalColor(indicatorNormalColor);
-            mIndicatorView.setIndicatorGap(indicatorGap);
-            mIndicatorView.setSlideMode(mIndicatorSlideMode);
-            mIndicatorView.setIndicatorWidth(normalIndicatorWidth, checkedIndicatorWidth);
-            if (mIndicatorView instanceof DashIndicatorView) {
-                ((DashIndicatorView) mIndicatorView).setSliderHeight(indicatorHeight);
-            }
-            mIndicatorView.notifyDataChanged();
-        }
+    @Override
+    protected void onAttachedToWindow() {
+        super.onAttachedToWindow();
+        startLoop();
     }
 
-    /**
-     * 设置触摸事件,当滑动或者触摸时停止自动轮播
-     */
     @SuppressLint("ClickableViewAccessibility")
     private void setTouchListener() {
         mViewPager.setOnTouchListener((v, event) -> {
@@ -242,12 +119,12 @@ public class BannerViewPager<T, VH extends ViewHolder> extends RelativeLayout im
             switch (action) {
                 case MotionEvent.ACTION_DOWN:
                 case MotionEvent.ACTION_MOVE:
-                    isLooping = true;
+                    setLooping(true);
                     stopLoop();
                     break;
                 case MotionEvent.ACTION_UP:
                 case MotionEvent.ACTION_CANCEL:
-                    isLooping = false;
+                    setLooping(false);
                     startLoop();
                 default:
                     break;
@@ -256,8 +133,87 @@ public class BannerViewPager<T, VH extends ViewHolder> extends RelativeLayout im
         });
     }
 
+    @Override
+    public void onPageSelected(int position) {
+        currentPosition = BannerUtils.getRealPosition(isCanLoop(), position, mList.size());
+        if (mOnPageChangeListener != null)
+            mOnPageChangeListener.onPageSelected(currentPosition);
+        if (mIndicatorView != null) {
+            mIndicatorView.onPageSelected(currentPosition);
+        }
+    }
+
+    @Override
+    public void onPageScrollStateChanged(int state) {
+        if (mIndicatorView != null) {
+            mIndicatorView.onPageScrollStateChanged(state);
+        }
+        if (mOnPageChangeListener != null) {
+            mOnPageChangeListener.onPageScrollStateChanged(state);
+        }
+    }
+
+    @Override
+    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
+        if (mOnPageChangeListener != null) {
+            mOnPageChangeListener.onPageScrolled(BannerUtils.getRealPosition(isCanLoop(), position, mList.size()),
+                    positionOffset, positionOffsetPixels);
+        }
+        if (mIndicatorView != null)
+            mIndicatorView.onPageScrolled(BannerUtils.getRealPosition(isCanLoop(), position, mList.size()),
+                    positionOffset, positionOffsetPixels);
+    }
+
+    private void handlePosition() {
+        if (mList.size() > 1) {
+            currentPosition = mViewPager.getCurrentItem() + 1;
+            if (isCanLoop()) {
+                if (currentPosition == MAX_VALUE - 1) {
+                    currentPosition = 0;
+                    mViewPager.setCurrentItem(currentPosition, false);
+                    mHandler.post(mRunnable);
+                } else {
+                    mViewPager.setCurrentItem(currentPosition);
+                    mHandler.postDelayed(mRunnable, getInterval());
+                }
+            } else {
+                if (currentPosition >= MAX_VALUE) {
+                    stopLoop();
+                } else {
+                    mViewPager.setCurrentItem(currentPosition);
+                    mHandler.postDelayed(mRunnable, getInterval());
+                }
+            }
+        }
+    }
+
+    private void initBannerData(List<T> list) {
+        if (list != null) {
+            mList.clear();
+            mList.addAll(list);
+            if (mList.size() > 0) {
+                if (mList.size() > 1) setIndicatorValues();
+                if (isCanLoop())
+                    currentPosition = MAX_VALUE / 2 - ((MAX_VALUE / 2) % mList.size()) + 1;
+                setupViewPager();
+                initRoundCorner();
+            }
+        }
+    }
+
+    private void setIndicatorValues() {
+        BannerOptions bannerOptions = mBannerManager.bannerOptions();
+        if (bannerOptions.isCustomIndicator() && null != mIndicatorView) {
+            initIndicator(mIndicatorView);
+        } else {
+            initIndicator(IndicatorFactory.createIndicatorView(getContext(), bannerOptions.getIndicatorStyle()));
+        }
+        mIndicatorView.setIndicatorOptions(bannerOptions.getIndicatorOptions());
+        mIndicatorView.setPageSize(mList.size());
+    }
+
     private void initIndicator(IIndicator indicatorView) {
-        mIndicatorLayout.setVisibility(mIndicatorVisibility);
+        mIndicatorLayout.setVisibility(mBannerManager.bannerOptions().getIndicatorVisibility());
         mIndicatorView = indicatorView;
         if (((View) mIndicatorView).getParent() == null) {
             mIndicatorLayout.removeAllViews();
@@ -270,7 +226,7 @@ public class BannerViewPager<T, VH extends ViewHolder> extends RelativeLayout im
     private void initIndicatorGravity() {
         RelativeLayout.LayoutParams layoutParams =
                 (RelativeLayout.LayoutParams) ((View) mIndicatorView).getLayoutParams();
-        switch (indicatorGravity) {
+        switch (mBannerManager.bannerOptions().getIndicatorGravity()) {
             case CENTER:
                 layoutParams.addRule(RelativeLayout.CENTER_HORIZONTAL);
                 break;
@@ -285,32 +241,34 @@ public class BannerViewPager<T, VH extends ViewHolder> extends RelativeLayout im
 
     private void initIndicatorViewMargin() {
         ViewGroup.MarginLayoutParams layoutParams = (MarginLayoutParams) ((View) mIndicatorView).getLayoutParams();
-        if (mIndicatorMargin == null) {
+        BannerOptions.IndicatorMargin indicatorMargin = mBannerManager.bannerOptions().getIndicatorMargin();
+        if (indicatorMargin == null) {
             int dp10 = BannerUtils.dp2px(10);
             layoutParams.setMargins(dp10, dp10, dp10, dp10);
         } else {
-            layoutParams.setMargins(mIndicatorMargin.left, mIndicatorMargin.top,
-                    mIndicatorMargin.right, mIndicatorMargin.bottom);
+            layoutParams.setMargins(indicatorMargin.getLeft(), indicatorMargin.getTop(),
+                    indicatorMargin.getRight(), indicatorMargin.getBottom());
+        }
+    }
+
+    private void initRoundCorner() {
+        int roundCorner = mBannerManager.bannerOptions().getRoundCorner();
+        if (roundCorner > 0 && Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
+            ViewStyleSetter viewStyleSetter = new ViewStyleSetter(this);
+            viewStyleSetter.setRoundCorner(roundCorner);
         }
     }
 
     private void setupViewPager() {
         if (holderCreator != null) {
             removeAllViews();
-            BannerPagerAdapter<T, VH> bannerPagerAdapter =
-                    new BannerPagerAdapter<>(mList, holderCreator);
-            bannerPagerAdapter.setCanLoop(isCanLoop);
-            bannerPagerAdapter.setPageClickListener(position -> {
-                if (mOnPageClickListener != null) {
-                    mOnPageClickListener.onPageClick(position);
-                }
-            });
-
-            mViewPager.setAdapter(bannerPagerAdapter);
+            mViewPager.setAdapter(getPagerAdapter());
             mViewPager.setCurrentItem(currentPosition);
             mViewPager.addOnPageChangeListener(this);
-            mViewPager.setScrollDuration(mScrollDuration);
-            mViewPager.disableTouchScroll(disableTouchScroll);
+            BannerOptions bannerOptions = mBannerManager.bannerOptions();
+            mViewPager.setScrollDuration(bannerOptions.getScrollDuration());
+            mViewPager.disableTouchScroll(bannerOptions.isDisableTouchScroll());
+            mViewPager.setFirstLayout(true);
             addView(mViewPager);
             addView(mIndicatorLayout);
             initPageStyle();
@@ -319,15 +277,22 @@ public class BannerViewPager<T, VH extends ViewHolder> extends RelativeLayout im
         } else {
             throw new NullPointerException("You must set HolderCreator for BannerViewPager");
         }
+    }
 
-        if (mRoundCorner > 0 && Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
-            ViewStyleSetter viewStyleSetter = new ViewStyleSetter(this);
-            viewStyleSetter.setRoundCorner(mRoundCorner);
-        }
+    private PagerAdapter getPagerAdapter() {
+        BannerPagerAdapter<T, VH> bannerPagerAdapter =
+                new BannerPagerAdapter<>(mList, holderCreator);
+        bannerPagerAdapter.setCanLoop(isCanLoop());
+        bannerPagerAdapter.setPageClickListener(position -> {
+            if (mOnPageClickListener != null) {
+                mOnPageClickListener.onPageClick(position);
+            }
+        });
+        return bannerPagerAdapter;
     }
 
     private void initPageStyle() {
-        switch (mPageStyle) {
+        switch (mBannerManager.bannerOptions().getPageStyle()) {
             case PageStyle.MULTI_PAGE:
                 setMultiPageStyle(false, MAX_SCALE);
                 break;
@@ -341,47 +306,35 @@ public class BannerViewPager<T, VH extends ViewHolder> extends RelativeLayout im
     }
 
     private void setMultiPageStyle(boolean overlap, float scale) {
-        mPageMargin = mPageMargin == 0 ? BannerUtils.dp2px(20) : mPageMargin;
-        mRevealWidth = mRevealWidth == 0 ? BannerUtils.dp2px(20) : mRevealWidth;
         setClipChildren(false);
         ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) mViewPager.getLayoutParams();
-        params.leftMargin = mPageMargin + mRevealWidth;
-        params.rightMargin = mPageMargin + mRevealWidth;
+        BannerOptions bannerOptions = mBannerManager.bannerOptions();
+        params.leftMargin = bannerOptions.getPageMargin() + bannerOptions.getRevealWidth();
+        params.rightMargin = params.leftMargin;
         mViewPager.setOverlapStyle(overlap);
-        mViewPager.setPageMargin(overlap ? -mPageMargin : mPageMargin);
+        mViewPager.setPageMargin(overlap ? -bannerOptions.getPageMargin() : bannerOptions.getPageMargin());
         mViewPager.setOffscreenPageLimit(2);
         setPageTransformer(new ScaleInTransformer(scale));
     }
 
-    @Override
-    public void onPageSelected(int position) {
-        currentPosition = PositionUtils.getRealPosition(isCanLoop, position, mList.size());
-        if (mOnPageChangeListener != null)
-            mOnPageChangeListener.onPageSelected(currentPosition);
-        if (mIndicatorView != null) {
-            mIndicatorView.onPageSelected(currentPosition);
-        }
+    private int getInterval() {
+        return mBannerManager.bannerOptions().getInterval();
     }
 
-    @Override
-    public void onPageScrollStateChanged(int state) {
-        if (mIndicatorView != null) {
-            mIndicatorView.onPageScrollStateChanged(state);
-        }
-        if (mOnPageChangeListener != null) {
-            mOnPageChangeListener.onPageScrollStateChanged(state);
-        }
+    private boolean isAutoPlay() {
+        return mBannerManager.bannerOptions().isAutoPlay();
     }
 
-    @Override
-    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
-        if (mOnPageChangeListener != null) {
-            mOnPageChangeListener.onPageScrolled(PositionUtils.getRealPosition(isCanLoop, position, mList.size()),
-                    positionOffset, positionOffsetPixels);
-        }
-        if (mIndicatorView != null)
-            mIndicatorView.onPageScrolled(PositionUtils.getRealPosition(isCanLoop, position, mList.size()),
-                    positionOffset, positionOffsetPixels);
+    private boolean isLooping() {
+        return mBannerManager.bannerOptions().isLooping();
+    }
+
+    private void setLooping(boolean looping) {
+        mBannerManager.bannerOptions().setLooping(looping);
+    }
+
+    private boolean isCanLoop() {
+        return mBannerManager.bannerOptions().isCanLoop();
     }
 
     /**
@@ -395,9 +348,9 @@ public class BannerViewPager<T, VH extends ViewHolder> extends RelativeLayout im
      * 开启轮播
      */
     public void startLoop() {
-        if (!isLooping && isAutoPlay && mList.size() > 1) {
-            mHandler.postDelayed(mRunnable, interval);
-            isLooping = true;
+        if (!isLooping() && isAutoPlay() && mList.size() > 1) {
+            mHandler.postDelayed(mRunnable, getInterval());
+            setLooping(true);
         }
     }
 
@@ -405,9 +358,9 @@ public class BannerViewPager<T, VH extends ViewHolder> extends RelativeLayout im
      * 停止轮播
      */
     public void stopLoop() {
-        if (isLooping) {
+        if (isLooping()) {
             mHandler.removeCallbacks(mRunnable);
-            isLooping = false;
+            setLooping(false);
         }
     }
 
@@ -428,20 +381,19 @@ public class BannerViewPager<T, VH extends ViewHolder> extends RelativeLayout im
      * @param radius 圆角大小
      */
     public BannerViewPager<T, VH> setRoundCorner(int radius) {
-        mRoundCorner = radius;
+        mBannerManager.bannerOptions().setRoundCorner(radius);
         return this;
     }
 
-
     /**
      * 设置是否自动轮播
      *
      * @param autoPlay 是否自动轮播
      */
     public BannerViewPager<T, VH> setAutoPlay(boolean autoPlay) {
-        isAutoPlay = autoPlay;
-        if (isAutoPlay) {
-            isCanLoop = true;
+        mBannerManager.bannerOptions().setAutoPlay(autoPlay);
+        if (isAutoPlay()) {
+            mBannerManager.bannerOptions().setCanLoop(true);
         }
         return this;
     }
@@ -452,9 +404,9 @@ public class BannerViewPager<T, VH extends ViewHolder> extends RelativeLayout im
      * @param canLoop 是否可以循环
      */
     public BannerViewPager<T, VH> setCanLoop(boolean canLoop) {
-        isCanLoop = canLoop;
+        mBannerManager.bannerOptions().setCanLoop(canLoop);
         if (!canLoop) {
-            isAutoPlay = false;
+            mBannerManager.bannerOptions().setAutoPlay(false);
         }
         return this;
     }
@@ -465,7 +417,7 @@ public class BannerViewPager<T, VH extends ViewHolder> extends RelativeLayout im
      * @param interval 自动轮播时间间隔 单位毫秒ms
      */
     public BannerViewPager<T, VH> setInterval(int interval) {
-        this.interval = interval;
+        mBannerManager.bannerOptions().setInterval(interval);
         return this;
     }
 
@@ -501,7 +453,7 @@ public class BannerViewPager<T, VH extends ViewHolder> extends RelativeLayout im
      * @param scrollDuration page滚动时间
      */
     public BannerViewPager<T, VH> setScrollDuration(int scrollDuration) {
-        mScrollDuration = scrollDuration;
+        mBannerManager.bannerOptions().setScrollDuration(scrollDuration);
         return this;
     }
 
@@ -511,8 +463,8 @@ public class BannerViewPager<T, VH extends ViewHolder> extends RelativeLayout im
      */
     public BannerViewPager<T, VH> setIndicatorColor(@ColorInt int normalColor,
                                                     @ColorInt int checkedColor) {
-        indicatorCheckedColor = checkedColor;
-        indicatorNormalColor = normalColor;
+        mBannerManager.bannerOptions().setIndicatorCheckedColor(checkedColor);
+        mBannerManager.bannerOptions().setIndicatorNormalColor(normalColor);
         return this;
     }
 
@@ -522,8 +474,7 @@ public class BannerViewPager<T, VH extends ViewHolder> extends RelativeLayout im
      * @param radius 指示器圆点半径
      */
     public BannerViewPager<T, VH> setIndicatorRadius(int radius) {
-        this.normalIndicatorWidth = radius * 2;
-        this.checkedIndicatorWidth = radius * 2;
+        setIndicatorRadius(radius,radius);
         return this;
     }
 
@@ -534,8 +485,8 @@ public class BannerViewPager<T, VH extends ViewHolder> extends RelativeLayout im
      * @param checkedRadius 选中时半径
      */
     public BannerViewPager<T, VH> setIndicatorRadius(int normalRadius, int checkedRadius) {
-        this.normalIndicatorWidth = normalRadius * 2;
-        this.checkedIndicatorWidth = checkedRadius * 2;
+        mBannerManager.bannerOptions().setNormalIndicatorWidth(normalRadius * 2);
+        mBannerManager.bannerOptions().setCheckedIndicatorWidth(checkedRadius * 2);
         return this;
     }
 
@@ -546,8 +497,7 @@ public class BannerViewPager<T, VH extends ViewHolder> extends RelativeLayout im
      * @param indicatorWidth 单个Indicator宽度/直径
      */
     public BannerViewPager<T, VH> setIndicatorWidth(int indicatorWidth) {
-        this.normalIndicatorWidth = indicatorWidth;
-        this.checkedIndicatorWidth = indicatorWidth;
+        setIndicatorWidth(indicatorWidth, indicatorWidth);
         return this;
     }
 
@@ -559,13 +509,13 @@ public class BannerViewPager<T, VH extends ViewHolder> extends RelativeLayout im
      * @param checkWidth  选中时宽度/直径
      */
     public BannerViewPager<T, VH> setIndicatorWidth(int normalWidth, int checkWidth) {
-        this.normalIndicatorWidth = normalWidth;
-        this.checkedIndicatorWidth = checkWidth;
+        mBannerManager.bannerOptions().setNormalIndicatorWidth(normalWidth);
+        mBannerManager.bannerOptions().setCheckedIndicatorWidth(checkWidth);
         return this;
     }
 
     public BannerViewPager<T, VH> setIndicatorHeight(int indicatorHeight) {
-        this.indicatorHeight = indicatorHeight;
+        mBannerManager.bannerOptions().setIndicatorHeight(indicatorHeight);
         return this;
     }
 
@@ -576,7 +526,7 @@ public class BannerViewPager<T, VH extends ViewHolder> extends RelativeLayout im
      * @return BannerViewPager
      */
     public BannerViewPager<T, VH> setIndicatorGap(int indicatorGap) {
-        this.indicatorGap = indicatorGap;
+        mBannerManager.bannerOptions().setIndicatorGap(indicatorGap);
         return this;
     }
 
@@ -591,7 +541,7 @@ public class BannerViewPager<T, VH extends ViewHolder> extends RelativeLayout im
     }
 
     public BannerViewPager<T, VH> setIndicatorVisibility(@Visibility int visibility) {
-        mIndicatorVisibility = visibility;
+        mBannerManager.bannerOptions().setIndicatorVisibility(visibility);
         return this;
     }
 
@@ -604,7 +554,7 @@ public class BannerViewPager<T, VH extends ViewHolder> extends RelativeLayout im
      *                {@link com.zhpan.bannerview.constants.IndicatorGravity#END}
      */
     public BannerViewPager<T, VH> setIndicatorGravity(@AIndicatorGravity int gravity) {
-        this.indicatorGravity = gravity;
+        mBannerManager.bannerOptions().setIndicatorGravity(gravity);
         return this;
     }
 
@@ -616,7 +566,7 @@ public class BannerViewPager<T, VH extends ViewHolder> extends RelativeLayout im
      * @see com.zhpan.bannerview.constants.IndicatorSlideMode#SMOOTH
      */
     public BannerViewPager<T, VH> setIndicatorSlideMode(@AIndicatorSlideMode int slideMode) {
-        mIndicatorSlideMode = slideMode;
+        mBannerManager.bannerOptions().setIndicatorSlideMode(slideMode);
         return this;
     }
 
@@ -629,7 +579,7 @@ public class BannerViewPager<T, VH extends ViewHolder> extends RelativeLayout im
      */
     public BannerViewPager<T, VH> setIndicatorView(IIndicator customIndicator) {
         if (customIndicator instanceof View) {
-            isCustomIndicator = true;
+            mBannerManager.bannerOptions().setCustomIndicator(true);
             mIndicatorView = customIndicator;
         }
         return this;
@@ -643,7 +593,7 @@ public class BannerViewPager<T, VH extends ViewHolder> extends RelativeLayout im
      *                       {@link IndicatorStyle#DASH}
      */
     public BannerViewPager<T, VH> setIndicatorStyle(@AIndicatorStyle int indicatorStyle) {
-        mIndicatorStyle = indicatorStyle;
+        mBannerManager.bannerOptions().setIndicatorStyle(indicatorStyle);
         return this;
     }
 
@@ -671,7 +621,7 @@ public class BannerViewPager<T, VH extends ViewHolder> extends RelativeLayout im
      * @param item Item index to select
      */
     public void setCurrentItem(int item) {
-        mViewPager.setCurrentItem(isCanLoop ? MAX_VALUE / 2 - ((MAX_VALUE / 2) % mList.size()) + 1 + item : item);
+        mViewPager.setCurrentItem(isCanLoop() ? MAX_VALUE / 2 - ((MAX_VALUE / 2) % mList.size()) + 1 + item : item);
     }
 
     /**
@@ -681,7 +631,7 @@ public class BannerViewPager<T, VH extends ViewHolder> extends RelativeLayout im
      * @param smoothScroll True to smoothly scroll to the new item, false to transition immediately
      */
     public void setCurrentItem(int item, boolean smoothScroll) {
-        mViewPager.setCurrentItem(isCanLoop ? MAX_VALUE / 2 - ((MAX_VALUE / 2) % mList.size()) + 1 + item : item, smoothScroll);
+        mViewPager.setCurrentItem(isCanLoop() ? MAX_VALUE / 2 - ((MAX_VALUE / 2) % mList.size()) + 1 + item : item, smoothScroll);
     }
 
     /**
@@ -692,7 +642,7 @@ public class BannerViewPager<T, VH extends ViewHolder> extends RelativeLayout im
      * @return BannerViewPager
      */
     public BannerViewPager<T, VH> setPageStyle(@APageStyle int pageStyle) {
-        mPageStyle = pageStyle;
+        mBannerManager.bannerOptions().setPageStyle(pageStyle);
         return this;
     }
 
@@ -703,7 +653,7 @@ public class BannerViewPager<T, VH extends ViewHolder> extends RelativeLayout im
      * @return BannerViewPager
      */
     public BannerViewPager<T, VH> setPageMargin(int pageMargin) {
-        mPageMargin = pageMargin;
+        mBannerManager.bannerOptions().setPageMargin(pageMargin);
         mViewPager.setPageMargin(pageMargin);
         return this;
     }
@@ -712,7 +662,7 @@ public class BannerViewPager<T, VH extends ViewHolder> extends RelativeLayout im
      * @param revealWidth 一屏多页模式下两边页面显露出来的宽度
      */
     public BannerViewPager<T, VH> setRevealWidth(int revealWidth) {
-        mRevealWidth = revealWidth;
+        mBannerManager.bannerOptions().setRevealWidth(revealWidth);
         return this;
     }
 
@@ -731,29 +681,15 @@ public class BannerViewPager<T, VH extends ViewHolder> extends RelativeLayout im
     }
 
     public BannerViewPager<T, VH> setIndicatorMargin(int left, int top, int right, int bottom) {
-        mIndicatorMargin = new IndicatorMargin();
-        mIndicatorMargin.bottom = bottom;
-        mIndicatorMargin.left = left;
-        mIndicatorMargin.top = top;
-        mIndicatorMargin.right = right;
+        mBannerManager.bannerOptions().setIndicatorMargin(left, top, right, bottom);
         return this;
     }
 
     public BannerViewPager<T, VH> disableTouchScroll(boolean disableTouchScroll) {
-        this.disableTouchScroll = disableTouchScroll;
+        mBannerManager.bannerOptions().setDisableTouchScroll(disableTouchScroll);
         return this;
     }
 
-
-    /**
-     * 仅供demo使用
-     */
-//    @Deprecated
-//    public void resetIndicator() {
-//        isCustomIndicator = false;
-//        mIndicatorView = null;
-//    }
-
     /**
      * 页面点击事件接口
      */
@@ -761,14 +697,17 @@ public class BannerViewPager<T, VH extends ViewHolder> extends RelativeLayout im
         void onPageClick(int position);
     }
 
-    private static class IndicatorMargin {
-        private int left, right, top, bottom;
-    }
-
     private ViewPager.OnPageChangeListener mOnPageChangeListener;
 
     public BannerViewPager<T, VH> setOnPageChangeListener(ViewPager.OnPageChangeListener onPageChangeListener) {
         mOnPageChangeListener = onPageChangeListener;
         return this;
     }
+
+    //  仅供demo使用
+//    @Deprecated
+//    public void resetIndicator() {
+//        mBannerManager.bannerOptions().setCustomIndicator(false);
+//        mIndicatorView = null;
+//    }
 }

+ 3 - 3
bannerview/src/main/java/com/zhpan/bannerview/adapter/BannerPagerAdapter.java

@@ -8,7 +8,7 @@ import android.view.ViewGroup;
 
 import com.zhpan.bannerview.holder.HolderCreator;
 import com.zhpan.bannerview.holder.ViewHolder;
-import com.zhpan.bannerview.utils.PositionUtils;
+import com.zhpan.bannerview.utils.BannerUtils;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -53,7 +53,7 @@ public class BannerPagerAdapter<T, VH extends ViewHolder> extends PagerAdapter {
     @Override
     public @NonNull
     Object instantiateItem(@NonNull final ViewGroup container, final int position) {
-        View itemView = findViewByPosition(container, PositionUtils.getRealPosition(isCanLoop, position, mList.size()));
+        View itemView = findViewByPosition(container, BannerUtils.getRealPosition(isCanLoop, position, mList.size()));
         container.addView(itemView);
         return itemView;
     }
@@ -74,7 +74,7 @@ public class BannerPagerAdapter<T, VH extends ViewHolder> extends PagerAdapter {
     private View getView(final int position, ViewGroup container) {
         ViewHolder<T> holder = holderCreator.createViewHolder();
         if (holder == null) {
-            throw new NullPointerException("can not return a null holder");
+            throw new NullPointerException("Can not return a null holder");
         }
         return createView(holder, position, container);
     }

+ 0 - 5
bannerview/src/main/java/com/zhpan/bannerview/annotation/Visibility.java

@@ -9,11 +9,6 @@ import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.lang.annotation.Target;
 
-import static com.zhpan.bannerview.constants.IndicatorGravity.CENTER;
-import static com.zhpan.bannerview.constants.IndicatorGravity.END;
-import static com.zhpan.bannerview.constants.IndicatorGravity.START;
-
-
 /**
  * <pre>
  *   Created by zhangpan on 2019-11-12.

+ 2 - 2
bannerview/src/main/java/com/zhpan/bannerview/constants/IndicatorGravity.java

@@ -8,6 +8,6 @@ package com.zhpan.bannerview.constants;
  */
 public interface IndicatorGravity {
     int CENTER = 0;
-    int START = 1;
-    int END = 2;
+    int START = 1 << 1;
+    int END = 1 << 2;
 }

+ 1 - 1
bannerview/src/main/java/com/zhpan/bannerview/constants/IndicatorSlideMode.java

@@ -8,5 +8,5 @@ package com.zhpan.bannerview.constants;
  */
 public interface IndicatorSlideMode {
     int NORMAL = 0;
-    int SMOOTH = 1;
+    int SMOOTH = 1 << 1;
 }

+ 1 - 1
bannerview/src/main/java/com/zhpan/bannerview/constants/IndicatorStyle.java

@@ -8,5 +8,5 @@ package com.zhpan.bannerview.constants;
  */
 public interface IndicatorStyle {
     int CIRCLE = 0;
-    int DASH = 1;
+    int DASH = 1 << 1;
 }

+ 3 - 3
bannerview/src/main/java/com/zhpan/bannerview/constants/PageStyle.java

@@ -10,9 +10,9 @@ public interface PageStyle {
 
     int NORMAL = 0;
 
-    int MULTI_PAGE = 1;
+    int MULTI_PAGE = 1 << 1;
 
-    int MULTI_PAGE_OVERLAP = 2;
+    int MULTI_PAGE_OVERLAP = 1 << 2;
 
-    int MULTI_PAGE_SCALE = 3;
+    int MULTI_PAGE_SCALE = 1 << 3;
 }

+ 4 - 4
bannerview/src/main/java/com/zhpan/bannerview/constants/TransformerStyle.java

@@ -2,8 +2,8 @@ package com.zhpan.bannerview.constants;
 
 public interface TransformerStyle {
     int NONE = 0;
-    int DEPTH = 1;
-    int STACK = 2;
-    int ACCORDION = 3;
-    int ROTATE = 4;
+    int DEPTH = 1 << 1;
+    int STACK = 1 << 2;
+    int ACCORDION = 1 << 3;
+    int ROTATE = 1 << 4;
 }

+ 1 - 1
bannerview/src/main/java/com/zhpan/bannerview/holder/ViewHolder.java

@@ -11,7 +11,7 @@ import android.view.ViewGroup;
 
 public interface ViewHolder<T> {
     View createView(ViewGroup viewGroup,Context context, int position);
-   // void onBind(Context context, int position, T data);
+
     /**
      * @param context context
      * @param data 实体类对象

+ 97 - 77
bannerview/src/main/java/com/zhpan/bannerview/indicator/BaseIndicatorView.java

@@ -1,7 +1,6 @@
 package com.zhpan.bannerview.indicator;
 
 import android.content.Context;
-import android.graphics.Color;
 import android.graphics.Paint;
 import android.util.AttributeSet;
 import android.view.View;
@@ -10,7 +9,7 @@ import androidx.annotation.Nullable;
 
 import com.zhpan.bannerview.annotation.AIndicatorSlideMode;
 import com.zhpan.bannerview.constants.IndicatorSlideMode;
-import com.zhpan.bannerview.utils.BannerUtils;
+import com.zhpan.bannerview.manager.IndicatorOptions;
 
 /**
  * <pre>
@@ -19,49 +18,8 @@ import com.zhpan.bannerview.utils.BannerUtils;
  * </pre>
  */
 public class BaseIndicatorView extends View implements IIndicator {
-    /**
-     * 页面size
-     */
-    protected int pageSize;
-    /**
-     * 未选中时Indicator颜色
-     */
-    protected int normalColor;
-    /**
-     * 选中时Indicator颜色
-     */
-    protected int checkedColor;
-    /**
-     * Indicator间距
-     */
-    protected float indicatorGap;
-    /**
-     * 从一个点滑动到另一个点的进度
-     */
-    protected float slideProgress;
-    /**
-     * 指示器当前位置
-     */
-    protected int currentPosition;
-    /**
-     * 指示器上一个位置
-     */
-    private int prePosition;
-    /**
-     * 是否是向右滑动,true向右,false向左
-     */
-    protected boolean slideToRight;
-
-    /**
-     * Indicator滑动模式,目前仅支持两种
-     *
-     * @see IndicatorSlideMode#NORMAL
-     * @see IndicatorSlideMode#SMOOTH
-     */
-    protected int slideMode;
 
-    protected float normalIndicatorWidth;
-    protected float checkedIndicatorWidth;
+    private IndicatorOptions mIndicatorOptions;
 
     protected Paint mPaint;
 
@@ -75,30 +33,26 @@ public class BaseIndicatorView extends View implements IIndicator {
 
     public BaseIndicatorView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
         super(context, attrs, defStyleAttr);
-        normalIndicatorWidth = BannerUtils.dp2px(8);
-        checkedIndicatorWidth = normalIndicatorWidth;
-        indicatorGap = normalIndicatorWidth;
-        normalColor = Color.parseColor("#8C18171C");
-        checkedColor = Color.parseColor("#8C6C6D72");
-        slideMode = IndicatorSlideMode.NORMAL;
+        mIndicatorOptions = new IndicatorOptions();
         mPaint = new Paint();
         mPaint.setAntiAlias(true);
     }
 
     @Override
     public void onPageSelected(int position) {
-        if (slideMode == IndicatorSlideMode.NORMAL) {
-            currentPosition = position;
-            slideProgress = 0;
+        if (getSlideMode() == IndicatorSlideMode.NORMAL) {
+            setCurrentPosition(position);
+            setSlideProgress(0);
             invalidate();
-        } else if (slideMode == IndicatorSlideMode.SMOOTH) {
+        } else if (getSlideMode() == IndicatorSlideMode.SMOOTH) {
+            boolean slideToRight = mIndicatorOptions.isSlideToRight();
             if (position == 0 && slideToRight) {
-                currentPosition = 0;
-                slideProgress = 0;
+                setCurrentPosition(0);
+                setSlideProgress(0);
                 invalidate();
-            } else if (position == pageSize - 1 && !slideToRight) {
-                currentPosition = pageSize - 1;
-                slideProgress = 0;
+            } else if (position == getPageSize() - 1 && !slideToRight) {
+                setCurrentPosition(getPageSize() - 1);
+                setSlideProgress(0);
                 invalidate();
             }
         }
@@ -106,24 +60,26 @@ public class BaseIndicatorView extends View implements IIndicator {
 
     @Override
     public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
-        if (slideMode == IndicatorSlideMode.SMOOTH) {
-            slideToRight = isSlideToRight(position, positionOffset);
+        if (getSlideMode() == IndicatorSlideMode.SMOOTH) {
+            setSlideToRight(isSlideToRight(position, positionOffset));
             //  TODO 解决滑动过快时positionOffset不会等0的情况
             if (positionOffset == 0) {
-                prePosition = position;
+                setPrePosition(position);
             }
-            if (!(position == pageSize - 1)) {
-                slideProgress = (currentPosition == pageSize - 1) && slideToRight ? 0 : positionOffset;
-                currentPosition = position;
+            if (!(position == getPageSize() - 1)) {
+                float slideProgress = (getCurrentPosition() == getPageSize() - 1) && isSlideToRight() ? 0 : positionOffset;
+                setSlideProgress(slideProgress);
+                setCurrentPosition(position);
                 invalidate();
             }
         }
     }
 
     private boolean isSlideToRight(int position, float positionOffset) {
-        if ((prePosition == 0 && position == pageSize - 1)) {
+        int prePosition = mIndicatorOptions.getPrePosition();
+        if ((prePosition == 0 && position == getPageSize() - 1)) {
             return false;
-        } else if (prePosition == pageSize - 1 && position == 0) {
+        } else if (prePosition == getPageSize() - 1 && position == 0) {
             return true;
         } else {
             return (position + positionOffset - prePosition) > 0;
@@ -132,27 +88,27 @@ public class BaseIndicatorView extends View implements IIndicator {
 
     @Override
     public void setPageSize(int pageSize) {
-        this.pageSize = pageSize;
+        mIndicatorOptions.setPageSize(pageSize);
         requestLayout();
     }
 
     @Override
     public void setNormalColor(int normalColor) {
-        this.normalColor = normalColor;
+        mIndicatorOptions.setNormalColor(normalColor);
     }
 
     @Override
     public void setCheckedColor(int checkedColor) {
-        this.checkedColor = checkedColor;
+        mIndicatorOptions.setCheckedColor(checkedColor);
     }
 
 
     /**
-     * @param gapRes Indicator间距
+     * @param indicatorGap Indicator间距
      */
-    public void setIndicatorGap(int gapRes) {
-        if (gapRes >= 0) {
-            this.indicatorGap = gapRes;
+    public void setIndicatorGap(float indicatorGap) {
+        if (indicatorGap >= 0) {
+            mIndicatorOptions.setIndicatorGap(indicatorGap);
         }
     }
 
@@ -163,7 +119,7 @@ public class BaseIndicatorView extends View implements IIndicator {
      */
     @Override
     public void setSlideMode(@AIndicatorSlideMode int slideMode) {
-        this.slideMode = slideMode;
+        mIndicatorOptions.setSlideMode(slideMode);
     }
 
     /**
@@ -174,8 +130,72 @@ public class BaseIndicatorView extends View implements IIndicator {
      */
     @Override
     public void setIndicatorWidth(int normalIndicatorWidth, int checkedIndicatorWidth) {
-        this.normalIndicatorWidth = normalIndicatorWidth;
-        this.checkedIndicatorWidth = checkedIndicatorWidth;
+        mIndicatorOptions.setNormalIndicatorWidth(normalIndicatorWidth);
+        mIndicatorOptions.setCheckedIndicatorWidth(checkedIndicatorWidth);
+    }
+
+    public int getPageSize() {
+        return mIndicatorOptions.getPageSize();
+    }
+
+    public int getNormalColor() {
+        return mIndicatorOptions.getNormalColor();
+    }
+
+    public int getCheckedColor() {
+        return mIndicatorOptions.getCheckedColor();
+    }
+
+    public float getIndicatorGap() {
+        return mIndicatorOptions.getIndicatorGap();
+    }
+
+    public float getSlideProgress() {
+        return mIndicatorOptions.getSlideProgress();
+    }
+
+    public int getCurrentPosition() {
+        return mIndicatorOptions.getCurrentPosition();
+    }
+
+    public void setCurrentPosition(int currentPosition) {
+        mIndicatorOptions.setCurrentPosition(currentPosition);
+    }
+
+    public void setIndicatorOptions(IndicatorOptions indicatorOptions) {
+        mIndicatorOptions = indicatorOptions;
+    }
+
+    public boolean isSlideToRight() {
+        return mIndicatorOptions.isSlideToRight();
+    }
+
+    public int getSlideMode() {
+        return mIndicatorOptions.getSlideMode();
+    }
+
+    public float getNormalIndicatorWidth() {
+        return mIndicatorOptions.getNormalIndicatorWidth();
+    }
+
+    public float getCheckedIndicatorWidth() {
+        return mIndicatorOptions.getCheckedIndicatorWidth();
+    }
+
+    private void setSlideProgress(float slideProgress) {
+        mIndicatorOptions.setSlideProgress(slideProgress);
+    }
+
+    private void setPrePosition(int prePosition) {
+        mIndicatorOptions.setPrePosition(prePosition);
+    }
+
+    private void setSlideToRight(boolean slideToRight) {
+        mIndicatorOptions.setSlideToRight(slideToRight);
+    }
+
+    public IndicatorOptions getIndicatorOptions() {
+        return mIndicatorOptions;
     }
 
     @Override

+ 14 - 13
bannerview/src/main/java/com/zhpan/bannerview/indicator/CircleIndicatorView.java

@@ -8,6 +8,7 @@ import android.util.AttributeSet;
  * Created by zhpan on 2017/12/6.
  */
 public class CircleIndicatorView extends BaseIndicatorView {
+
     private float mNormalRadius;
     private float mCheckedRadius;
     private float maxRadius;
@@ -23,10 +24,10 @@ public class CircleIndicatorView extends BaseIndicatorView {
 
     public CircleIndicatorView(Context context, AttributeSet attrs, int defStyleAttr) {
         super(context, attrs, defStyleAttr);
-        mPaint.setColor(normalColor);
-        mNormalRadius = normalIndicatorWidth / 2;
-        mCheckedRadius = checkedIndicatorWidth / 2;
-        indicatorGap = mNormalRadius * 2;
+        mPaint.setColor(getNormalColor());
+        mNormalRadius = getNormalIndicatorWidth() / 2;
+        mCheckedRadius = getCheckedIndicatorWidth() / 2;
+        setIndicatorGap(mNormalRadius * 2);
     }
 
     @Override
@@ -38,20 +39,20 @@ public class CircleIndicatorView extends BaseIndicatorView {
     @Override
     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
         super.onMeasure(widthMeasureSpec, heightMeasureSpec);
-        mNormalRadius = normalIndicatorWidth / 2;
-        mCheckedRadius = checkedIndicatorWidth / 2;
+        mNormalRadius = getNormalIndicatorWidth() / 2;
+        mCheckedRadius = getCheckedIndicatorWidth() / 2;
         maxRadius = Math.max(mCheckedRadius, mNormalRadius);
-        setMeasuredDimension((int) ((pageSize - 1) * indicatorGap + 2 * (maxRadius + mNormalRadius * (pageSize - 1))),
+        setMeasuredDimension((int) ((getPageSize() - 1) * getIndicatorGap() + 2 * (maxRadius + mNormalRadius * (getPageSize() - 1))),
                 (int) (2 * maxRadius));
     }
 
     @Override
     protected void onDraw(Canvas canvas) {
         super.onDraw(canvas);
-        if(pageSize>1){
-            for (int i = 0; i < pageSize; i++) {
-                mPaint.setColor(normalColor);
-                canvas.drawCircle(maxRadius + (2 * mNormalRadius + indicatorGap) * i, height / 2f, mNormalRadius, mPaint);
+        if (getPageSize() > 1) {
+            for (int i = 0; i < getPageSize(); i++) {
+                mPaint.setColor(getNormalColor());
+                canvas.drawCircle(maxRadius + (2 * mNormalRadius + getIndicatorGap()) * i, height / 2f, mNormalRadius, mPaint);
             }
             drawSliderStyle(canvas);
         }
@@ -73,8 +74,8 @@ public class CircleIndicatorView extends BaseIndicatorView {
     }
 
     private void drawSliderStyle(Canvas canvas) {
-        mPaint.setColor(checkedColor);
-        canvas.drawCircle(maxRadius + (2 * mNormalRadius + indicatorGap) * currentPosition + (2 * mNormalRadius + indicatorGap) * slideProgress,
+        mPaint.setColor(getCheckedColor());
+        canvas.drawCircle(maxRadius + (2 * mNormalRadius + getIndicatorGap()) * getCurrentPosition() + (2 * mNormalRadius + getIndicatorGap()) * getSlideProgress(),
                 height / 2f, mCheckedRadius, mPaint);
     }
 }

+ 38 - 32
bannerview/src/main/java/com/zhpan/bannerview/indicator/DashIndicatorView.java

@@ -2,7 +2,6 @@ package com.zhpan.bannerview.indicator;
 
 import android.content.Context;
 import android.graphics.Canvas;
-import android.graphics.Paint;
 import android.util.AttributeSet;
 
 import com.zhpan.bannerview.constants.IndicatorSlideMode;
@@ -25,8 +24,8 @@ public class DashIndicatorView extends BaseIndicatorView {
 
     public DashIndicatorView(Context context, AttributeSet attrs, int defStyleAttr) {
         super(context, attrs, defStyleAttr);
-        mPaint.setColor(normalColor);
-        sliderHeight = normalIndicatorWidth / 2;
+        mPaint.setColor(getNormalColor());
+        sliderHeight = getNormalIndicatorWidth() / 2;
     }
 
     @Override
@@ -37,10 +36,10 @@ public class DashIndicatorView extends BaseIndicatorView {
     @Override
     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
         super.onMeasure(widthMeasureSpec, heightMeasureSpec);
-        maxWidth = Math.max(normalIndicatorWidth, checkedIndicatorWidth);
-        minWidth = Math.min(normalIndicatorWidth, checkedIndicatorWidth);
-        setMeasuredDimension((int) ((pageSize - 1) * indicatorGap + maxWidth + (pageSize - 1) * minWidth),
-                (int) (sliderHeight));
+        maxWidth = Math.max(getNormalIndicatorWidth(), getCheckedIndicatorWidth());
+        minWidth = Math.min(getNormalIndicatorWidth(), getCheckedIndicatorWidth());
+        setMeasuredDimension((int) ((getPageSize() - 1) * getIndicatorGap() + maxWidth + (getPageSize() - 1) * minWidth),
+                (int) (getSliderHeight()));
     }
 
     @Override
@@ -51,9 +50,9 @@ public class DashIndicatorView extends BaseIndicatorView {
     @Override
     protected void onDraw(Canvas canvas) {
         super.onDraw(canvas);
-        if (pageSize > 1) {
-            for (int i = 0; i < pageSize; i++) {
-                if (slideMode == IndicatorSlideMode.SMOOTH) {
+        if (getPageSize() > 1) {
+            for (int i = 0; i < getPageSize(); i++) {
+                if (getSlideMode() == IndicatorSlideMode.SMOOTH) {
                     smoothSlide(canvas, i);
                 } else {
                     normalSlide(canvas, i);
@@ -64,32 +63,32 @@ public class DashIndicatorView extends BaseIndicatorView {
 
 
     private void normalSlide(Canvas canvas, int i) {
-        if (normalIndicatorWidth == checkedIndicatorWidth) {
-            mPaint.setColor(normalColor);
-            float left = i * (normalIndicatorWidth) + i * +indicatorGap;
-            canvas.drawRect(left, 0, left + normalIndicatorWidth, sliderHeight, mPaint);
+        if (getNormalIndicatorWidth() == getCheckedIndicatorWidth()) {
+            mPaint.setColor(getNormalColor());
+            float left = i * (getNormalIndicatorWidth()) + i * +getIndicatorGap();
+            canvas.drawRect(left, 0, left + getNormalIndicatorWidth(), getSliderHeight(), mPaint);
             drawSliderStyle(canvas);
         } else {  //  仿支付宝首页轮播图的Indicator
-            if (i < currentPosition) {
-                mPaint.setColor(normalColor);
-                float left = i * minWidth + i * indicatorGap;
-                canvas.drawRect(left, 0, left + minWidth, sliderHeight, mPaint);
-            } else if (i == currentPosition) {
-                mPaint.setColor(checkedColor);
-                float left = i * minWidth + i * indicatorGap;
-                canvas.drawRect(left, 0, left + minWidth + (maxWidth - minWidth), sliderHeight, mPaint);
+            if (i < getCurrentPosition()) {
+                mPaint.setColor(getNormalColor());
+                float left = i * minWidth + i * getIndicatorGap();
+                canvas.drawRect(left, 0, left + minWidth, getSliderHeight(), mPaint);
+            } else if (i == getCurrentPosition()) {
+                mPaint.setColor(getCheckedColor());
+                float left = i * minWidth + i * getIndicatorGap();
+                canvas.drawRect(left, 0, left + minWidth + (maxWidth - minWidth), getSliderHeight(), mPaint);
             } else {
-                mPaint.setColor(normalColor);
-                float left = i * minWidth + i * indicatorGap + (maxWidth - minWidth);
-                canvas.drawRect(left, 0, left + minWidth, sliderHeight, mPaint);
+                mPaint.setColor(getNormalColor());
+                float left = i * minWidth + i * getIndicatorGap() + (maxWidth - minWidth);
+                canvas.drawRect(left, 0, left + minWidth, getSliderHeight(), mPaint);
             }
         }
     }
 
     private void smoothSlide(Canvas canvas, int i) {
-        mPaint.setColor(normalColor);
-        float left = i * (maxWidth) + i * +indicatorGap + (maxWidth - minWidth);
-        canvas.drawRect(left, 0, left + minWidth, sliderHeight, mPaint);
+        mPaint.setColor(getNormalColor());
+        float left = i * (maxWidth) + i * +getIndicatorGap() + (maxWidth - minWidth);
+        canvas.drawRect(left, 0, left + minWidth, getSliderHeight(), mPaint);
         drawSliderStyle(canvas);
     }
 
@@ -109,13 +108,20 @@ public class DashIndicatorView extends BaseIndicatorView {
     }
 
     private void drawSliderStyle(Canvas canvas) {
-        mPaint.setColor(checkedColor);
-        float left = currentPosition * (maxWidth) + currentPosition * +indicatorGap + (maxWidth + indicatorGap) * slideProgress;
-        canvas.drawRect(left, 0, left + maxWidth, sliderHeight, mPaint);
+        mPaint.setColor(getCheckedColor());
+        float left = getCurrentPosition() * (maxWidth) + getCurrentPosition() * +getIndicatorGap() + (maxWidth + getIndicatorGap()) * getSlideProgress();
+        canvas.drawRect(left, 0, left + maxWidth, getSliderHeight(), mPaint);
     }
 
-    public DashIndicatorView setSliderHeight(int sliderHeight) {
+    public DashIndicatorView setSliderHeight(float sliderHeight) {
         this.sliderHeight = sliderHeight;
         return this;
     }
+
+    public float getSliderHeight() {
+        if (getIndicatorOptions().getSliderHeight() > 0) {
+            return getIndicatorOptions().getSliderHeight();
+        }
+        return sliderHeight;
+    }
 }

+ 4 - 1
bannerview/src/main/java/com/zhpan/bannerview/indicator/IIndicator.java

@@ -3,6 +3,7 @@ package com.zhpan.bannerview.indicator;
 import androidx.viewpager.widget.ViewPager;
 
 import com.zhpan.bannerview.annotation.AIndicatorSlideMode;
+import com.zhpan.bannerview.manager.IndicatorOptions;
 
 
 /**
@@ -20,9 +21,11 @@ public interface IIndicator extends ViewPager.OnPageChangeListener {
 
     void setSlideMode(@AIndicatorSlideMode int slideStyle);
 
-    void setIndicatorGap(int gap);
+    void setIndicatorGap(float gap);
 
     void setIndicatorWidth(int normalIndicatorWidth, int checkedIndicatorWidth);
 
+    void setIndicatorOptions(IndicatorOptions options);
+
     void notifyDataChanged();
 }

+ 79 - 0
bannerview/src/main/java/com/zhpan/bannerview/manager/AttributeController.java

@@ -0,0 +1,79 @@
+package com.zhpan.bannerview.manager;
+
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.graphics.Color;
+import android.util.AttributeSet;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+import com.zhpan.bannerview.R;
+import com.zhpan.bannerview.utils.BannerUtils;
+
+import static com.zhpan.bannerview.manager.BannerOptions.DEFAULT_SCROLL_DURATION;
+
+/**
+ * <pre>
+ *   Created by zhpan on 2019/11/20.
+ *   Description:
+ * </pre>
+ */
+public class AttributeController {
+
+    private BannerOptions mBannerOptions;
+
+    public AttributeController(BannerOptions bannerOptions) {
+        mBannerOptions = bannerOptions;
+    }
+
+    public void init(@NonNull Context context, @Nullable AttributeSet attrs) {
+        if (attrs != null) {
+            TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.BannerViewPager);
+            initBannerAttrs(typedArray);
+            initIndicatorAttrs(typedArray);
+            typedArray.recycle();
+        }
+    }
+
+    private void initIndicatorAttrs(TypedArray typedArray) {
+        int indicatorCheckedColor = typedArray.getColor(R.styleable.BannerViewPager_bvp_indicator_checked_color, Color.parseColor("#8C18171C"));
+        int indicatorNormalColor = typedArray.getColor(R.styleable.BannerViewPager_bvp_indicator_normal_color, Color.parseColor("#8C6C6D72"));
+        int normalIndicatorWidth = (int) typedArray.getDimension(R.styleable.BannerViewPager_bvp_indicator_radius, BannerUtils.dp2px(8));
+        int indicatorGravity = typedArray.getInt(R.styleable.BannerViewPager_bvp_indicator_gravity, 0);
+        int indicatorStyle = typedArray.getInt(R.styleable.BannerViewPager_bvp_indicator_style, 0);
+        int indicatorSlideMode = typedArray.getInt(R.styleable.BannerViewPager_bvp_indicator_slide_mode, 0);
+        int indicatorVisibility = typedArray.getInt(R.styleable.BannerViewPager_bvp_indicator_visibility, 0);
+        mBannerOptions.setIndicatorCheckedColor(indicatorCheckedColor);
+        mBannerOptions.setIndicatorNormalColor(indicatorNormalColor);
+        mBannerOptions.setNormalIndicatorWidth(normalIndicatorWidth);
+        mBannerOptions.setIndicatorGravity(indicatorGravity);
+        mBannerOptions.setIndicatorStyle(indicatorStyle);
+        mBannerOptions.setIndicatorSlideMode(indicatorSlideMode);
+        mBannerOptions.setIndicatorVisibility(indicatorVisibility);
+        mBannerOptions.setIndicatorGap(normalIndicatorWidth);
+        mBannerOptions.setIndicatorHeight(normalIndicatorWidth / 2);
+        mBannerOptions.setCheckedIndicatorWidth(normalIndicatorWidth);
+
+    }
+
+    private void initBannerAttrs(TypedArray typedArray) {
+        int interval = typedArray.getInteger(R.styleable.BannerViewPager_bvp_interval, 3000);
+        boolean isAutoPlay = typedArray.getBoolean(R.styleable.BannerViewPager_bvp_auto_play, true);
+        boolean isCanLoop = typedArray.getBoolean(R.styleable.BannerViewPager_bvp_can_loop, true);
+        int pageMargin = (int) typedArray.getDimension(R.styleable.BannerViewPager_bvp_page_margin, 0);
+        int roundCorner = (int) typedArray.getDimension(R.styleable.BannerViewPager_bvp_round_corner, 0);
+        int revealWidth = (int) typedArray.getDimension(R.styleable.BannerViewPager_bvp_reveal_width, 0);
+        int pageStyle = typedArray.getInt(R.styleable.BannerViewPager_bvp_page_style, 0);
+        int scrollDuration = typedArray.getInt(R.styleable.BannerViewPager_bvp_scroll_duration, DEFAULT_SCROLL_DURATION);
+        mBannerOptions.setInterval(interval);
+        mBannerOptions.setAutoPlay(isAutoPlay);
+        mBannerOptions.setCanLoop(isCanLoop);
+        mBannerOptions.setPageMargin(pageMargin);
+        mBannerOptions.setRoundCorner(roundCorner);
+        mBannerOptions.setRevealWidth(revealWidth);
+        mBannerOptions.setPageStyle(pageStyle);
+        mBannerOptions.setScrollDuration(scrollDuration);
+    }
+
+}

+ 33 - 0
bannerview/src/main/java/com/zhpan/bannerview/manager/BannerManager.java

@@ -0,0 +1,33 @@
+package com.zhpan.bannerview.manager;
+
+import android.content.Context;
+import android.util.AttributeSet;
+
+/**
+ * <pre>
+ *   Created by zhpan on 2019/11/20.
+ *   Description:
+ * </pre>
+ */
+public class BannerManager {
+
+    private BannerOptions mBannerOptions;
+
+    private AttributeController mAttributeController;
+
+    public BannerManager() {
+        mBannerOptions = new BannerOptions();
+        mAttributeController = new AttributeController(mBannerOptions);
+    }
+
+    public BannerOptions bannerOptions() {
+        if (mBannerOptions == null) {
+            mBannerOptions = new BannerOptions();
+        }
+        return mBannerOptions;
+    }
+
+    public void initAttrs(Context context, AttributeSet attrs) {
+        mAttributeController.init(context, attrs);
+    }
+}

+ 271 - 0
bannerview/src/main/java/com/zhpan/bannerview/manager/BannerOptions.java

@@ -0,0 +1,271 @@
+package com.zhpan.bannerview.manager;
+
+import com.zhpan.bannerview.constants.PageStyle;
+import com.zhpan.bannerview.utils.BannerUtils;
+
+/**
+ * <pre>
+ *   Created by zhpan on 2019/11/20.
+ *   Description:
+ * </pre>
+ */
+public class BannerOptions {
+
+    public BannerOptions() {
+        mIndicatorOptions = new IndicatorOptions();
+        mPageMargin = BannerUtils.dp2px(20);
+        mRevealWidth = BannerUtils.dp2px(20);
+    }
+
+    public static final int DEFAULT_SCROLL_DURATION = 500;
+
+    private int interval;
+
+    private int currentPosition;
+
+    private boolean isLooping;
+
+    private boolean isCanLoop;
+
+    private boolean isAutoPlay = false;
+
+    private int indicatorGravity;
+
+    private int mPageMargin;
+
+    private int mRevealWidth;
+
+    private int mIndicatorStyle;
+
+    private boolean isCustomIndicator;
+
+    private int mPageStyle = PageStyle.NORMAL;
+
+    private IndicatorMargin mIndicatorMargin;
+
+    private int mIndicatorVisibility;
+
+    private int mScrollDuration;
+
+    private int mRoundCorner;
+
+    private boolean disableTouchScroll;
+
+    private IndicatorOptions mIndicatorOptions;
+
+    public int getInterval() {
+        return interval;
+    }
+
+    public void setInterval(int interval) {
+        this.interval = interval;
+    }
+
+    public int getCurrentPosition() {
+        return currentPosition;
+    }
+
+    public void setCurrentPosition(int currentPosition) {
+        this.currentPosition = currentPosition;
+    }
+
+    public boolean isLooping() {
+        return isLooping;
+    }
+
+    public void setLooping(boolean looping) {
+        isLooping = looping;
+    }
+
+    public boolean isCanLoop() {
+        return isCanLoop;
+    }
+
+    public void setCanLoop(boolean canLoop) {
+        isCanLoop = canLoop;
+    }
+
+    public boolean isAutoPlay() {
+        return isAutoPlay;
+    }
+
+    public void setAutoPlay(boolean autoPlay) {
+        isAutoPlay = autoPlay;
+    }
+
+    public int getIndicatorGravity() {
+        return indicatorGravity;
+    }
+
+    public void setIndicatorGravity(int indicatorGravity) {
+        this.indicatorGravity = indicatorGravity;
+    }
+
+    public int getIndicatorNormalColor() {
+        return mIndicatorOptions.getNormalColor();
+    }
+
+    public void setIndicatorNormalColor(int indicatorNormalColor) {
+        mIndicatorOptions.setNormalColor(indicatorNormalColor);
+    }
+
+    public int getIndicatorCheckedColor() {
+        return mIndicatorOptions.getCheckedColor();
+    }
+
+    public void setIndicatorCheckedColor(int indicatorCheckedColor) {
+        mIndicatorOptions.setCheckedColor(indicatorCheckedColor);
+    }
+
+    public int getNormalIndicatorWidth() {
+        return (int) mIndicatorOptions.getNormalIndicatorWidth();
+    }
+
+    public void setNormalIndicatorWidth(int normalIndicatorWidth) {
+        mIndicatorOptions.setNormalIndicatorWidth(normalIndicatorWidth);
+    }
+
+    public int getCheckedIndicatorWidth() {
+        return (int) mIndicatorOptions.getCheckedIndicatorWidth();
+    }
+
+    public void setCheckedIndicatorWidth(int checkedIndicatorWidth) {
+        mIndicatorOptions.setCheckedIndicatorWidth(checkedIndicatorWidth);
+    }
+
+    public IndicatorOptions getIndicatorOptions() {
+        return mIndicatorOptions;
+    }
+
+    public int getPageMargin() {
+        return mPageMargin;
+    }
+
+    public void setPageMargin(int pageMargin) {
+        mPageMargin = pageMargin;
+    }
+
+    public int getRevealWidth() {
+        return mRevealWidth;
+    }
+
+    public void setRevealWidth(int revealWidth) {
+        mRevealWidth = revealWidth;
+    }
+
+    public int getIndicatorStyle() {
+        return mIndicatorStyle;
+    }
+
+    public void setIndicatorStyle(int indicatorStyle) {
+        mIndicatorStyle = indicatorStyle;
+    }
+
+    public int getIndicatorSlideMode() {
+        return mIndicatorOptions.getSlideMode();
+    }
+
+    public void setIndicatorSlideMode(int indicatorSlideMode) {
+        mIndicatorOptions.setSlideMode(indicatorSlideMode);
+    }
+
+    public float getIndicatorGap() {
+        return mIndicatorOptions.getIndicatorGap();
+    }
+
+    public void setIndicatorGap(float indicatorGap) {
+        mIndicatorOptions.setIndicatorGap(indicatorGap);
+    }
+
+    public float getIndicatorHeight() {
+        return mIndicatorOptions.getSliderHeight();
+    }
+
+    public void setIndicatorHeight(int indicatorHeight) {
+        mIndicatorOptions.setSliderHeight(indicatorHeight);
+    }
+
+    public boolean isCustomIndicator() {
+        return isCustomIndicator;
+    }
+
+    public void setCustomIndicator(boolean customIndicator) {
+        isCustomIndicator = customIndicator;
+    }
+
+    public int getPageStyle() {
+        return mPageStyle;
+    }
+
+    public void setPageStyle(int pageStyle) {
+        mPageStyle = pageStyle;
+    }
+
+    public IndicatorMargin getIndicatorMargin() {
+        return mIndicatorMargin;
+    }
+
+    public void setIndicatorMargin(int left, int top, int right, int bottom) {
+        mIndicatorMargin = new IndicatorMargin(left, top, right, bottom);
+    }
+
+    public int getRoundCorner() {
+        return mRoundCorner;
+    }
+
+    public void setRoundCorner(int roundCorner) {
+        this.mRoundCorner = roundCorner;
+    }
+
+    public int getScrollDuration() {
+        return mScrollDuration;
+    }
+
+    public void setScrollDuration(int scrollDuration) {
+        this.mScrollDuration = scrollDuration;
+    }
+
+    public int getIndicatorVisibility() {
+        return mIndicatorVisibility;
+    }
+
+    public void setIndicatorVisibility(int indicatorVisibility) {
+        mIndicatorVisibility = indicatorVisibility;
+    }
+
+    public boolean isDisableTouchScroll() {
+        return disableTouchScroll;
+    }
+
+    public void setDisableTouchScroll(boolean disableTouchScroll) {
+        this.disableTouchScroll = disableTouchScroll;
+    }
+
+    public static class IndicatorMargin {
+
+        private int left, right, top, bottom;
+
+        public IndicatorMargin(int left, int top, int right, int bottom) {
+            this.left = left;
+            this.right = right;
+            this.top = top;
+            this.bottom = bottom;
+        }
+
+        public int getLeft() {
+            return left;
+        }
+
+        public int getRight() {
+            return right;
+        }
+
+        public int getTop() {
+            return top;
+        }
+
+        public int getBottom() {
+            return bottom;
+        }
+    }
+}

+ 167 - 0
bannerview/src/main/java/com/zhpan/bannerview/manager/IndicatorOptions.java

@@ -0,0 +1,167 @@
+package com.zhpan.bannerview.manager;
+
+import android.graphics.Color;
+
+import com.zhpan.bannerview.constants.IndicatorSlideMode;
+import com.zhpan.bannerview.utils.BannerUtils;
+
+/**
+ * <pre>
+ *   Created by zhpan on 2019/11/20.
+ *   Description:
+ * </pre>
+ */
+public class IndicatorOptions {
+
+    public IndicatorOptions() {
+        normalIndicatorWidth = BannerUtils.dp2px(8);
+        checkedIndicatorWidth = normalIndicatorWidth;
+        indicatorGap = normalIndicatorWidth;
+        normalColor = Color.parseColor("#8C18171C");
+        checkedColor = Color.parseColor("#8C6C6D72");
+        slideMode = IndicatorSlideMode.NORMAL;
+    }
+
+    /**
+     * 页面size
+     */
+    private int pageSize;
+    /**
+     * 未选中时Indicator颜色
+     */
+    private int normalColor;
+    /**
+     * 选中时Indicator颜色
+     */
+    private int checkedColor;
+    /**
+     * Indicator间距
+     */
+    private float indicatorGap;
+    /**
+     * 从一个点滑动到另一个点的进度
+     */
+    private float slideProgress;
+    /**
+     * 指示器当前位置
+     */
+    private int currentPosition;
+    /**
+     * 指示器上一个位置
+     */
+    private int prePosition;
+    /**
+     * 是否是向右滑动,true向右,false向左
+     */
+    private boolean slideToRight;
+
+    private float sliderHeight;
+
+    /**
+     * Indicator滑动模式,目前仅支持两种
+     *
+     * @see IndicatorSlideMode#NORMAL
+     * @see IndicatorSlideMode#SMOOTH
+     */
+    private int slideMode;
+
+    private float normalIndicatorWidth;
+
+    private float checkedIndicatorWidth;
+
+    public int getPageSize() {
+        return pageSize;
+    }
+
+    public void setPageSize(int pageSize) {
+        this.pageSize = pageSize;
+    }
+
+    public int getNormalColor() {
+        return normalColor;
+    }
+
+    public void setNormalColor(int normalColor) {
+        this.normalColor = normalColor;
+    }
+
+    public int getCheckedColor() {
+        return checkedColor;
+    }
+
+    public void setCheckedColor(int checkedColor) {
+        this.checkedColor = checkedColor;
+    }
+
+    public float getIndicatorGap() {
+        return indicatorGap;
+    }
+
+    public void setIndicatorGap(float indicatorGap) {
+        this.indicatorGap = indicatorGap;
+    }
+
+    public float getSlideProgress() {
+        return slideProgress;
+    }
+
+    public void setSlideProgress(float slideProgress) {
+        this.slideProgress = slideProgress;
+    }
+
+    public int getCurrentPosition() {
+        return currentPosition;
+    }
+
+    public void setCurrentPosition(int currentPosition) {
+        this.currentPosition = currentPosition;
+    }
+
+    public int getPrePosition() {
+        return prePosition;
+    }
+
+    public void setPrePosition(int prePosition) {
+        this.prePosition = prePosition;
+    }
+
+    public boolean isSlideToRight() {
+        return slideToRight;
+    }
+
+    public void setSlideToRight(boolean slideToRight) {
+        this.slideToRight = slideToRight;
+    }
+
+    public int getSlideMode() {
+        return slideMode;
+    }
+
+    public void setSlideMode(int slideMode) {
+        this.slideMode = slideMode;
+    }
+
+    public float getNormalIndicatorWidth() {
+        return normalIndicatorWidth;
+    }
+
+    public void setNormalIndicatorWidth(float normalIndicatorWidth) {
+        this.normalIndicatorWidth = normalIndicatorWidth;
+    }
+
+    public float getCheckedIndicatorWidth() {
+        return checkedIndicatorWidth;
+    }
+
+    public void setCheckedIndicatorWidth(float checkedIndicatorWidth) {
+        this.checkedIndicatorWidth = checkedIndicatorWidth;
+    }
+
+    public float getSliderHeight() {
+        return sliderHeight;
+    }
+
+    public void setSliderHeight(float sliderHeight) {
+        this.sliderHeight = sliderHeight;
+    }
+}

+ 0 - 3
bannerview/src/main/java/com/zhpan/bannerview/transform/pagestyle/BasePageTransformer.java

@@ -6,9 +6,6 @@ import android.view.View;
 
 import androidx.viewpager.widget.ViewPager;
 
-/**
- * Created by zhy on 16/5/7.
- */
 public abstract class BasePageTransformer implements ViewPager.PageTransformer {
     protected ViewPager.PageTransformer mPageTransformer = NonPageTransformer.INSTANCE;
     public static final float DEFAULT_CENTER = 0.5f;

+ 0 - 3
bannerview/src/main/java/com/zhpan/bannerview/transform/pagestyle/NonPageTransformer.java

@@ -4,9 +4,6 @@ import android.view.View;
 
 import androidx.viewpager.widget.ViewPager;
 
-/**
- * Created by zhy on 16/5/7.
- */
 public class NonPageTransformer implements ViewPager.PageTransformer {
     @Override
     public void transformPage(View page, float position) {

+ 4 - 13
bannerview/src/main/java/com/zhpan/bannerview/utils/BannerUtils.java

@@ -23,19 +23,6 @@ public class BannerUtils {
         return (int) (0.5F + dpValue * Resources.getSystem().getDisplayMetrics().density);
     }
 
-    public static float px2dp(float pxValue) {
-        return pxValue / Resources.getSystem().getDisplayMetrics().density;
-    }
-
-    public int dip2px(float dpValue) {
-        return (int) (0.5F + dpValue * this.density);
-    }
-
-    public float px2dip(int pxValue) {
-        return (float) pxValue / this.density;
-    }
-
-
     public static void e(String tag, String msg) {
         if (DEBUG) {
             Log.e(tag, msg);
@@ -47,4 +34,8 @@ public class BannerUtils {
             Log.e("BannerView", msg);
         }
     }
+
+    public static int getRealPosition(boolean isCanLoop, int position, int pageSize) {
+        return isCanLoop ? (position - 1 + pageSize) % pageSize : (position + pageSize) % pageSize;
+    }
 }

+ 0 - 8
bannerview/src/main/java/com/zhpan/bannerview/utils/PositionUtils.java

@@ -1,8 +0,0 @@
-package com.zhpan.bannerview.utils;
-
-public class PositionUtils {
-
-    public static int getRealPosition(boolean isCanLoop, int position, int pageSize) {
-        return isCanLoop ? (position - 1 + pageSize) % pageSize : (position + pageSize) % pageSize;
-    }
-}

+ 46 - 13
bannerview/src/main/java/com/zhpan/bannerview/view/CatchViewPager.java

@@ -1,5 +1,6 @@
 package com.zhpan.bannerview.view;
 
+import android.annotation.SuppressLint;
 import android.content.Context;
 
 import androidx.viewpager.widget.ViewPager;
@@ -15,6 +16,8 @@ import java.lang.reflect.Field;
 import java.util.ArrayList;
 import java.util.Collections;
 
+import static com.zhpan.bannerview.manager.BannerOptions.DEFAULT_SCROLL_DURATION;
+
 /**
  * Author zhangpan
  * Time:2018/11/14 15:24
@@ -25,8 +28,8 @@ public class CatchViewPager extends ViewPager {
     private SparseIntArray mSparseIntArray = new SparseIntArray();
     private boolean mOverlapStyle = false;
     private BannerScroller mBannerScroller;
-    public static final int DEFAULT_SCROLL_DURATION = 800;
     private boolean disableTouchScroll;
+    private boolean firstLayout = true;
 
     public CatchViewPager(Context context) {
         this(context, null);
@@ -50,18 +53,6 @@ public class CatchViewPager extends ViewPager {
         return false;
     }
 
-    private void hookScroller() {
-        try {
-            mBannerScroller = new BannerScroller(getContext());
-            mBannerScroller.setDuration(DEFAULT_SCROLL_DURATION);
-            Field mField = ViewPager.class.getDeclaredField("mScroller");
-            mField.setAccessible(true);
-            mField.set(this, mBannerScroller);
-        } catch (Exception e) {
-            e.printStackTrace();
-        }
-    }
-
     @Override
     protected int getChildDrawingOrder(int childCount, int i) {
         if (mOverlapStyle) {
@@ -96,6 +87,7 @@ public class CatchViewPager extends ViewPager {
         mBannerScroller.setDuration(scrollDuration);
     }
 
+    @SuppressLint("ClickableViewAccessibility")
     @Override
     public boolean onTouchEvent(MotionEvent ev) {
         if (disableTouchScroll) {
@@ -107,4 +99,45 @@ public class CatchViewPager extends ViewPager {
     public void disableTouchScroll(boolean disableTouchScroll) {
         this.disableTouchScroll = disableTouchScroll;
     }
+
+
+    @Override
+    protected void onAttachedToWindow() {
+        super.onAttachedToWindow();
+        hookFirstLayout();
+    }
+
+
+    @Override
+    protected void onDetachedFromWindow() {
+        super.onDetachedFromWindow();
+        firstLayout = false;
+    }
+
+    private void hookScroller() {
+        try {
+            mBannerScroller = new BannerScroller(getContext());
+            mBannerScroller.setDuration(DEFAULT_SCROLL_DURATION);
+            Field mField = ViewPager.class.getDeclaredField("mScroller");
+            mField.setAccessible(true);
+            mField.set(this, mBannerScroller);
+        } catch (IllegalAccessException | NoSuchFieldException e) {
+            e.printStackTrace();
+        }
+    }
+
+    private void hookFirstLayout() {
+        try {
+            Field mFirstLayout = ViewPager.class.getDeclaredField("mFirstLayout");
+            mFirstLayout.setAccessible(true);
+            mFirstLayout.set(this, firstLayout);
+            setCurrentItem(getCurrentItem());
+        } catch (IllegalAccessException | NoSuchFieldException e) {
+            e.printStackTrace();
+        }
+    }
+
+    public void setFirstLayout(boolean firstLayout) {
+        this.firstLayout = firstLayout;
+    }
 }

+ 2 - 0
build.gradle

@@ -1,6 +1,7 @@
 // Top-level build file where you can add configuration options common to all sub-projects/modules.
 
 buildscript {
+    ext.kotlin_version = '1.3.41'
     repositories {
         jcenter()
 //        maven {
@@ -12,6 +13,7 @@ buildscript {
         classpath 'com.android.tools.build:gradle:3.5.0'
         classpath 'com.github.dcendents:android-maven-gradle-plugin:2.1'
         classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.8.4'
+        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
         // NOTE: Do not place your application dependencies here; they belong
         // in the individual module build.gradle files
     }

BIN
download/app.apk