Android自定义控件实现优雅的广告轮播图

Android自定义控件实现优雅的广告轮播图,第1张

概述前言今天给大家带来一个新的控件C轮播图,网上已经有很多这类的博客来讲解如何实现的,那么我的这个有哪些特点呢?或是说有哪些不同呢?

前言

今天给大家带来一个新的控件C轮播图,网上已经有很多这类的博客来讲解如何实现的,那么我的这个有哪些特点呢?或是说有哪些不同呢?

满足了轮播图的基本要求,循环滑动,在最后一张切到第一张时可以平稳的过渡
简洁简洁简洁
扩展性强

如何使用

下面我们先展示两种效果图

1 默认效果

代码实现

//布局代码<com.landptf.vIEw.BannerM  androID:ID="@+ID/bm_banner"  androID:layout_wIDth="match_parent"  androID:layout_height="200dp" />//java代码BannerM banner = (BannerM) findVIEwByID(R.ID.bm_banner);if (banner != null) { banner.setBannerBeanList(bannerList).show();}//初始化数据private voID initData() { bannerList = new ArrayList<>(4); BannerBean banner1 = new BannerBean("测试图片1",url1,""); BannerBean banner2 = new BannerBean("测试图片2",url2,""); BannerBean banner3 = new BannerBean("测试图片3",url3,""); BannerBean banner4 = new BannerBean("测试图片4",url4,""); bannerList.add(banner1); bannerList.add(banner2); bannerList.add(banner3); bannerList.add(banner4);}

其实关键代码就一行,这里面用到了BannerBean的实体类,有三个参数,分别是图片的描述文字,图片地址,点击后对应的链接

以上全部都是默认值,下面来看一下都哪些可以自定义

2 自定义效果

图1和图2主要有以下几点不同

1 指示器和文字的位置结构,这里面我只实现了两种,大家也可以下载源码后扩展
2 圆点指示器选中后的颜色
3 自动播放的时间间隔
4 支持图片未加载出来之前显示默认图片

自定义效果的代码实现

下面通过xml和java代码来分别演示一下图2的实现

1 xml

<com.landptf.vIEw.BannerM  androID:ID="@+ID/bm_banner"  androID:layout_wIDth="match_parent"  androID:layout_height="200dp"  landptf:defaultimageDrawable="@drawable/default_image"  landptf:intervalTime="3"  landptf:indexposition="bottom"  landptf:indexcolor="@color/colorPrimary"  />BannerM banner = (BannerM) findVIEwByID(R.ID.bm_banner);if (banner != null) { banner.setBannerBeanList(bannerList)   .setonItemClickListener(new BannerM.OnItemClickListener() {    @OverrIDe    public voID onItemClick(int position) {     Log.e("landptf","position = " + position);    }   })   .show();}

2 java

<com.landptf.vIEw.BannerM  androID:ID="@+ID/bm_banner"  androID:layout_wIDth="match_parent"  androID:layout_height="200dp" />BannerM banner = (BannerM) findVIEwByID(R.ID.bm_banner);if (banner != null) { banner.setBannerBeanList(bannerList)   .setDefaultimageResID(R.drawable.default_image)   .setIndexposition(BannerM.INDEX_position_BottOM)   .setIndexcolor(getResources().getcolor(R.color.colorPrimary))   .setIntervalTime(3)   .setonItemClickListener(new BannerM.OnItemClickListener() {    @OverrIDe    public voID onItemClick(int position) {     Log.e("landptf","position = " + position);    }   })   .show();}

以上两种代码实现的效果完全等价,在java代码中都是通过链式调用,使代码看起来更加的简洁。
有木有很方便,大大的减少了代码量,而且是可以直接拿来用的。好了下面我们来看一下实现的代码。

实现

图片下载集成了Picasso,有对Picasso不熟悉的童鞋可以看一下我之前的博客图片加载利器之Picasso(二)基本用法

<?xml version="1.0" enCoding="utf-8"?><relativeLayout xmlns:androID="http://schemas.androID.com/apk/res/androID" androID:layout_wIDth="match_parent" androID:layout_height="match_parent"> <androID.support.v4.vIEw.VIEwPager  androID:ID="@+ID/vp_banner"  androID:layout_wIDth="match_parent"  androID:layout_height="match_parent" /> <VIEwStub  androID:ID="@+ID/vs_index_right"  androID:layout_wIDth="match_parent"  androID:layout_height="wrap_content"  androID:layout_alignParentBottom="true"  androID:layout="@layout/vIEwstub_banner_m_index_right" /> <VIEwStub  androID:ID="@+ID/vs_index_bottom"  androID:layout_wIDth="match_parent"  androID:layout_height="wrap_content"  androID:layout_alignParentBottom="true"  androID:layout="@layout/vIEwstub_banner_m_index_bottom" /></relativeLayout>

