瀏覽代碼

Indicator改为自定义View 添加控制是否循环、是否自动轮播

zhpan 7 年之前
父節點
當前提交
3b9eee5b0a

+ 1 - 14
.idea/misc.xml

@@ -1,8 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <project version="4">
-  <component name="EntryPointsManager">
-    <entry_points version="2.0" />
-  </component>
   <component name="NullableNotNullManager">
     <option name="myDefaultNullable" value="android.support.annotation.Nullable" />
     <option name="myDefaultNotNull" value="android.support.annotation.NonNull" />
@@ -27,17 +24,7 @@
       </value>
     </option>
   </component>
-  <component name="ProjectLevelVcsManager" settingsEditedManually="false">
-    <OptionsSetting value="true" id="Add" />
-    <OptionsSetting value="true" id="Remove" />
-    <OptionsSetting value="true" id="Checkout" />
-    <OptionsSetting value="true" id="Update" />
-    <OptionsSetting value="true" id="Status" />
-    <OptionsSetting value="true" id="Edit" />
-    <ConfirmationsSetting value="0" id="Add" />
-    <ConfirmationsSetting value="0" id="Remove" />
-  </component>
-  <component name="ProjectRootManager" version="2" languageLevel="JDK_1_7" default="true" assert-keyword="true" jdk-15="true" project-jdk-name="1.8" project-jdk-type="JavaSDK">
+  <component name="ProjectRootManager" version="2" languageLevel="JDK_1_7" default="true" project-jdk-name="1.8" project-jdk-type="JavaSDK">
     <output url="file://$PROJECT_DIR$/build/classes" />
   </component>
   <component name="ProjectType">

+ 19 - 8
app/src/main/java/com/example/zhpan/circleviewpager/MainActivity.java

@@ -1,5 +1,6 @@
 package com.example.zhpan.circleviewpager;
 
+import android.graphics.Color;
 import android.os.Bundle;
 import android.support.v7.app.AppCompatActivity;
 import android.widget.Toast;
@@ -33,11 +34,11 @@ public class MainActivity extends AppCompatActivity {
     }
 
     private void initData() {
-        DataBean dataBean=new DataBean("http://img0.imgtn.bdimg.com/it/u=3159618424,497154385&fm=214&gp=0.jpg","图片一");
-        DataBean dataBean1=new DataBean("http://img0.imgtn.bdimg.com/it/u=3159618424,497154385&fm=214&gp=0.jpg","图片二");
-        DataBean dataBean2=new DataBean("http://img4.imgtn.bdimg.com/it/u=928730363,1881984966&fm=214&gp=0.jpg","图片三");
-        DataBean dataBean3=new DataBean("http://img4.imgtn.bdimg.com/it/u=3779410813,199087977&fm=214&gp=0.jpg","图片四");
-        DataBean dataBean4=new DataBean("http://img2.niutuku.com/desk/1208/1450/ntk-1450-9891.jpg","图片五");
+        DataBean dataBean = new DataBean("http://img0.imgtn.bdimg.com/it/u=3159618424,497154385&fm=214&gp=0.jpg", "图片一");
+        DataBean dataBean1 = new DataBean("http://img0.imgtn.bdimg.com/it/u=3159618424,497154385&fm=214&gp=0.jpg", "图片二");
+        DataBean dataBean2 = new DataBean("http://img4.imgtn.bdimg.com/it/u=928730363,1881984966&fm=214&gp=0.jpg", "图片三");
+        DataBean dataBean3 = new DataBean("http://img4.imgtn.bdimg.com/it/u=3779410813,199087977&fm=214&gp=0.jpg", "图片四");
+        DataBean dataBean4 = new DataBean("http://img2.niutuku.com/desk/1208/1450/ntk-1450-9891.jpg", "图片五");
         mList.add(dataBean);
         mList.add(dataBean1);
         mList.add(dataBean2);
@@ -52,22 +53,23 @@ public class MainActivity extends AppCompatActivity {
     }
 
     private void setViewPager() {
-        //  设置指示器资源图片
-        mViewpager.setIndicator(R.drawable.red_dot,R.drawable.red_dot_night);
+
         //  设置指示器半径大小(dp)
         mViewpager.setDotWidth(8);
         //  设置指示器位置
         mViewpager.setIndicatorGravity(CircleViewPager.IndicatorGravity.END);
+        mViewpager.setAutoPlay(true);
         //  是否显示指示器
         mViewpager.isShowIndicator(true);
         //  设置图片切换时间间隔
         mViewpager.setInterval(3000);
+        mViewpager.setCanLoop(true);
         //  设置页面点击事件
         mViewpager.setOnPageClickListener(new CircleViewPager.OnPageClickListener() {
             @Override
             public void onPageClick(int position) {
                 List<DataBean> list = mViewpager.getList();
-                Toast.makeText(MainActivity.this, "点击了" +list.get(position).getDescribe(), Toast.LENGTH_SHORT).show();
+                Toast.makeText(MainActivity.this, "点击了" + list.get(position).getDescribe(), Toast.LENGTH_SHORT).show();
             }
         });
 
@@ -85,6 +87,15 @@ public class MainActivity extends AppCompatActivity {
                 return new MyViewHolder();
             }
         });
