
前言
今天给大家带来一个新的控件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自定义控件实现优雅的广告轮播图所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)