在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
# 循环轮播控件
# Android ViewPager实现无限循环轮播广告位Banner效果
# Android ViewPager循环播放广告实例详解
# Android实现Banner界面广告图片循环轮播(包括实现手动滑动循环)
# Android 使用 ViewPager循环广告位的实现
# Android 使用viewpager实现无限循环(定时+手动)
# Android viewpager中动态添加view并实现伪无限循环的方法
# Android ViewPager实现无限循环效果
# Android实现轮播图无限循环效果
# Android ViewPager实现智能无限循环滚动回绕效果
# Android开发实现广告无限循环功能示例
# 自定义
# 加载
# 淘宝
# 在这里
# 也要
# 京东
# 第一张
# 小编
# 时长
# 往右
# 往左
# 就会
# 是在
# 放在
# 第一个
# 那就
# 在此
# 两种
# 给大家
# 换了
相关文章:
大连网站制作费用,大连新青年网站,五年四班里的视频怎样下载啊?
如何在局域网内绑定自建网站域名?
东莞专业制作网站的公司,东莞大学生网的网址是什么?
如何快速搭建虚拟主机网站?新手必看指南
如何通过PHP快速构建高效问答网站功能?
建站主机选购指南与交易推荐:核心配置解析
建站一年半SEO优化实战指南:核心词挖掘与长尾流量提升策略
如何基于云服务器快速搭建网站及云盘系统?
seo网站制作优化,网站SEO优化步骤有哪些?
广州网站设计制作一条龙,广州巨网网络科技有限公司是干什么的?
云南网站制作公司有哪些,云南最好的招聘网站是哪个?
齐河建站公司:营销型网站建设与SEO优化双核驱动策略
如何选择网络建站服务器?高效建站必看指南
制作企业网站建设方案,怎样建设一个公司网站?
免费制作统计图的网站有哪些,如何看待现如今年轻人买房难的情况?
如何彻底卸载建站之星软件?
宠物网站制作html代码,有没有专门介绍宠物如何养的网站啊?
阿里云网站搭建费用解析:服务器价格与建站成本优化指南
网站制作的软件有哪些,制作微信公众号除了秀米还有哪些比较好用的平台?
视频网站制作教程,怎么样制作优酷网的小视频?
沈阳制作网站公司排名,沈阳装饰协会官方网站?
宝塔新建站点为何无法访问?如何排查?
如何用手机制作网站和网页,手机移动端的网站能制作成中英双语的吗?
微信网站制作公司有哪些,民生银行办理公司开户怎么在微信网页上查询进度?
极客网站有哪些,DoNews、36氪、爱范儿、虎嗅、雷锋网、极客公园这些互联网媒体网站有什么差异?
网站制作大概要多少钱一个,做一个平台网站大概多少钱?
美食网站链接制作教程视频,哪个教做美食的网站比较专业点?
企业在线网站设计制作流程,想建设一个属于自己的企业网站,该如何去做?
家庭建站与云服务器建站,如何选择更优?
怎么将XML数据可视化 D3.js加载XML
b2c电商网站制作流程,b2c水平综合的电商平台?
网站制作中优化长尾关键字挖掘的技巧,建一个视频网站需要多少钱?
建站10G流量真的够用吗?如何应对访问高峰?
Python路径拼接规范_跨平台处理说明【指导】
Swift开发中switch语句值绑定模式
北京制作网站的公司排名,北京三快科技有限公司是做什么?北京三快科技?
高防服务器:AI智能防御DDoS攻击与数据安全保障
七夕网站制作视频,七夕大促活动怎么报名?
如何基于云服务器快速搭建个人网站?
高端企业智能建站程序:SEO优化与响应式模板定制开发
郑州企业网站制作公司,郑州招聘网站有哪些?
长沙做网站要多少钱,长沙国安网络怎么样?
如何用美橙互联一键搭建多站合一网站?
制作网站公司那家好,网络公司是做什么的?
如何高效完成独享虚拟主机建站?
盐城做公司网站,江苏电子版退休证办理流程?
c++如何打印函数堆栈信息_c++ backtrace函数与符号名解析【方法】
孙琪峥织梦建站教程如何优化数据库安全?
如何在自有机房高效搭建专业网站?
如何自定义建站之星网站的导航菜单样式?
*请认真填写需求信息,我们会在24小时内与您取得联系。