Android实现自定义轮播图片控件示例

作者:android_c 时间:2021-09-19 01:27:05 

要完成一个轮播图片,首先想到的应该是使用ViewPager来实现。ViewPager已经有了滑动的功能,我们只要让它自己滚动。再加上下方的小圆点就行了。所以我们本次的自定义控件就是由ViewPager和LinearLayout叠加起来组成的。

直接先上效果图:

Android实现自定义轮播图片控件示例

创建一个自定义的ViewPager

先上完整的代码


package com.kcode.autoscrollviewpager.view;

import android.content.Context;
import android.os.Message;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;

import java.util.Timer;
import java.util.TimerTask;

/**
* Created by caik on 2016/10/10.
*/

public class AutoViewPager extends ViewPager {

private static final String TAG = "AutoViewPager";

private int currentItem;

private Timer mTimer;
 private AutoTask mTask;

private boolean isFirst = true;

public AutoViewPager(Context context) {
   super(context);
 }

public AutoViewPager(Context context, AttributeSet attrs) {
   super(context, attrs);
 }

public void start(){
   if (mTimer == null) {
     mTimer = new Timer();
   }
   mTimer.schedule(new AutoTask(),3000,3000);

}

private Runnable runnable = new Runnable() {
   @Override
   public void run() {
     currentItem = getCurrentItem();
     if(currentItem == getAdapter().getCount() - 1){
       currentItem = 0 ;
     }else {
       currentItem++ ;
     }
     setCurrentItem(currentItem);
   }
 };

private AutoHandler mHandler = new AutoHandler();

public void updatePointView(int size) {
   if (getParent() instanceof AutoScrollViewPager){
     AutoScrollViewPager pager = (AutoScrollViewPager) getParent();
     pager.initPointView(size);
   }else {
     Log.e(TAG,"parent view not be AutoScrollViewPager");
   }
 }

public void onPageSelected(int position) {
   AutoScrollViewPager pager = (AutoScrollViewPager) getParent();
   pager.updatePointView(position);
 }

private class AutoTask extends TimerTask{

@Override
   public void run() {
     mHandler.post(runnable);
   }
 }

private final static class AutoHandler extends android.os.Handler{
   @Override
   public void handleMessage(Message msg) {
     super.handleMessage(msg);

}
 }

public void onStop(){
   //先取消定时器
   if (mTimer != null) {
     mTimer.cancel();
     mTimer = null;
   }
 }

public void onDestroy(){
   onStop();
 }

public void onResume(){
   start();
 }

@Override
 public boolean onTouchEvent(MotionEvent ev) {
   switch (ev.getAction()){
     case MotionEvent.ACTION_DOWN:
       Log.i(TAG,"down");
       onStop();
       break;
     case MotionEvent.ACTION_MOVE:
       Log.i(TAG,"move");
       break;
     case MotionEvent.ACTION_UP:
       Log.i(TAG,"up");
       onResume();
       break;
   }
   return super.onTouchEvent(ev);
 }
}

AutoViewPager 继承至ViewPager,我们通过Timer来启动一个定时器。


public void start(){
   if (mTimer == null) {
     mTimer = new Timer();
   }
   mTimer.schedule(new AutoTask(),3000,3000);

}

private Runnable runnable = new Runnable() {
   @Override
   public void run() {
     currentItem = getCurrentItem();
     if(currentItem == getAdapter().getCount() - 1){
       currentItem = 0 ;
     }else {
       currentItem++ ;
     }
     setCurrentItem(currentItem);
   }
 };

每隔三秒去更新一下页面。这样就能起到一个自己滚动的效果。

设置Adapter

要实现无限循环,只要把Adapter中的getCount()方法返回无限大,直接返回Integer.MAX_VALUE就可以了。

完整的Adapter代码:


package com.kcode.autoscrollviewpager.view;

import android.content.Context;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;

import com.kcode.autoscrollviewpager.R;

import java.util.ArrayList;
import java.util.List;

/**
* Created by caik on 2016/10/11.
*/

