Android之仿京东淘宝的自动无限轮播控件
在App的开发中,很多的时候都需要实现类似京东淘宝一样的自动无限轮播的广告栏,所以就自己写了一个,下面是我自定义控件的实现思路和过程。
一、自定义控件属性
新建自定义控件SliderLayout继承于RelativeLayout,首先要考虑的就是自定义的控件需要扩展那些属性,把这些属性列出来。在这里是要实现类似于京东淘宝的无限轮播广告栏,那么首先想到的就是轮播的时长、轮播指示器的样式等等。我在这里列举了一些并且结合到了代码中。
1、扩展属性
(1)是否开启自动轮播的功能。
(2)指示器的图形样式,一般为圆形和方形两种。
(3)指示器的位置,一般为底部或者顶部。
(4)指示器被选中和不被选中时的样式:颜色、高度、宽度、间隔等。
(5)轮播的时长。
(6)加载的如果是网络图片的话,需要默认图片和错误图片等。
2、在attrs.xml文件中添加这些扩展的属性。
<declare-styleable name="SliderLayout">
<attr name="sl_is_auto_play" format="boolean"/>
<attr name="sl_indicator_shape" format="enum">
<enum name="oval" value="0" />
<enum name="rect" value="1" />
</attr>
<attr name="sl_indicator_position" format="enum">
<enum name="centerBottom" value="0" />
<enum name="rightBottom" value="1" />
<enum name="leftBottom" value="2" />
<enum name="centerTop" value="3" />
<enum name="rightTop" value="4" />
<enum name="leftTop" value="5" />
</attr>
<attr name="sl_selected_indicator_color" format="color|reference" />
<attr name="sl_unselected_indicator_color" format="color|reference" /> <attr name="sl_selected_indicator_height" format="dimension|reference" />
<attr name="sl_selected_indicator_width" format="dimension|reference" /> <attr name="sl_unselected_indicator_height" format="dimension|reference" />
<attr name="sl_unselected_indicator_width" format="dimension|reference" /> <attr name="sl_indicator_space" format="dimension|reference" />
<attr name="sl_indicator_margin" format="dimension|reference" />
<attr name="sl_auto_play_duration" format="integer|reference" />
<attr name="sl_default_image" format="reference"/>
<attr name="sl_error_image" format="reference"/>
</declare-styleable>
二、自定义轮播控件的初始化
1、获取到扩展属性的值
在自定义SliderLayout中获取到扩展的样式,然后根据样式获取相应的属性值,最好是要先设置好默认值。
TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.SliderLayout, defStyleAttr, 0);
if (array != null) {
isAutoPlay = array.getBoolean(R.styleable.SliderLayout_sl_is_auto_play, isAutoPlay);
//get the shape of indicator
int intShape = array.getInt(R.styleable.SliderLayout_sl_indicator_shape, indicatorShape.ordinal());
for (IndicatorShape shape : IndicatorShape.values()) {
if (shape.ordinal() == intShape) {
indicatorShape = shape;
break;
}
}
//get the position of indicator
int intPosition = array.getInt(R.styleable.SliderLayout_sl_indicator_position, IndicatorPosition.centerBottom.ordinal());
for (IndicatorPosition position : IndicatorPosition.values()) {
if (position.ordinal() == intPosition) {
indicatorPosition = position;
break;
}
}
unSelectedIndicatorColor = array.getColor(R.styleable.SliderLayout_sl_unselected_indicator_color, unSelectedIndicatorColor);
selectedIndicatorColor = array.getColor(R.styleable.SliderLayout_sl_selected_indicator_color, selectedIndicatorColor);
unSelectedIndicatorHeight = array.getDimension(R.styleable.SliderLayout_sl_unselected_indicator_height, unSelectedIndicatorHeight);
unSelectedIndicatorWidth = array.getDimension(R.styleable.SliderLayout_sl_unselected_indicator_width, unSelectedIndicatorWidth);
selectedIndicatorHeight = array.getDimension(R.styleable.SliderLayout_sl_selected_indicator_height, selectedIndicatorHeight);
selectedIndicatorWidth = array.getDimension(R.styleable.SliderLayout_sl_selected_indicator_width, selectedIndicatorWidth);
indicatorSpace = array.getDimension(R.styleable.SliderLayout_sl_indicator_space, indicatorSpace);
indicatorMargin = array.getDimension(R.styleable.SliderLayout_sl_indicator_margin, indicatorMargin);
autoPlayDuration = array.getInt(R.styleable.SliderLayout_sl_auto_play_duration, autoPlayDuration);
defaultImage = array.getResourceId(R.styleable.SliderLayout_sl_default_image, defaultImage);
errorImage = array.getResourceId(R.styleable.SliderLayout_sl_error_image, errorImage);
}
2、初始化控件
根据这里所需要实现的功能,首先需要一个图像切换器ImageSwticher,还要指示器,这里就用ImageView了。
switcherImage = new ImageSwitcher(context);
switcherImage.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)); for (int i = 0; i < itemCount; i++) {
ImageView indicator = new ImageView(context);
indicator.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
indicator.setPadding((int) (indicatorSpace), (int) (indicatorSpace), (int) (indicatorSpace), (int) (indicatorSpace));
indicator.setImageDrawable(unSelectedDrawable);
indicatorContainer.addView(indicator);
final int finalI = i;
indicator.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
stopAutoPlay();
switchIndicator(finalI);
pictureIndex = finalI;
handler.sendEmptyMessageDelayed(START_AUTO_PLAY,autoPlayDuration);
}
});
}
3、初始化选中第一张图片
专门写一个针对指示器切换的函数,然后在初始化的时候直接调用,选中第一个指示器,就是选中第一张图片了。
函数代码如下。
private void switchIndicator(int index) {
for (int i = 0; i < indicatorContainer.getChildCount(); i++) {
((ImageView) indicatorContainer.getChildAt(i)).setImageDrawable(i == index ? selectedDrawable : unSelectedDrawable);
}
loadImage(index);
}
调用选中第一张图。
switchIndicator(0);
三、图片的加载
1、网路图片的加载
在这里使用Picasso框架来加载图片,根据url来加载显示图片,同时也要显示图片的加载进度,这里就需要一个Dialog提示框了,Dialog的样式最好是可以自定义的。
private void loadNetImage(int pictureIndex) {
if (list != null && list.size() != 0) {
Picasso.with(context)
.load((String) list.get(pictureIndex))
.placeholder(defaultImage)
.error(errorImage)
.tag(context)
.into(mTarget);
}
}
下面是图片的加载提示过程。
private Target mTarget = new Target() {
@Override
public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
dismissDialog();
((ImageView) switcherImage.getCurrentView()).setScaleType(ImageView.ScaleType.CENTER_CROP);
((ImageView) switcherImage.getCurrentView()).setLayoutParams(new ImageSwitcher.LayoutParams(ImageSwitcher.LayoutParams.MATCH_PARENT, ImageSwitcher.LayoutParams.MATCH_PARENT));
((ImageView) switcherImage.getCurrentView()).setImageBitmap(bitmap);
}
@Override
public void onBitmapFailed(Drawable errorDrawable) {
dismissDialog();
((ImageView) switcherImage.getCurrentView()).setImageDrawable(errorDrawable);
}
@Override
public void onPrepareLoad(Drawable placeHolderDrawable) {
showDialog();
}
};
2、加载资源图片
只能加载网络图片是不够的呢,还需要可以加载资源图片,加载资源图片的办法就更加简单了。
private void loadFileImage(int pictureIndex) {
if (list != null && list.size() != 0) {
switcherImage.setImageResource((Integer) list.get(pictureIndex));
}
}
四、设置图片切换的动画
设置图片从左往右以及从右往左的动画效果,并且当滑动到该图片时,指示器也要一起变化,这里就简单说下从左往右的动画了。
private void SliderLeftToRight() {
// get current index
pictureIndex = pictureIndex == 0 ? itemCount - 1
: pictureIndex - 1;
// set Animation
switcherImage.setInAnimation(AnimationUtils.loadAnimation(context,
android.R.anim.slide_in_left));
switcherImage.setOutAnimation(AnimationUtils.loadAnimation(context,
android.R.anim.slide_out_right));
switchIndicator(pictureIndex);
}
从右往左滑动时的代码和这个是一样的,就是换了下方向,需要自己定义下。
五、定义图片的点击事件
1、定义interface来监听事件
在自定义控件中自定义一个interface来监听事件就可以了。
public interface IOnClickListener {
void onItemClick(View view, int position);
}
2、在onTouch中调用点击事件。
这里需要说明下为什么在onTouch中处理,因为onTouch是触摸事件,在滑动的过程中,用户是触摸了屏幕的,所以根据用户触摸屏幕时点击下的X坐标和点击起来时的X坐标的对比来判断是左滑还是右滑了,这样的话,就会和onClick事件相冲了,所以就想到了一个办法,那就是在范围内的话,就默认为点击事件,范围外就是滑动事件了。
if (0==(Math.abs(touchUpX - touchDownX))||(Math.abs(touchUpX - touchDownX))<50) {
if (listener != null) {
stopAutoPlay();
listener.onItemClick(view, pictureIndex);
handler.sendEmptyMessageDelayed(START_AUTO_PLAY,autoPlayDuration);
}
}
六、效果图
说到了这里,应该有所思路了吧,现在就来看下效果吧。

