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仿京东淘宝自动无限循环轮播控件思路详解,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对脚本之家网站的支持!

时间: 2024-11-02 14:52:29

Android仿京东淘宝自动无限循环轮播控件思路详解的相关文章

Android convinientbanner顶部广告轮播控件使用详解

本文实例为大家分享了convinientbanner顶部广告轮播控件的具体代码,供大家参考,具体内容如下 gradle中添加 compile 'com.bigkoo:convenientbanner:2.0.5' 布局 <com.bigkoo.convenientbanner.ConvenientBanner xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/convenientBa

Android 使用ViewPager自动滚动循环轮播效果_Android

对Android 利用ViewPager实现图片可以左右循环滑动效果,感兴趣的朋友可以直接点击查看内容详情. 主要介绍如何实现ViewPager自动播放,循环滚动的效果及使用.顺便解决ViewPager嵌套(ViewPager inside ViewPager)影响触摸滑动及ViewPager滑动速度设置问题. 先给大家展示下效果图,喜欢的朋友可以下载源码: 1.实现 没有通过ScheduledExecutorService或Timer定期执行某个任务实现,而是简单的通过handler发送消息去

Android中使用TextView实现高仿京东淘宝各种倒计时效果_Android

今天给大家带来的是仅仅使用一个TextView实现一个高仿京东.淘宝.唯品会等各种电商APP的活动倒计时.最近公司一直加班也没来得及时间去整理,今天难得休息想把这个分享给大家,只求共同学习,以及自己后续的复习.为什么会想到使用一个TextView来实现呢?因为最近公司在做一些优化的工作,其中就有一个倒计时样式,原来开发的这个控件的同事使用了多个TextView拼接在一起的,实现的代码冗余比较大,故此项目经理就说:小宏这个就交给你来优化了,并且还要保证有一定的扩展性,当时就懵逼了.不知道从何处开始

Android中使用TextView实现高仿京东淘宝各种倒计时效果

今天给大家带来的是仅仅使用一个TextView实现一个高仿京东.淘宝.唯品会等各种电商APP的活动倒计时.最近公司一直加班也没来得及时间去整理,今天难得休息想把这个分享给大家,只求共同学习,以及自己后续的复习.为什么会想到使用一个TextView来实现呢?因为最近公司在做一些优化的工作,其中就有一个倒计时样式,原来开发的这个控件的同事使用了多个TextView拼接在一起的,实现的代码冗余比较大,故此项目经理就说:小宏这个就交给你来优化了,并且还要保证有一定的扩展性,当时就懵逼了.不知道从何处开始

Android 仿淘宝、京东商品详情页向上拖动查看图文详情控件DEMO详解_Android

一.淘宝商品详情页效果 我们的效果 二.实现思路      使用两个scrollView,两个scrollView 竖直排列,通过自定义viewGroup来控制两个scrollView的竖直排列,以及滑动事件的处理.如下图 三.具体实现 1.继承viewGroup自定义布局View 重写onMeasure()和onLayout方法,在onLayout方法中完成对两个子ScrollView的竖直排列布局,代码如下: 布局文件: <RelativeLayout xmlns:android="h

Android仿美团淘宝实现多级下拉列表菜单功能

我们在常用的电商或者旅游APP中,例如美团,手机淘宝等等,都能够看的到有那种下拉式的二级列表菜单.具体如图所示: 上面两张图就是美团的一个二级列表菜单的一个展示.我相信很多人都想开发一个跟它一样的功能放到自己的APP中.好,接下来我们就开始动手,解决它. 1.结构分析 首先,我们给出这个下拉菜单需要的组建.我们用线框图来分析. 1)如上图所示,最外围的是一个Activity,顶部包含了一个View的容器,这个容器主要是装载ToggleButton来实现诸如美团里面的"美食,全城,理我最近,刷选&

Android ViewPager实现无限循环轮播广告位Banner效果

现在一些app通常会在头部放一个广告位,底部放置一行小圆圈指示器,指示广告位当前的页码,轮播展示一些图片,这些图片来自于网络.这个广告位banner是典型的android ViewPager实现,但是如果自己实现这样的ViewPager,要解决一系列琐碎的问题,比如: (1)这个广告位ViewPager要支持无限循环轮播,例如,有3张图片,A,B,C,当用户滑到最后C时候再滑就要滑到A,反之亦然. (2)ViewPager要实现自动播放,比如每个若干秒如2秒,自动切换播放到下一张图片. (3)通

Android客户端实现图片轮播控件_Android

本文和大家一起写一个Android图片轮播控件,供大家参考,具体内容如下 1. 轮播控件的组成部分     我们以知乎日报Android客户端的轮播控件为例,分析一下轮播控件的主要组成:        首先我们要有用来显示图片的View对象,根据上图中底部中央的5个点,我们知道需要5个ImageView来显示需要轮播的图片,另外还需要5个ImageView来显示5个点.现在考虑以下轮播组件应该具有的行为,首先需要每隔一定时间间隔切换到下一张图片,并且图片间切换的效果应该是平滑的,就像"翻书&qu

Android客户端实现图片轮播控件

本文和大家一起写一个Android图片轮播控件,供大家参考,具体内容如下 1. 轮播控件的组成部分 我们以知乎日报Android客户端的轮播控件为例,分析一下轮播控件的主要组成: 首先我们要有用来显示图片的View对象,根据上图中底部中央的5个点,我们知道需要5个ImageView来显示需要轮播的图片,另外还需要5个ImageView来显示5个点.现在考虑以下轮播组件应该具有的行为,首先需要每隔一定时间间隔切换到下一张图片,并且图片间切换的效果应该是平滑的,就像"翻书"一样.由此我们可