当前位置: 移动技术网 > 移动技术>移动开发>Android > Android实现自定义轮播图片控件详解

Android实现自定义轮播图片控件详解

2019年07月24日  | 移动技术网移动技术  | 我要评论

首先上效果图

实现原理

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

一、创建一个自定义的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>

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流。

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网