在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之仿京东淘宝的自动无限轮播控件的更多相关文章

  1. Android高仿京东淘宝自动无限循环轮播控件的实现思路和过程

    在App的开发中,很多的时候都需要实现类似京东淘宝一样的自动无限轮播的广告栏,所以就自己写了一个,下面是我自定义控件的实现思路和过程. 一.自定义控件属性 新建自定义控件SliderLayout继承于 ...

  2. Android图片轮播控件

    Android广告图片轮播控件,支持无限循环和多种主题,可以灵活设置轮播样式.动画.轮播和切换时间.位置.图片加载框架等! 使用步骤 Step 1.依赖banner Gradle dependenci ...

  3. 一起写一个Android图片轮播控件

    注:本文提到的Android轮播控件Demo地址: Android图片轮播控件 1. 轮播控件的组成部分 我们以知乎日报Android客户端的轮播控件为例,分析一下轮播控件的主要组成: 首先我们要有用 ...

  4. Android 开发最牛的图片轮播控件,基本什么都包含了。

    Android图片轮播控件  源码下载地址: Android 图片轮播 现在的绝大数app都有banner界面,实现循环播放多个广告图片和手动滑动循环等功能.因为ViewPager并不支持循环翻页, ...

  5. 浅谈android中只使用一个TextView实现高仿京东,淘宝各种倒计时

    今天给大家带来的是只使用一个TextView实现一个高仿京东.淘宝.唯品会等各种电商APP的活动倒计时.近期公司一直加班也没来得及时间去整理,今天难得歇息想把这个分享给大家.只求共同学习,以及自己兴许 ...

  6. jQuery仿京东首页广告图片切换图片轮播

    1.效果图如下: 2.源码如下: <!DOCTYPE html> <html lang="en"> <head> <meta charse ...

  7. 小鲜肉初学JS做得仿京东淘宝竖排二级导航

    <!DOCTYPE html><html><head><meta charset="utf-8"><meta http-equ ...

  8. 仿京东淘宝商品详情页属性选择js效果

    在网上找了好久发现都不符合要求就自己摸索写了一个,用到了linq.js这个linq to js 扩展,不然用纯JS遍历json查询要死人啊 demo:http://123.207.28.46:8086 ...

  9. ios之无限 自动 图片轮播器的实现

    比较之前发布的手动无限图片轮播器进行了改进.实现了自动无限轮播的功能.比较适合团购标题分类下面的轮播器功能. 实现思路: * 开启一个定时器,把操作放入消息循环池.每隔一定时间,操作执行一次. * 注 ...

随机推荐

  1. JAVA--可变长参数

    可变长参数: 可变长参数可以接受任意个数的实参,形参实际上是一个数组. 语法形式: 方法名称(类型 参数1,类型 参数2,类型...可变长参数) *可变长参数一定是方法的最后一个参数 public v ...

  2. PLSQL游标使用

    游标是一个指针,它指向一块SQL区域,该区域用于存储处理过来的SELECT或者其他的DML操作返回的数据.由PLSQL创建并管理的游标成为隐式游标,用户创建并管理的成为显示游标.游标可以看做是指向记录 ...

  3. 矢量切片(Vector tile)番外一:Proj4js

    说明:番外篇是对正篇矢量切片(Vector tile)中提到的一些值得继续延伸的关注点继续进行探索和学习,所涉及的内容以解决实际问题为主要导向. 一.新的需求? 在完成了矢量切片的工作后,新的需求出现 ...

  4. 事件详解<一>

    一 扭转对事件的认知 事件,是js和html交互的桥梁.当用户操作页面上的元素,比如点击,鼠标移入移出,然后做一些事情. 你若触发,我便执行--事件发生,调用它的处理函数执行相应的JavaScript ...

  5. java生成二维码

    具体代码如下,作为一个新手,期待与你一起交流: import java.awt.Color; import java.awt.Graphics2D; import java.awt.image.Buf ...

  6. sicily 1063. Who's the Boss 排序+递推

    #include <cstdio> #include <algorithm> using namespace std; struct Emp{ int id, salary, ...

  7. 数据库笔试面试题库(Oracle、MySQL等)

    数据库笔试面试题库(Oracle.MySQL等) 版权声明:版权所有,欢迎分享本文,转载请保留出处,否则追究法律责任,谢谢合作. 注:本文将持续更新,可关注作者微信公众号以便获得最新笔试面试资料. ⊙ ...

  8. How to build mscorlib.dll with visual studio

    Recently, Microsoft Corportation has released a new look for .NET Reference Source. And you may find ...

  9. 基于Asp.Net Core Mvc和EntityFramework Core 的实战入门教程系列-1

    来个目录吧: 第一章 第二章 第三章 暂时就这么多.后面路线更新吧 本系列文章为翻译加上我个人的使用心得理解,希望帮助热爱学习的程序员. 珍重声明:本系列文章会跟原文有点出入,去掉了罗里吧嗦的文字. ...

  10. 图片流量节省大杀器:基于腾讯云CDN的sharpP自适应图片技术实践

    目前移动端运营素材大部分依赖图片,基于对图片流量更少,渲染速度更快的诉求,我们推动CDN,X5内核,即通产品部共同推出了一套业务透明,无痛接入的CDN图片优化方案:基于CDN的sharpP自适应图片无 ...