public abstract class BaseViewPagerAdapter<T> extends PagerAdapter implements ViewPager.OnPageChangeListener{

private List<T> data = new ArrayList<>();

private Context mContext;
 private AutoViewPager mView;

private OnAutoViewPagerItemClickListener listener;

public BaseViewPagerAdapter(List<T> t) {
   this.data = t;
 }

public BaseViewPagerAdapter(Context context, AutoViewPager viewPager) {
   this.mContext = context;
   mView = viewPager;
   mView.setAdapter(this);
   mView.addOnPageChangeListener(this);
   mView.setCurrentItem(0);
 }

public BaseViewPagerAdapter(Context context, AutoViewPager viewPager,OnAutoViewPagerItemClickListener listener) {
   this.mContext = context;
   mView = viewPager;
   this.listener = listener;
   mView.setAdapter(this);
   mView.addOnPageChangeListener(this);
   mView.setCurrentItem(0);
 }

public BaseViewPagerAdapter(Context context, List<T> data,AutoViewPager viewPager,OnAutoViewPagerItemClickListener listener) {
   this.mContext = context;
   mView = viewPager;
   this.data = data;
   this.listener = listener;
   mView.setAdapter(this);
   mView.addOnPageChangeListener(this);
   mView.setCurrentItem(0);

mView.start();
   mView.updatePointView(getRealCount());
 }

public void add(T t){
   data.add(t);
   notifyDataSetChanged();
   mView.updatePointView(getRealCount());
 }

@Override
 public int getCount() {
   return data == null ? 0 : Integer.MAX_VALUE;
 }

public int getRealCount(){
   return data == null ? 0 : data.size();
 }

@Override
 public void destroyItem(ViewGroup container, int position, Object object) {
   container.removeView((ImageView) object);
 }

@Override
 public Object instantiateItem(ViewGroup container, final int position) {
   ImageView view = (ImageView) LayoutInflater.from(mContext)
       .inflate(R.layout.imageview,container,false);
   view.setOnClickListener(new View.OnClickListener() {
     @Override
     public void onClick(View view) {
       if (listener != null) {
         listener.onItemClick(position % getRealCount(),data.get(position % getRealCount()));
       }
     }
   });

loadImage(view,position, data.get(position % getRealCount()));
   container.addView(view);

return view;
 }

public abstract void loadImage(ImageView view,int position,T t);

@Override
 public boolean isViewFromObject(View view, Object object) {
   return view == object;
 }

@Override
 public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

}

@Override
 public void onPageSelected(int position) {
   mView.onPageSelected(position % getRealCount());
 }

@Override
 public void onPageScrollStateChanged(int state) {

}

public interface OnAutoViewPagerItemClickListener<T> {
   void onItemClick(int position,T t);
 }
}

这里我们使用了泛型,因为有时候我们可能只传一个url集合进来,也可能是对象集合,方便拓展。加载图片的方法也是一个抽象方法


public abstract void loadImage(ImageView view,int position,T t);

因为每个App使用的图片加载框架都不一样,所以这里的加载就留个App自己实现。使用的时候创建Adapter只要继承这里的BaseViewPagerAdapter,然后重写loadImage(ImageView view,int position,T t)方法,在这里进行图片的加载就行了。

如果你需不要底部的小圆点标示的话,这里就已经完成了。使用的时候,直接使用


 <com.kcode.autoscrollviewpager.view.AutoViewPager
   android:layout_width="match_parent"
   android:layout_height="200dp">

</com.kcode.autoscrollviewpager.view.AutoViewPager>

代替


 <android.support.v4.view.ViewPager
   android:layout_width="match_parent"
   android:layout_height="match_parent">

</android.support.v4.view.ViewPager>

就可以了。需要底部的小圆点标示的话,继续往下

添加小圆点标示

需要添加小圆点标示的话。其实就是在ViewPager上再加一层。我们新建一个View,继承至RelativeLayout

完整代码如下:


package com.kcode.autoscrollviewpager.view;

import android.content.Context;
import android.util.AttributeSet;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;

import com.kcode.autoscrollviewpager.R;

import static android.view.Gravity.CENTER;

/**
* Created by caik on 2016/10/17.
*/

public class AutoScrollViewPager extends RelativeLayout{

private AutoViewPager mViewPager;

private Context mContext;

private LinearLayout layout;

public AutoScrollViewPager(Context context) {
   super(context);
   init(context);
 }

public AutoScrollViewPager(Context context, AttributeSet attrs) {
   super(context, attrs);
   init(context);
 }

private void init(Context context){
   mContext = context;
   mViewPager = new AutoViewPager(context);
   layout = new LinearLayout(mContext);
   addView(mViewPager);
 }

public AutoViewPager getViewPager() {
   return mViewPager;
 }

public void initPointView(int size){

layout = new LinearLayout(mContext);
   for (int i = 0; i < size; i++) {
     ImageView imageView = new ImageView(mContext);
     LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(20,20);
     params.leftMargin = 8;
     params.gravity = CENTER;
     imageView.setLayoutParams(params);
     if (i == 0) {
       imageView.setBackgroundResource(R.drawable.point_checked);
     }else {
       imageView.setBackgroundResource(R.drawable.point_normal);
     }

layout.addView(imageView);
   }

LayoutParams layoutParams = new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
   layoutParams.addRule(ALIGN_PARENT_BOTTOM);
   layoutParams.addRule(ALIGN_PARENT_RIGHT);
   layoutParams.setMargins(12,20,12,20);
   layout.setLayoutParams(layoutParams);
   addView(layout);
 }

public void updatePointView(int position) {
   int size = layout.getChildCount();
   for (int i = 0; i < size; i++) {
     ImageView imageView = (ImageView) layout.getChildAt(i);
     if (i == position){
       imageView.setBackgroundResource(R.drawable.point_checked);
     }else {
       imageView.setBackgroundResource(R.drawable.point_normal);
     }

}
 }

}

