与轮播图结合的ViewPagerIndicatorView

来源:互联网 发布:二叉树的前序遍历java 编辑:程序博客网 时间:2024/04/18 23:34
首先看看长啥样吧

没错,这种Indication和我们在百度上一搜一大把的还是有点不一样的,这个完全就是用作为展示用的,用来提示用户当前是第几页了。

首先来看一下主要的控件,

IndicatorView.java

  1. import android.content.Context;
  2. import android.os.Handler;
  3. import android.os.Message;
  4. import android.util.AttributeSet;
  5. import android.view.LayoutInflater;
  6. import android.view.View;
  7. import android.widget.ImageView;
  8. import android.widget.LinearLayout;
  9. import android.widget.RelativeLayout;
  10. import java.lang.ref.WeakReference;
  11. import cn.mifengkong.loan.R;
  12. /**
  13. * user guide, viewpager indicator
  14. *
  15. */
  16. public class IndicatorView extends RelativeLayout {
  17. /**
  18. * anchor container
  19. */
  20. private LinearLayout indicateLayout;
  21. private Handler refreshHandler;
  22. /**
  23. * page total count
  24. */
  25. private int totelCount = 0;
  26. /**
  27. * current page
  28. */
  29. private int currentIndex = 0;
  30. public IndicatorView(Context context, AttributeSet attrs) {
  31. super(context, attrs);
  32. this.init(context);
  33. }
  34. public IndicatorView(Context context) {
  35. super(context);
  36. this.init(context);
  37. }
  38. /**
  39. * @param context
  40. */
  41. private void init(Context context) {
  42. LayoutInflater.from(context).inflate(R.layout.viewpager_indicator_layout, this);
  43. this.indicateLayout = (LinearLayout) findViewById(R.id.image_indicater_layout);
  44. this.refreshHandler = new ScrollIndicateHandler(IndicatorView.this);
  45. }
  46. /**
  47. * get current index
  48. */
  49. public int getCurrentIndex() {
  50. return this.currentIndex;
  51. }
  52. public void setTotalCount(int size) {
  53. this.totelCount = size;
  54. }
  55. /**
  56. * git view count
  57. */
  58. public int getTotalCount() {
  59. return this.totelCount;
  60. }
  61. /**
  62. * set show item current
  63. *
  64. * @param index postion
  65. */
  66. public void setCurrentItem(int index) {
  67. this.currentIndex = index;
  68. }
  69. /**
  70. * show
  71. */
  72. public void show() {
  73. for (int index = 0; index < this.totelCount; index++) {
  74. final View indicater = new ImageView(getContext());
  75. LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
  76. params.leftMargin = 10;
  77. indicater.setLayoutParams(params);
  78. this.indicateLayout.addView(indicater, index);
  79. }
  80. this.refreshHandler.sendEmptyMessage(currentIndex);
  81. }
  82. /**
  83. * refresh indicate anchor
  84. */
  85. protected void refreshIndicateView() {
  86. for (int index = 0; index < totelCount; index++) {
  87. final ImageView imageView = (ImageView) this.indicateLayout.getChildAt(index);
  88. if (this.currentIndex == index) {
  89. imageView.setBackgroundResource(R.drawable.dot_focus);
  90. } else {
  91. imageView.setBackgroundResource(R.drawable.dot_normal);
  92. }
  93. }
  94. }
  95. /**
  96. * ScrollIndicateHandler
  97. */
  98. private static class ScrollIndicateHandler extends Handler {
  99. private final WeakReference<IndicatorView> scrollIndicateViewRef;
  100. public ScrollIndicateHandler(IndicatorView scrollIndicateView) {
  101. this.scrollIndicateViewRef = new WeakReference<IndicatorView>(
  102. scrollIndicateView);
  103. }
  104. @Override
  105. public void handleMessage(Message msg) {
  106. super.handleMessage(msg);
  107. IndicatorView scrollIndicateView = scrollIndicateViewRef.get();
  108. if (scrollIndicateView != null) {
  109. scrollIndicateView.refreshIndicateView();
  110. }
  111. }
  112. }
  113. }

贴完代码,现在来看一下代码:
  1. public IndicatorView(Context context, AttributeSet attrs) {
  2. super(context, attrs);
  3. this.init(context);
  4. }
  5. public IndicatorView(Context context) {
  6. super(context);
  7. this.init(context);
  8. }
两个构造方法都调用了init()方法来初始化布局以及控件。

在初始化完控件以后,调用getTotalCount()给控件设置点的个数,以及调用setCurrentItem()方法来设置默认选中的点