+        //  设置指示器资源图片
+        mViewPager2.setIndicatorColor(Color.parseColor("#6C6D72"),
+                Color.parseColor("#18171C"));
+        mViewPager2.setOnPageClickListener(new CircleViewPager.OnPageClickListener() {
+            @Override
+            public void onPageClick(int position) {
+                Toast.makeText(MainActivity.this, "图片"+(position+1), Toast.LENGTH_SHORT).show();
+            }
+        });
     }
 
     @Override

二進制
app/src/main/res/drawable/red_dot.png


二進制
app/src/main/res/drawable/red_dot_night.png


+ 2 - 8
app/src/main/res/layout/activity_main.xml

@@ -10,9 +10,7 @@
         android:id="@+id/viewpager"
         android:layout_width="match_parent"
         android:layout_height="150dp"
-        app:darkDotRes="@drawable/red_dot_night"
-        app:interval="5000"
-        app:lightDotRes="@drawable/red_dot" />
+        app:interval="5000" />
 
     <com.example.viewpager.view.CircleViewPager
         android:id="@+id/viewpager2"
@@ -20,9 +18,5 @@
         android:layout_height="match_parent"
         android:layout_marginEnd="35dp"
         android:layout_marginStart="35dp"
-        app:darkDotRes="@drawable/red_dot_night"
-        app:interval="5000"
-        app:lightDotRes="@drawable/red_dot" />
-
-
+        app:interval="5000" />
 </LinearLayout>

+ 0 - 6
app/src/main/res/values/attrs.xml

@@ -1,10 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
 <resources>
-    <declare-styleable name="MyViewPager">
-        <attr name="lightDotRes" format="reference"/>
-        <attr name="darkDotRes" format="reference"/>
-        <attr name="dotWidth" format="dimension"/>
-        <attr name="interval" format="integer"/>
 
-    </declare-styleable>
 </resources>

+ 1 - 1
viewpager/src/main/java/com/example/viewpager/adapter/CirclePagerAdapter.java