初始化的时候创建一个ViewPager,一个LinearLayout(用来放小圆点)


public AutoScrollViewPager(Context context) {
   super(context);
   init(context);
 }

public AutoScrollViewPager(Context context, AttributeSet attrs) {
   super(context, attrs);
   init(context);
 }

private void init(Context context){
   mContext = context;
   mViewPager = new AutoViewPager(context);
   layout = new LinearLayout(mContext);
   addView(mViewPager);
 }

再通过addView(mViewPager);添加。

需要准备两张图片,这里用Shape进行绘制,Shape的使用可以查看Android Shape使用.

初始化小圆点:


public void initPointView(int size){

layout = new LinearLayout(mContext);
   for (int i = 0; i < size; i++) {
     ImageView imageView = new ImageView(mContext);
     LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(20,20);
     params.leftMargin = 8;
     params.gravity = CENTER;
     imageView.setLayoutParams(params);
     if (i == 0) {
       imageView.setBackgroundResource(R.drawable.point_checked);
     }else {
       imageView.setBackgroundResource(R.drawable.point_normal);
     }

layout.addView(imageView);
   }

LayoutParams layoutParams = new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
   layoutParams.addRule(ALIGN_PARENT_BOTTOM);
   layoutParams.addRule(ALIGN_PARENT_RIGHT);
   layoutParams.setMargins(12,20,12,20);
   layout.setLayoutParams(layoutParams);
   addView(layout);
 }

更新小圆点:


public void updatePointView(int position) {
   int size = layout.getChildCount();
   for (int i = 0; i < size; i++) {
     ImageView imageView = (ImageView) layout.getChildAt(i);
     if (i == position){
       imageView.setBackgroundResource(R.drawable.point_checked);
     }else {
       imageView.setBackgroundResource(R.drawable.point_normal);
     }

}
 }

带小圆点的使用以下控件


<com.kcode.autoscrollviewpager.view.AutoScrollViewPager
   android:id="@+id/viewPager"
   android:layout_width="match_parent"
   android:layout_height="220dp">

</com.kcode.autoscrollviewpager.view.AutoScrollViewPager>

标签:android,轮播图
0
投稿

猜你喜欢

  • ViewDragHelper实现QQ侧滑效果

    2022-12-25 23:26:54
  • Java编写实现坦克大战小游戏

    2023-11-24 09:15:34
  • 通过Feign进行调用@FeignClient 找不到的解决方案

    2023-08-18 19:06:52
  • startActivityForResult和setResult案例详解

    2023-09-15 19:13:33
  • 浅谈@Aspect@Order各个通知的执行顺序

    2021-10-24 19:00:38
  • Android进程运行中权限被收回导致关闭的问题解决

    2023-11-21 16:56:45
  • C#计时器的三种实现方法

    2023-06-08 04:41:32
  • Java设计模式之Builder建造者模式

    2021-12-16 07:21:53
  • Springboot整合微信支付(订单过期取消及商户主动查单)

    2023-05-15 23:40:50
  • Java Validation方法入参校验实现过程解析

    2021-08-04 03:31:50
  • java中带参数的try(){}语法含义详解

    2021-10-27 05:20:16
  • Java中String、StringBuffer、StringBuilder的区别介绍

    2023-11-20 18:31:32
  • springboot+jwt实现token登陆权限认证的实现

    2021-12-22 12:02:46
  • C# 生成随机数的代码

    2021-06-16 06:05:43
  • SpringCloud超详细讲解负载均衡组件Ribbon源码

    2021-06-17 18:39:47
  • Java在web页面上的编码解码处理及中文URL乱码解决

    2023-08-25 11:10:19
  • java多线程-同步块实例讲解

    2022-06-21 02:10:41
  • Mybatis中xml的动态sql实现示例

    2023-11-29 17:09:36
  • springboot cloud使用eureka整合分布式事务组件Seata 的方法

    2023-08-19 13:49:44
  • MybatisPlus实现简单增删改查功能

    2021-12-27 06:25:21
  • asp之家 软件编程 m.aspxhome.com