源代码目前已经开放了,放在Github上面,欢迎指导建议。http://www.github.com/LT5505/SliderLayout
Android之仿京东淘宝的自动无限轮播控件的更多相关文章
- Android高仿京东淘宝自动无限循环轮播控件的实现思路和过程
在App的开发中,很多的时候都需要实现类似京东淘宝一样的自动无限轮播的广告栏,所以就自己写了一个,下面是我自定义控件的实现思路和过程. 一.自定义控件属性 新建自定义控件SliderLayout继承于 ...
- Android图片轮播控件
Android广告图片轮播控件,支持无限循环和多种主题,可以灵活设置轮播样式.动画.轮播和切换时间.位置.图片加载框架等! 使用步骤 Step 1.依赖banner Gradle dependenci ...
- 一起写一个Android图片轮播控件
注:本文提到的Android轮播控件Demo地址: Android图片轮播控件 1. 轮播控件的组成部分 我们以知乎日报Android客户端的轮播控件为例,分析一下轮播控件的主要组成: 首先我们要有用 ...
- Android 开发最牛的图片轮播控件,基本什么都包含了。
Android图片轮播控件 源码下载地址: Android 图片轮播 现在的绝大数app都有banner界面,实现循环播放多个广告图片和手动滑动循环等功能.因为ViewPager并不支持循环翻页, ...
- 浅谈android中只使用一个TextView实现高仿京东,淘宝各种倒计时
今天给大家带来的是只使用一个TextView实现一个高仿京东.淘宝.唯品会等各种电商APP的活动倒计时.近期公司一直加班也没来得及时间去整理,今天难得歇息想把这个分享给大家.只求共同学习,以及自己兴许 ...
- jQuery仿京东首页广告图片切换图片轮播
1.效果图如下: 2.源码如下: <!DOCTYPE html> <html lang="en"> <head> <meta charse ...
- 小鲜肉初学JS做得仿京东淘宝竖排二级导航
<!DOCTYPE html><html><head><meta charset="utf-8"><meta http-equ ...
- 仿京东淘宝商品详情页属性选择js效果
在网上找了好久发现都不符合要求就自己摸索写了一个,用到了linq.js这个linq to js 扩展,不然用纯JS遍历json查询要死人啊 demo:http://123.207.28.46:8086 ...
- ios之无限 自动 图片轮播器的实现
比较之前发布的手动无限图片轮播器进行了改进.实现了自动无限轮播的功能.比较适合团购标题分类下面的轮播器功能. 实现思路: * 开启一个定时器,把操作放入消息循环池.每隔一定时间,操作执行一次. * 注 ...
随机推荐
- 【Java深入研究】2、JVM类加载机制
一.先看看编写出的代码的执行过程: 二.研究类加载机制的意义 从上图可以看出,类加载是Java程序运行的第一步,研究类的加载有助于了解JVM执行过程,并指导开发者采取更有效的措施配合程序执行. 研究类 ...
- JAVA中的数据结构 - 真正的去理解红黑树
一, 红黑树所处数据结构的位置: 在JDK源码中, 有treeMap和JDK8的HashMap都用到了红黑树去存储 红黑树可以看成B树的一种: 从二叉树看,红黑树是一颗相对平衡的二叉树 二叉树--&g ...
- 尝试回答js问题
看到@玉伯的这篇文章<Sea.js 源码解析(三)>给的几个问题,在综合下面的评论,写出自己的总结: 我们知道 typeof new String("xxx") 返回 ...
- win8配置JDK
有很多新手朋友对win7 和win8里的环境变量不是很熟悉,下面我整理了一下: 首先要说一下,win7里和win8配置方法是相同的,配置之前先去百度一下 JDK 然后找到自己电脑系统对应的jdk版本下 ...
- 在IntelliJ IDEA 13中配置OpenCV的Java开发环境
准备工作: 下载IDEA 13(这里以版本13为例,后面简称IDEA): 下载Java JDK(用于配置基本的Java开发环境): 下载OpenCV 2.4.9(这里以版本2.4.9为例,据这篇文章说 ...
- JAVA三大特性之二——继承
很多人在学习了JAVA以后,都会了解这个概念,而且继承也会在以后的开发中经常用到,但对于JAVA的继承特性,很多人都了解的不够深入,不够完整,当然这其中包括我,所以我就想抽点时间来整理一下JAVA继承 ...
- windows下读取utf-8文件
#include <stdio.h> #include <tchar.h> #include <memory> int main() { FILE* fp1 = f ...
- 利用jink的驱动软件j-flash 合并两个hex的方法,bootloader+app
由于前几天要给工厂app和bootloader的hex的文件,网上很多都是bin的合并方法,bin的方法不再赘述,相信大家都能找到,现在将hex合并的方法写下来: 第一步:先打开第一个hex文件, 第 ...
- 第28篇 js中let和var
let与var 在js中声明一个变量除了一个var 还有一个let的声明.对于var 在前面的作用域中已经讲过,这次主要说下二者的区别: 在MDN上有这样的一个demo: var list = d ...
- 程序员的自我修养:高效使用Google解决问题
如果票选近二十年最伟大的发明,我相信搜索引擎肯定会占据一个不容小觑的位置,它不单是一项发明,更是一项成就,最大程度消灭了信息的不平等.既然人人都可以接触到海量的信息,那么衡量信息财富多寡就只剩下技巧这 ...