@@ -59,7 +59,7 @@ public class CirclePagerAdapter<T> extends PagerAdapter {
         view.setOnClickListener(new View.OnClickListener() {
             @Override
             public void onClick(View v) {
-                viewPager.imageClick(position - 1);
+                viewPager.imageClick(position);
             }
         });
         return view;

+ 51 - 0
viewpager/src/main/java/com/example/viewpager/utils/DensityUtils.java

@@ -0,0 +1,51 @@
+package com.example.viewpager.utils;
+
+import android.content.Context;
+import android.util.DisplayMetrics;
+
+/**
+ * dp px转换
+ */
+public class DensityUtils {
+    private static int screenW;
+    private static int screenH;
+    private static float screenDensity;
+
+    public static int getScreenW(Context context){
+        if (screenW == 0){
+            initScreen(context);
+        }
+        return screenW;
+    }
+
+    public static int getScreenH(Context context){
+        if (screenH == 0){
+            initScreen(context);
+        }
+        return screenH;
+    }
+
+    public static float getScreenDensity(Context context){
+        if (screenDensity == 0){
+            initScreen(context);
+        }
+        return screenDensity;
+    }
+
+    private static void initScreen(Context context){
+        DisplayMetrics metric = context.getResources().getDisplayMetrics();
+        screenW = metric.widthPixels;
+        screenH = metric.heightPixels;
+        screenDensity = metric.density;
+    }
+
+
+    public static int dp2px(Context context, float dpValue) {
+        return (int) (dpValue * getScreenDensity(context) + 0.5f);
+    }
+
+
+    public static int px2dp(Context context, float pxValue) {
+        return (int) (pxValue / getScreenDensity(context) + 0.5f);
+    }
+}

+ 90 - 46
viewpager/src/main/java/com/example/viewpager/view/CircleViewPager.java

@@ -2,8 +2,9 @@ package com.example.viewpager.view;
 
 import android.content.Context;
 import android.content.res.TypedArray;
+import android.graphics.Color;
 import android.os.Handler;
-import android.support.annotation.DrawableRes;
+import android.support.annotation.ColorInt;
 import android.support.v4.view.ViewPager;
 import android.util.AttributeSet;
 import android.view.Gravity;
@@ -11,7 +12,6 @@ import android.view.LayoutInflater;
 import android.view.MotionEvent;
 import android.view.View;
 import android.widget.FrameLayout;
-import android.widget.ImageView;
 import android.widget.LinearLayout;
 
 import com.example.viewpager.R;
@@ -25,7 +25,6 @@ import java.util.List;
 
 /**
  * Created by zhpan on 2017/3/28.
- *
  */
 public class CircleViewPager<T> extends FrameLayout {
     private ViewPager mViewPager;
@@ -34,11 +33,7 @@ public class CircleViewPager<T> extends FrameLayout {
     //  重新构造后的轮播数据集合
     private List<T> mListAdd;
     //  指示器图片集合
-    private List<ImageView> mIvDotList;
-    //  选中时轮播圆点资源id
-    private int mLightIndicator;
-    //  未选中时轮播圆点资源id
-    private int mDarkIndicator;
+    private List<DotView> mIvDotList;
     //   轮播原点宽度
     private float mDotWidth;
     //  图片切换时间间隔
@@ -48,13 +43,21 @@ public class CircleViewPager<T> extends FrameLayout {
     //  图片上一个位置
     private int prePosition = 0;
     //  图片当前位置
-    private int currentPosition = 1;
-    //  是否循环
-    private boolean isLoop;
+    private int currentPosition;
+    //  是否正在循环
+    private boolean isLooping;
+    private boolean isCanLoop;
+
+
     //  是否显示指示器圆点
-    boolean showIndicator = true;
+    private boolean showIndicator = true;
+    private boolean isAutoPlay = false;
     private View mView;
 
+
+    private int indicatorNormalColor;
+    private int indicatorCheckedColor;
+
     private LinearLayout mLlDot;
     private HolderCreator holderCreator;
     private OnPageClickListener mOnPageClickListener;
@@ -108,13 +111,13 @@ public class CircleViewPager<T> extends FrameLayout {
     private void init(AttributeSet attrs) {
         if (attrs != null) {
             TypedArray typedArray = getContext().obtainStyledAttributes(attrs, R.styleable.CircleViewPager);
-            mLightIndicator = typedArray.getResourceId(R.styleable.CircleViewPager_lightDotRes, R.drawable.red_dot);
-            mDarkIndicator = typedArray.getResourceId(R.styleable.CircleViewPager_darkDotRes, R.drawable.red_dot_night);
             mDotWidth = typedArray.getDimension(R.styleable.CircleViewPager_dotWidth, 20);
             interval = typedArray.getInteger(R.styleable.CircleViewPager_interval, 3000);
+            indicatorCheckedColor = typedArray.getColor(R.styleable.CircleViewPager_indicator_checked_color, Color.parseColor("#FF4C39"));
+            indicatorNormalColor = typedArray.getColor(R.styleable.CircleViewPager_indicator_normal_color, Color.parseColor("#935656"));
             typedArray.recycle();
         }
-         mView = LayoutInflater.from(getContext()).inflate(R.layout.view_pager_layout, this);
+        mView = LayoutInflater.from(getContext()).inflate(R.layout.view_pager_layout, this);
         mLlDot = (LinearLayout) mView.findViewById(R.id.ll_main_dot);
         mViewPager = (ViewPager) mView.findViewById(R.id.vp_main);
         mList = new ArrayList<>();
@@ -143,6 +146,13 @@ public class CircleViewPager<T> extends FrameLayout {
         } else if (mList.size() == 1) {
             mListAdd.add(mList.get(0));
         } else if (mList.size() > 1) {
+            createData();
+        }
+    }
+
+    private void createData() {
+        if (isCanLoop) {
+            currentPosition = 1;
             for (int i = 0; i < mList.size() + 2; i++) {
                 if (i == 0) {   //  判断当i=0为该处的mList的最后一个数据作为mListAdd的第一个数据
                     mListAdd.add(mList.get(mList.size() - 1));
@@ -152,6 +162,8 @@ public class CircleViewPager<T> extends FrameLayout {
                     mListAdd.add(mList.get(i - 1));
                 }
             }
+        } else {
+            mListAdd.addAll(mList);
         }
     }
 
@@ -164,12 +176,12 @@ public class CircleViewPager<T> extends FrameLayout {
                 switch (action) {
                     case MotionEvent.ACTION_DOWN:
                     case MotionEvent.ACTION_MOVE:
-                        isLoop = true;
+                        isLooping = true;
                         stopLoop();
                         break;
                     case MotionEvent.ACTION_UP:
                     case MotionEvent.ACTION_CANCEL:
-                        isLoop = false;
+                        isLooping = false;
                         startLoop();
                     default:
                         break;
@@ -179,17 +191,18 @@ public class CircleViewPager<T> extends FrameLayout {
         });
     }
 
+
     private void startLoop() {
-        if (!isLoop && mViewPager != null) {
+        if (!isLooping && isAutoPlay && mViewPager != null) {
             mHandler.postDelayed(mRunnable, interval);// 每interval秒执行一次runnable.
-            isLoop = true;
+            isLooping = true;
         }
     }
 
     public void stopLoop() {
-        if (isLoop && mViewPager != null) {
+        if (isLooping && mViewPager != null) {
             mHandler.removeCallbacks(mRunnable);
-            isLoop = false;
+            isLooping = false;
         }
     }
 
@@ -201,17 +214,18 @@ public class CircleViewPager<T> extends FrameLayout {
         if (mList.size() > 1) {
             //  for循环创建mUrlList.size()个ImageView(小圆点)
             for (int i = 0; i < mList.size(); i++) {
-                ImageView imageViewDot = new ImageView(getContext());
-                imageViewDot.setLayoutParams(params);
-                //  设置小圆点的背景为暗红图片
-                imageViewDot.setBackgroundResource(mDarkIndicator);
-                mLlDot.addView(imageViewDot);
-                mIvDotList.add(imageViewDot);
+                DotView dotView = new DotView(getContext());
+                dotView.setLayoutParams(params);
+                dotView.setNormalColor(indicatorNormalColor);
+                dotView.setCheckedColor(indicatorCheckedColor);
+                dotView.setChecked(false);
+                mLlDot.addView(dotView);
+                mIvDotList.add(dotView);
             }
         }
         //设置第一个小圆点图片背景为红色
         if (mList.size() > 1) {
-            mIvDotList.get(dotPosition).setBackgroundResource(mLightIndicator);
+            mIvDotList.get(dotPosition).setChecked(true);
         }
     }
 
@@ -275,20 +289,29 @@ public class CircleViewPager<T> extends FrameLayout {
     }
 
     private void pageSelected(int position) {
-        if (position == 0) {    //判断当切换到第0个页面时把currentPosition设置为list.size(),即倒数第二个位置,小圆点位置为length-1
-            currentPosition = mList.size();
-            dotPosition = mList.size() - 1;
-        } else if (position == mList.size() + 1) {    //当切换到最后一个页面时currentPosition设置为第一个位置,小圆点位置为0
-            currentPosition = 1;
-            dotPosition = 0;
+        if (isCanLoop) {
+            if (position == 0) {    //判断当切换到第0个页面时把currentPosition设置为list.size(),即倒数第二个位置,小圆点位置为length-1
+                currentPosition = mList.size();
+                dotPosition = mList.size() - 1;
+            } else if (position == mList.size() + 1) {    //当切换到最后一个页面时currentPosition设置为第一个位置,小圆点位置为0
+                currentPosition = 1;
+                dotPosition = 0;
+            } else {
+                currentPosition = position;
+                dotPosition = position - 1;
+            }
+            //  把之前的小圆点设置背景为暗红,当前小圆点设置为红色
+            mIvDotList.get(prePosition).setChecked(false);
+            mIvDotList.get(dotPosition).setChecked(true);
+            prePosition = dotPosition;
         } else {
             currentPosition = position;
-            dotPosition = position - 1;
+            //  把之前的小圆点设置背景为暗红,当前小圆点设置为红色
+            mIvDotList.get(prePosition).setChecked(false);
+            mIvDotList.get(currentPosition).setChecked(true);
+            prePosition = currentPosition;
         }
-        //  把之前的小圆点设置背景为暗红,当前小圆点设置为红色
-        mIvDotList.get(prePosition).setBackgroundResource(mDarkIndicator);
-        mIvDotList.get(dotPosition).setBackgroundResource(mLightIndicator);
-        prePosition = dotPosition;
+
     }
 
     public interface OnPageClickListener {
@@ -297,8 +320,13 @@ public class CircleViewPager<T> extends FrameLayout {
 
     //  adapter中图片点击的回掉方法
     public void imageClick(int position) {
-        if (mOnPageClickListener != null)
-            mOnPageClickListener.onPageClick(position);
+        if (isCanLoop) {
+            if (mOnPageClickListener != null)
+                mOnPageClickListener.onPageClick(position - 1);
+        } else {
+            if (mOnPageClickListener != null)
+                mOnPageClickListener.onPageClick(position);
+        }
     }
 
     public void setDotWidth(float dotWidth) {
@@ -306,18 +334,34 @@ public class CircleViewPager<T> extends FrameLayout {
     }
 
     /**
-     * @param lightDotRes 选中时指示器图片
-     * @param darkDotRes  未选中时指示器图片
+     * @param checkedColor 选中时指示器颜色
+     * @param normalColor  未选中时指示器颜色
      */
-    public void setIndicator(@DrawableRes int lightDotRes, @DrawableRes int darkDotRes) {
-        mDarkIndicator = darkDotRes;
-        mLightIndicator = lightDotRes;
+    public void setIndicatorColor(@ColorInt int normalColor, @ColorInt int checkedColor) {
+        indicatorCheckedColor = checkedColor;
+        indicatorNormalColor = normalColor;
     }
 
     public void setOnPageClickListener(OnPageClickListener onPageClickListener) {
         this.mOnPageClickListener = onPageClickListener;
     }
 
+    public boolean isAutoPlay() {
+        return isAutoPlay;
+    }
+
+    public void setAutoPlay(boolean autoPlay) {
+        isAutoPlay = autoPlay;
+    }
+
+    public boolean isCanLoop() {
+        return isCanLoop;
+    }
+
+    public void setCanLoop(boolean canLoop) {
+        isCanLoop = canLoop;
+    }
+
     public void setInterval(int interval) {
         this.interval = interval;
     }

+ 78 - 0
viewpager/src/main/java/com/example/viewpager/view/DotView.java

@@ -0,0 +1,78 @@
+package com.example.viewpager.view;
+
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Paint;
+import android.util.AttributeSet;
+import android.view.View;
+
+/**
+ * Created by zhpan on 2017/12/6.
+ */
+
+public class DotView extends View {
+    private int normalColor;
+    private int checkedColor;
+    private Paint mPaint;
+    private boolean isChecked;
+
+
+
+    public DotView(Context context) {
+        this(context, null);
+    }
+
+    public DotView(Context context, AttributeSet attrs) {
+        this(context, attrs, 0);
+    }
+
+    public DotView(Context context, AttributeSet attrs, int defStyleAttr) {
+        super(context, attrs, defStyleAttr);
+        normalColor = Color.parseColor("#000000");
+        checkedColor = Color.parseColor("#ffffff");
+        mPaint = new Paint();
+        mPaint.setColor(normalColor);
+        mPaint.setAntiAlias(true);
+    }
+
+    @Override
+    protected void onDraw(Canvas canvas) {
+        super.onDraw(canvas);
+        int width = getWidth();
+        int height = getHeight();
+        canvas.drawCircle(width / 2, height / 2, Math.min(width, height) / 2, mPaint);
+    }
+
+    public boolean isChecked() {
+        return isChecked;
+    }
+
+    public void setChecked(boolean checked) {
+        if (checked) {
+            mPaint.setColor(checkedColor);
+        } else {
+            mPaint.setColor(normalColor);
+        }
+        isChecked = checked;
+        invalidate();
+    }
+
+    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;
+    }
+
+
+}

二進制
viewpager/src/main/res/drawable/red_dot.png


二進制
viewpager/src/main/res/drawable/red_dot_night.png


+ 4 - 0
viewpager/src/main/res/values/attrs.xml

@@ -10,5 +10,9 @@
         <!--页面切换时间间隔-->
         <attr name="interval" format="integer"/>
 
+        <attr name="indicator_checked_color" format="color"/>
+        <attr name="indicator_normal_color" format="color"/>
+
     </declare-styleable>
+
 </resources>