show()方法:
  1. public void show() {
  2. for (int index = 0; index < this.totelCount; index++) {
  3. final View indicater = new ImageView(getContext());
  4. LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
  5. LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
  6. params.leftMargin = 10;
  7. indicater.setLayoutParams(params);
  8. this.indicateLayout.addView(indicater, index);
  9. }
  10. this.refreshHandler.sendEmptyMessage(currentIndex);
  11. }

就是将我们的一个一个的点添加到我们的线性布局中,并且我们还利用LinearLayout.LayoutParams来给点进行布局,这里的话,我让点距离右边10PX。添加完以后
调用了Handler的sendEmptyMessage方法发送了一个消息,我们的Handler还做了防止内存泄漏的操作。

在Handler的SendMessage方法中调用了refreshIndicateView()方法,

  1. /**
  2. * refresh indicate anchor
  3. */
  4. protected void refreshIndicateView() {
  5. for (int index = 0; index < totelCount; index++) {
  6. final ImageView imageView = (ImageView) this.indicateLayout.getChildAt(index);
  7. if (this.currentIndex == index) {
  8. imageView.setBackgroundResource(R.drawable.dot_focus);
  9. } else {
  10. imageView.setBackgroundResource(R.drawable.dot_normal);
  11. }
  12. }
  13. }
再该方法中,就只是分别对选中的点和没有选中的点设置了不同的背景图片,当然你也可以自己设置背景图片的样式。

viewpager_indicator_layout.xml

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. android:layout_width="wrap_content"
  4. android:layout_height="wrap_content"
  5. >
  6. <LinearLayout
  7. android:id="@+id/image_indicater_layout"
  8. android:layout_width="wrap_content"
  9. android:layout_height="wrap_content"
  10. android:layout_centerHorizontal="true"
  11. android:layout_alignParentBottom="true"
  12. android:layout_marginBottom="10dp"
  13. android:gravity="center"
  14. android:minHeight="10dp"
  15. android:minWidth="60dp"
  16. android:orientation="horizontal" >
  17. </LinearLayout>
  18. </RelativeLayout>

两个背景图片的样式也贴一下吧

dot_normal.xml
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <shape xmlns:android="http://schemas.android.com/apk/res/android">
  3. <solid android:color="#ffffff" />
  4. <size
  5. android:width="6dp"
  6. android:height="6dp"/>
  7. <corners
  8. android:radius="6dp"/>
  9. </shape>

dot_focus.xml
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <shape xmlns:android="http://schemas.android.com/apk/res/android">
  3. <solid android:color="#ffffff" />
  4. <size
  5. android:width="18dp"
  6. android:height="6dp"/>
  7. <corners
  8. android:radius="5dp"/>
  9. </shape>

然后接下来的看一下如何使用吧

  1. IndicatorView indicatorView = new IndicatorView(getActivity());
  2. indicatorView.setTotalCount(mImageViewUrl.size());//设置点的个数
  3. indicatorView.setCurrentItem(0);//设置默认选中的点
  4. RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(
  5. RelativeLayout.LayoutParams.WRAP_CONTENT,RelativeLayout.LayoutParams.WRAP_CONTENT);
  6. params.addRule(RelativeLayout.CENTER_HORIZONTAL);//设置我们的View水平居中
  7. params.addRule(RelativeLayout.ALIGN_BOTTOM);//设置IndicatorView居于底部
  8. params.bottomMargin = CommonUtil.dip2px(UiUtils.getContext(), 10);//距离底部10DP
  9. mTopView.addView(indicatorView,params);//将IndicatorView添加到布局中
  10. indicatorView.show();//将IndicatorView显示粗来
mImageViewUrl这个参数是用来存放轮播图图片的地址集合

这样还不够,轮播图肯定是挥动的,所以我们要在ViewPager的OnPageChangeListener监听器中onPageSelected方法对选中的点进行改变

  1. private class MyOnPageChangeListener implements OnPageChangeListener {
  2. /**
  3. * 界面选中的时候调用,初始化点的滚动
  4. */
  5. @Override
  6. public void onPageSelected(final int position) {
  7. if (null != indicatorView && indicatorView.getTotalCount() > 0) {
  8. indicatorView.setCurrentItem(position % mImageUrl.size());// % mImageUrl.size() 这个是因为我的轮播图是无限滚动的,所以加上这个,如果你的轮播图不是这样的,可以去掉
  9. indicatorView.refreshIndicateView();
  10. }
  11. }
  12. @Override
  13. public void onPageScrollStateChanged(int arg0) {
  14. }
  15. @Override
  16. public void onPageScrolled(int arg0, float arg1, int arg2) {
  17. }
  18. }







0 0
原创粉丝点击