Android ViewPager指示器
生活随笔
收集整理的這篇文章主要介紹了
Android ViewPager指示器
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
一個values文件
attrs_universal_indicator.xml文件
<?xml version="1.0" encoding="utf-8"?> <resources><declare-styleable name="Indicator"><!--未選中的指示器顏色--><attr name="normal_color" format="reference|color" /><!--選中的指示器顏色--><attr name="selected_color" format="reference|color" /><!--指示器每個item之間的間距--><attr name="spacing" format="dimension" /><!--指示器排列方向--><attr name="orientation" format="enum"><enum name="horizontal" value="0" /><enum name="vertical" value="1" /></attr><!--指示器類型 命名規(guī)則:未選中樣式_選中樣式--><attr name="style" format="enum"><!--都是圓點--><enum name="circle_circle" value="0"/><!--都是方形--><enum name="rect_rect" value="1" /><!--未選中是圓點,選中是方形--><enum name="circle_rect" value="2" /></attr><!--都是圓點指示器半徑大小--><attr name="circle_circle_radius" format="dimension" /><!--都是方形指示器長度--><attr name="rect_rect_itemWidth" format="dimension" /><!--都是方形指示器高度--><attr name="rect_rect_itemHeight" format="dimension" /><!--都是方形指示器圓角--><attr name="rect_rect_corner" format="dimension" /><!--circle_rect 模式圓點半徑--><attr name="circle_rect_radius" format="dimension" /><!--circle_rect 模式方形寬度--><attr name="circle_rect_itemWidth" format="dimension" /><!--circle_rect 模式方形高度--><attr name="circle_rect_itemHeight" format="dimension" /><!--circle_rect 模式方形圓角--><attr name="circle_rect_corner" format="dimension" /></declare-styleable> </resources>?
?
自定義view類UIndicator
/*** 作者:created by meixi* 郵箱:1085220040@qq.com* 日期:2020/1/6 10:41*/public class UIndicator extends View implements ViewPager.OnPageChangeListener {private static final String TAG = "UIndicator";//指示器樣式一 選中未選中都是圓點public static final int STYLE_CIRCLR_CIRCLE = 0;//指示器樣式二 選中未選中都是方形public static final int STYLE_RECT_RECT = 1;//指示器樣式三 選中方形,未選中圓點public static final int STYLE_CIRCLR_RECT = 2;//橫向排列public static final int HORIZONTAL = 0;//縱向排列public static final int VERTICAL = 1;private Context mContext;//指示器之間的間距private int spacing;//指示器排列方向private int orientation = HORIZONTAL;//選中與為選中的顏色private ColorStateList selectedColor, normalColor;//指示器樣式,默認都是圓點private int mStyle = STYLE_CIRCLR_CIRCLE;//樣式一 圓點半徑大小private int circleCircleRadius = 0;//樣式二 方形大小及圓角private int rectRectItemWidth = 0, rectRectItemHeight = 0, rectRectCorner = 0;//樣式三 選中的方形大小及圓角private int circleRectItemWidth = 0, circleRectItemHeight = 0, circleRectCorner = 0;//樣式三 未選中的圓點半徑private int circleRectRadius = 0;//畫筆private Paint normalPaint, selectedPaint;//指示器item的區(qū)域private RectF mRectF;//指示器大小private int width, height;//指示器item個數(shù)private int itemCount = 0;//當前選中的位置private int selection = 0;private ViewPager viewPager;public UIndicator(Context context) {this(context, null);}public UIndicator(Context context, @Nullable AttributeSet attrs) {this(context, attrs, 0);}public UIndicator(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);mContext = context;init(attrs);intPaint();checkItemCount();}/*** 加載自定義屬性*/private void init(AttributeSet attrs) {// 加載自定義屬性集合TypedArray ta = mContext.obtainStyledAttributes(attrs, R.styleable.Indicator);// 第二個參數(shù)是默認設置顏色selectedColor = ta.getColorStateList(R.styleable.Indicator_selected_color);normalColor = ta.getColorStateList(R.styleable.Indicator_normal_color);spacing = ta.getDimensionPixelSize(R.styleable.Indicator_spacing, dip2px(6));//6orientation = ta.getInt(R.styleable.Indicator_orientation, HORIZONTAL);mStyle = ta.getInt(R.styleable.Indicator_style, STYLE_CIRCLR_CIRCLE);circleCircleRadius = ta.getDimensionPixelSize(R.styleable.Indicator_circle_circle_radius, dip2px(3));rectRectCorner = ta.getDimensionPixelSize(R.styleable.Indicator_rect_rect_corner, 0);rectRectItemHeight = ta.getDimensionPixelSize(R.styleable.Indicator_rect_rect_itemHeight, dip2px(3));rectRectItemWidth = ta.getDimensionPixelSize(R.styleable.Indicator_rect_rect_itemWidth, dip2px(15));circleRectCorner = ta.getDimensionPixelSize(R.styleable.Indicator_circle_rect_corner, 0);circleRectRadius = ta.getDimensionPixelSize(R.styleable.Indicator_circle_rect_radius, dip2px(3));//3circleRectItemHeight = ta.getDimensionPixelSize(R.styleable.Indicator_circle_rect_itemHeight, dip2px(3));circleRectItemWidth = ta.getDimensionPixelSize(R.styleable.Indicator_circle_rect_itemWidth, dip2px(15));// 解析后釋放資源ta.recycle();}private void intPaint() {normalPaint = new Paint();normalPaint.setStyle(Paint.Style.FILL);normalPaint.setAntiAlias(true);normalPaint.setColor(normalColor == null ? Color.GRAY : normalColor.getDefaultColor());selectedPaint = new Paint();selectedPaint.setStyle(Paint.Style.FILL);selectedPaint.setAntiAlias(true);selectedPaint.setColor(selectedColor == null ? Color.RED : selectedColor.getDefaultColor());mRectF = new RectF();}@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {super.onMeasure(widthMeasureSpec, heightMeasureSpec);int heightSize = MeasureSpec.getSize(heightMeasureSpec);int widthSize = MeasureSpec.getSize(widthMeasureSpec);switch (mStyle) {case STYLE_CIRCLR_CIRCLE:if (orientation == HORIZONTAL){width = 2 * circleCircleRadius * itemCount + (itemCount - 1) * spacing;height = Math.max(heightSize, 2 * circleCircleRadius);} else {height = 2 * circleCircleRadius * itemCount + (itemCount - 1) * spacing;width = Math.max(widthSize, 2 * circleCircleRadius);}break;case STYLE_RECT_RECT:if (orientation == HORIZONTAL){width = rectRectItemWidth * itemCount + (itemCount - 1) * spacing;height = Math.max(heightSize, rectRectItemHeight);} else {height = rectRectItemHeight * itemCount + (itemCount - 1) * spacing;width = Math.max(widthSize, rectRectItemWidth);}break;case STYLE_CIRCLR_RECT:if (orientation == HORIZONTAL){int normalItemWidth = circleRectRadius * 2;width = (itemCount - 1) * normalItemWidth + circleRectItemWidth + (itemCount - 1) * spacing;int tempHeight = Math.max(circleRectItemHeight, circleRectRadius * 2);height = Math.max(heightSize, tempHeight);} else {int normalItemHeight = circleRectRadius * 2;height = (itemCount - 1) * normalItemHeight + circleRectItemHeight + (itemCount - 1) * spacing;int tempWidth = Math.max(circleRectItemWidth, circleRectRadius * 2);width = Math.max(widthSize, tempWidth);}break;}setMeasuredDimension(width, height);}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);if (orientation == HORIZONTAL) {switch (mStyle) {case STYLE_CIRCLR_CIRCLE:float cy = height / 2;for (int i = 0; i < itemCount; i++) {int cx = (i + 1) * circleCircleRadius + i * spacing;//全部繪制圓點,畫筆的區(qū)別canvas.drawCircle(cx, cy, circleCircleRadius, i == selection ? selectedPaint : normalPaint);}break;case STYLE_RECT_RECT:for (int i = 0; i < itemCount; i++) {int left = i * rectRectItemWidth + i * spacing;mRectF.set(left, 0, left + rectRectItemWidth, rectRectItemHeight);//全部繪制圓角矩形,畫筆的區(qū)別canvas.drawRoundRect(mRectF, rectRectCorner, rectRectCorner, i == selection ? selectedPaint : normalPaint);}break;case STYLE_CIRCLR_RECT:for (int i = 0; i < itemCount; i++) {int left = selection * (circleRectRadius * 2 + spacing);int top;if (selection == i) {//選中的繪制圓角矩形top = (height - circleRectItemHeight) / 2;mRectF.set(left, top, left + circleRectItemWidth, circleRectItemHeight + top);canvas.drawRoundRect(mRectF, circleRectCorner, circleRectCorner, selectedPaint);} else {//未選中的繪制圓點,距離需要判斷position在選中的左邊或者右邊,從而確定cxtop = (height - circleRectRadius * 2) / 2;int cx = 0;float cy1 = circleRectRadius + top;if (selection < i) {cx = (i - 1) * circleRectRadius * 2 + i * spacing + circleRectItemWidth + circleRectRadius;} else {cx = i * (circleRectRadius * 2) + i * spacing + circleRectRadius;}canvas.drawCircle(cx, cy1, circleRectRadius, normalPaint);}}break;}} else {switch (mStyle) {case STYLE_CIRCLR_CIRCLE:float cx = width / 2;for (int i = 0; i < itemCount; i++) {int cy = i * (circleCircleRadius * 2 + spacing)+ circleCircleRadius;//全部繪制圓點,畫筆的區(qū)別canvas.drawCircle(cx, cy, circleCircleRadius, i == selection ? selectedPaint : normalPaint);}break;case STYLE_RECT_RECT:for (int i = 0; i < itemCount; i++) {int top = i * rectRectItemHeight + i * spacing;int left = (width - rectRectItemWidth) / 2;mRectF.set(left, top, left + rectRectItemWidth, top + rectRectItemHeight);//全部繪制圓角矩形,畫筆的區(qū)別canvas.drawRoundRect(mRectF, rectRectCorner, rectRectCorner, i == selection ? selectedPaint : normalPaint);}break;case STYLE_CIRCLR_RECT:for (int i = 0; i < itemCount; i++) {if (selection == i) {int left = (width - circleRectItemWidth) / 2;//選中的繪制圓角矩形int top = selection * (circleRectRadius * 2 + spacing);mRectF.set(left, top, left + circleRectItemWidth, top + circleRectItemHeight);canvas.drawRoundRect(mRectF, circleRectCorner, circleRectCorner, selectedPaint);} else {//未選中的繪制圓點,距離需要判斷position在選中的左邊或者右邊,從而確定cxint cx1 = (width - 2 * circleRectRadius) / 2 + circleRectRadius;float cy1 = 0;if (selection < i) {cy1 = (i - 1) * circleRectRadius * 2 + i * spacing + circleRectItemHeight + circleRectRadius;} else {cy1 = i * (circleRectRadius * 2) + i * spacing + circleRectRadius;}canvas.drawCircle(cx1, cy1, circleRectRadius, normalPaint);}}break;}}}/*** 關聯(lián)ViewPager** @param viewPager*/public void attachToViewPager(ViewPager viewPager) {this.viewPager = viewPager;PagerAdapter pagerAdapter = viewPager.getAdapter();if (pagerAdapter != null) {//TODO 如果項目使用了阿里開源庫,UltraViewPager,想要兼容需要用以下方式獲取 itemCount,否則去除這個if條件if (pagerAdapter instanceof UltraViewPagerAdapter) {//從UltraViewPagerAdapter獲取真實的個數(shù)itemCount = ((UltraViewPagerAdapter) pagerAdapter).getRealCount();} else {itemCount = pagerAdapter.getCount();}selection = viewPager.getCurrentItem() % itemCount;checkItemCount();}viewPager.addOnPageChangeListener(this);}/*** 設置選中的值,當ViewPager只有一個item不顯示指示器*/private void checkItemCount() {if (selection >= itemCount) {selection = itemCount - 1;}setVisibility((itemCount <= 1) ? GONE : VISIBLE);}@Overridepublic void onPageSelected(int i) {if (viewPager != null) {PagerAdapter pagerAdapter = viewPager.getAdapter();if (pagerAdapter != null) {selection = viewPager.getCurrentItem() % itemCount;}}postInvalidate();}@Overridepublic void onPageScrolled(int i, float v, int i1) {}@Overridepublic void onPageScrollStateChanged(int i) {}/*** dp to px*/public int dip2px(float dpValue) {final float scale = getContext().getResources().getDisplayMetrics().density;return (int) (dpValue * scale + 0.5f);} }Activity代碼
?
public class ViewPagerActivity extends Activity {private ViewPager vp;private UIndicator uIndicator1;?
vp = findViewById(R.id.vp_guide); uIndicator1 = findViewById(R.id.indicator1); uIndicator1.attachToViewPager(vp);vp.setAdapter(mAdapter);在attachToViewPager之前
?
附:layout調(diào)用自定義view
<com.tianxin.okhttptest.viewpg.UIndicatorandroid:id="@+id/indicator1"android:layout_width="match_parent"android:layout_height="6dp"android:layout_gravity="bottom|center_horizontal"android:layout_marginTop="10dp"app:circle_circle_radius="3dp"app:normal_color="#99ffffff"app:selected_color="#ffffff"app:spacing="10dp"app:style="circle_rect" />總結
以上是生活随笔為你收集整理的Android ViewPager指示器的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 动态规划(冬令营课堂笔记)
- 下一篇: SNS 简介