VIEwStub的引用代码这里就不给出,大家可以访问我的git查看,文末会给出地址

package com.landptf.vIEw;import androID.annotation.Suppresslint;import androID.content.Context;import androID.content.res.colorStateList;import androID.content.res.TypedArray;import androID.graphics.drawable.Drawable;import androID.graphics.drawable.GradIEntDrawable;import androID.os.Handler;import androID.os.Message;import androID.os.Parcelable;import androID.support.annotation.Nullable;import androID.support.v4.vIEw.PagerAdapter;import androID.support.v4.vIEw.VIEwPager;import androID.util.AttributeSet;import androID.vIEw.LayoutInflater;import androID.vIEw.VIEw;import androID.vIEw.VIEwGroup;import androID.vIEw.VIEwParent;import androID.vIEw.VIEwStub;import androID.Widget.ImageVIEw;import androID.Widget.linearLayout;import androID.Widget.relativeLayout;import androID.Widget.TextVIEw;import com.landptf.R;import com.landptf.bean.BannerBean;import com.landptf.util.ConvertM;import com.squareup.picasso.MemoryPolicy;import com.squareup.picasso.Picasso;import java.util.ArrayList;import java.util.List;import java.util.concurrent.Executors;import java.util.concurrent.scheduledexecutorservice;import java.util.concurrent.TimeUnit;/** * Created by landptf on 2017/03/06. * 轮播图控件 */public class BannerM extends relativeLayout { /**  * 圆点指示器的位置,文字在左,圆点在右  */ public static final int INDEX_position_RIGHT = 0x100; /**  * 圆点指示器的位置,文字在上,圆点在下  */ public static final int INDEX_position_BottOM = 0x101; private static final int HANDLE_UPDATE_INDEX = 0; private Context mContext; private VIEwPager vpBanner; private VIEwPagerAdapter adapter; private OnItemClickListener mOnItemClickListener; //装载ImageVIEw控件的List private List<ImageVIEw> ivList; //圆点指示器控件 private List<VIEw> vList; //控制圆点VIEw的形状,未选中的颜色 private GradIEntDrawable gradIEntDrawable; //控制圆点VIEw的形状,选中的颜色 private GradIEntDrawable gradIEntDrawableSelected; //选中圆点的颜色值,默认为#FF3333 private int indexcolorResID; //图片对应的文字描述 private TextVIEw tvText; //自动滑动的定时器 private scheduledexecutorservice scheduledexecutorservice; //当前加载到第几页 private int currentIndex = 0; //默认背景图 private int defaultimageResID; private Drawable defaultimageDrawable = null; //自动轮播的时间间隔(s) private int intervalTime = 5; //轮播图需要的数据列表 private List<BannerBean> bannerBeanList; //圆点指示器的位置,提供两种布局 private int indexposition = INDEX_position_RIGHT; public BannerM(Context context) {  this(context,null); } public BannerM(Context context,AttributeSet attrs) {  this(context,attrs,0); } public BannerM(Context context,AttributeSet attrs,int defStyleAttr) {  super(context,defStyleAttr);  init(context,defStyleAttr); } private voID init(Context context,int defStyle) {  mContext = context;  LayoutInflater.from(context).inflate(R.layout.vIEw_banner_m,this,true);  vpBanner = (VIEwPager) findVIEwByID(R.ID.vp_banner);  TypedArray a = getContext().obtainStyledAttributes(    attrs,R.styleable.bannerM,defStyle,0);  if (a != null) {   defaultimageDrawable = a.getDrawable(R.styleable.bannerM_defaultimageDrawable);   intervalTime = a.getInteger(R.styleable.bannerM_intervalTime,5);   indexposition = a.getInteger(R.styleable.bannerM_indexposition,INDEX_position_RIGHT);   colorStateList indexcolorList = a.getcolorStateList(R.styleable.bannerM_indexcolor);   if (indexcolorList != null) {    indexcolorResID = indexcolorList.getcolorForState(getDrawableState(),0);   }   a.recycle();  } } /**  * 设置图片加载之前默认显示的图片  *  * @param defaultimageResID  * @return BannerM  */ public BannerM setDefaultimageResID(int defaultimageResID) {  this.defaultimageResID = defaultimageResID;  return this; } /**  * 设置图片加载之前默认显示的图片  *  * @param defaultimageDrawable  * @return BannerM  */ public BannerM setDefaultimageDrawable(Drawable defaultimageDrawable) {  this.defaultimageDrawable = defaultimageDrawable;  return this; } /**  * 设置轮播的时间间隔,单位为s,默认为5s  *  * @param intervalTime  * @return BannerM  */ public BannerM setIntervalTime(int intervalTime) {  this.intervalTime = intervalTime;  return this; } /**  * 设置圆点指示器的位置  * #BannerM.INDEX_position_RIGHT or #BannerM.INDEX_position_BottOM  *  * @param indexposition  * @return BannerM  */ public BannerM setIndexposition(int indexposition) {  this.indexposition = indexposition;  return this; } /**  * 选中圆点的颜色值,默认为#FF3333  *  * @param indexcolor  * @return BannerM  */ public BannerM setIndexcolor(int indexcolor) {  this.indexcolorResID = indexcolor;  return this; } /**  * 设置轮播图需要的数据列表  *  * @param bannerBeanList  * @return BannerM  */ public BannerM setBannerBeanList(List<BannerBean> bannerBeanList) {  this.bannerBeanList = bannerBeanList;  return this; } /**  * 设置图片的点击事件  * @param Listener  */ public BannerM setonItemClickListener(@Nullable OnItemClickListener Listener) {  mOnItemClickListener = Listener;  return this; } public voID show() {  if (bannerBeanList == null || bannerBeanList.size() == 0) {   throw new IllegalArgumentException("bannerBeanList == null");  }  initimageVIEwList();  initIndexList();  vpBanner.addOnPagechangelistener(new OnPagechangelistener());  adapter = new VIEwPagerAdapter();  vpBanner.setAdapter(adapter);  //定时器开始工作  startPlay(); } /**  * 初始化圆点指示器,根据indexposition来加载不同的布局  */ private voID initIndexList() {  int count = bannerBeanList.size();  vList = new ArrayList<>(count);  linearLayout llindex;  if (indexposition == INDEX_position_RIGHT) {   VIEwStub vsIndexRight = (VIEwStub) findVIEwByID(R.ID.vs_index_right);   vsIndexRight.inflate();   llindex = (linearLayout) findVIEwByID(R.ID.ll_index_right);   tvText = (TextVIEw) findVIEwByID(R.ID.tv_text);  } else {   VIEwStub vsIndexBottom = (VIEwStub) findVIEwByID(R.ID.vs_index_bottom);   vsIndexBottom.inflate();   llindex = (linearLayout) findVIEwByID(R.ID.ll_index_bottom);   tvText = (TextVIEw) findVIEwByID(R.ID.tv_text);  }  //默认第一张图片的文字描述  tvText.setText(bannerBeanList.get(0).getText());  //使用GradIEntDrawable构造圆形控件  gradIEntDrawable = new GradIEntDrawable();  gradIEntDrawable.setShape(GradIEntDrawable.oval);  gradIEntDrawable.setcolor(mContext.getResources().getcolor(R.color.text));  gradIEntDrawableSelected = new GradIEntDrawable();  gradIEntDrawableSelected.setShape(GradIEntDrawable.oval);  if (indexcolorResID != 0) {   gradIEntDrawableSelected.setcolor(indexcolorResID);  } else {   gradIEntDrawableSelected.setcolor(mContext.getResources().getcolor(R.color.maincolor));  }  for (int i = 0; i < count; i++) {   VIEw vIEw = new VIEw(mContext);   linearLayout.LayoutParams lpVIEw = new linearLayout.LayoutParams(ConvertM.dp2px(mContext,8),ConvertM.dp2px(mContext,8));   lpVIEw.rightmargin = ConvertM.dp2px(mContext,4);   vIEw.setLayoutParams(lpVIEw);   if (0 == i) {    vIEw.setBackgroundDrawable(gradIEntDrawableSelected);   } else {    vIEw.setBackgroundDrawable(gradIEntDrawable);   }   vIEw.bringToFront();   vList.add(vIEw);   llindex.addVIEw(vIEw);  } } /**  * 初始化ImageVIEw,使用Picasso下载图片,只在SdCard中缓存  */ private voID initimageVIEwList() {  int count = bannerBeanList.size();  ivList = new ArrayList<>(count);  for (int i = 0; i < count; i++) {   final ImageVIEw imageVIEw = new ImageVIEw(mContext);   imageVIEw.setScaleType(ImageVIEw.ScaleType.CENTER_CROP);   ivList.add(imageVIEw);   imageVIEw.setonClickListener(new OnClickListener() {    @OverrIDe    public voID onClick(VIEw v) {     mOnItemClickListener.onItemClick(getposition(imageVIEw));    }   });   if (defaultimageResID != 0) {    Picasso.with(mContext)      .load(bannerBeanList.get(i).getUrl())      .placeholder(defaultimageResID)      .memoryPolicy(MemoryPolicy.NO_CACHE,MemoryPolicy.NO_STORE)      .into(imageVIEw);   } else if (defaultimageDrawable != null) {    Picasso.with(mContext)      .load(bannerBeanList.get(i).getUrl())      .placeholder(defaultimageDrawable)      .memoryPolicy(MemoryPolicy.NO_CACHE,MemoryPolicy.NO_STORE)      .into(imageVIEw);   } else {    Picasso.with(mContext)      .load(bannerBeanList.get(i).getUrl())      .memoryPolicy(MemoryPolicy.NO_CACHE,MemoryPolicy.NO_STORE)      .into(imageVIEw);   }  } } private voID startPlay() {  scheduledexecutorservice = Executors.newSingleThreadScheduledExecutor();  scheduledexecutorservice.scheduleAtFixedrate(new Runnable() {   @OverrIDe   public voID run() {    currentIndex++;    handler.obtainMessage(HANDLE_UPDATE_INDEX).sendToTarget();   }  },intervalTime,TimeUnit.SECONDS); } /**  * 获取点击图片的位置  * @param item  * @return int  */ private int getposition(ImageVIEw item) {  for (int i = 0; i < ivList.size(); i++) {   if (item == ivList.get(i)) {    return i;   }  }  return -1; } @Suppresslint("HandlerLeak") private Handler handler = new Handler() {  @OverrIDe  public voID handleMessage(Message msg) {   switch (msg.what) {    case HANDLE_UPDATE_INDEX:     vpBanner.setCurrentItem(currentIndex);     break;    default:     break;   }  } }; private class OnPagechangelistener implements VIEwPager.OnPagechangelistener {  @OverrIDe  public voID onPageScrolled(int position,float positionOffset,int positionOffsetPixels) {  }  @OverrIDe  public voID onPageSelected(int position) {   currentIndex = position;   for (int i = 0; i < bannerBeanList.size(); i++) {    if (position % ivList.size() == i) {     vList.get(i).setBackgroundDrawable(gradIEntDrawableSelected);    } else {     vList.get(i).setBackgroundDrawable(gradIEntDrawable);    }    tvText.setText(bannerBeanList.get(position % ivList.size()).getText());   }  }  @OverrIDe  public voID onPageScrollStateChanged(int state) {  } } private class VIEwPagerAdapter extends PagerAdapter {  @OverrIDe  public voID destroyItem(VIEw container,int position,Object object) {  }  @OverrIDe  public Object instantiateItem(VIEw container,int position) {   position %= ivList.size();   if (position<0){    position = ivList.size()+position;   }   ImageVIEw imageVIEw = ivList.get(position);   VIEwParent vp =imageVIEw.getParent();   if (vp!=null){    VIEwGroup parent = (VIEwGroup)vp;    parent.removeVIEw(imageVIEw);   }   ((VIEwPager) container).addVIEw(imageVIEw);   return imageVIEw;  }  @OverrIDe  public int getCount() {   return Integer.MAX_VALUE;  }  @OverrIDe  public boolean isVIEwFromObject(VIEw arg0,Object arg1) {   return arg0 == arg1;  }  @OverrIDe  public voID restoreState(Parcelable arg0,ClassLoader arg1) {  }  @OverrIDe  public Parcelable saveState() {   return null;  }  @OverrIDe  public voID startUpdate(VIEw arg0) {  }  @OverrIDe  public voID finishUpdate(VIEw arg0) {  } } public interface OnItemClickListener {  voID onItemClick(int position); }}

这篇文章就介绍到这里了,点击这里查看源码

下面是测试用的图片:

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程小技巧。

您可能感兴趣的文章:Android自定义控件实现简单的轮播图控件Android ViewPager实现轮播图效果Android如何使用RecyclerView打造首页轮播图Android实现基于ViewPager的无限循环自动播放带指示器的轮播图CarouselFigureView控件Android开发在轮播图片上加入点击事件的方法Android实现轮播图无限循环效果Android下拉刷新与轮播图滑动冲突解决方案Android实现自定义轮播图片控件示例Android中用RxJava和ViewPager实现轮播图Android实现ViewPage轮播图效果 总结

以上是内存溢出为你收集整理的Android自定义控件实现优雅的广告轮播图全部内容,希望文章能够帮你解决Android自定义控件实现优雅的广告轮播图所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/web/1142892.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-05-31
下一篇2022-05-31

发表评论

登录后才能评论

评论列表(0条)

    保存