尊重作者劳动成果,转载时请标明该文章出自 http://blog.csdn.net/allen315410/article/details/39294343

最近翻看以前的某项目时,发现了一个极其常用的效果——广告条,或者也称不上自定义组件,但是使用频率还是相当普遍的。

打开市面上各大App主界面,或多或少会出现这样的东西,甚至一个应用中出现N多个,这种展示广告的效果,不仅动态效果好,而且众所周知的“不占屏”,想想在手机设备这么小的屏幕尺寸下,能放下几页甚至十几页的广告循环播放,就知道这种广告的使用频率之大了。以下是我收集的部分APP中使用的效果截图:

这些“千万亿”级别的APP都在使用的效果,为什么我们不能效仿追随一下呢,那下面我就开始动手做一个自己的广告条;

要求如下:1,实现多图展示

2,实现手势切换

3,广告图片与广告标语同时切换

4,循环切换,定时循环播放

以下是我的项目结构:

广告条实际上用的是ViewPager来做的,布局中仅仅放了一个ViewPager而已,其它的图片切换都是用ViewPager来展示的,布局如下:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent" ><android.support.v4.view.ViewPagerandroid:id="@+id/viewpager"android:layout_width="match_parent"android:layout_height="200dp" /><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:layout_alignBottom="@id/viewpager"android:background="#33000000"android:orientation="vertical"android:padding="5dp" ><TextViewandroid:id="@+id/tv_image_description"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center_horizontal"android:text="巩俐不低俗,我们也不低俗"android:textColor="@android:color/white" /><LinearLayoutandroid:id="@+id/ll_point_group"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center_horizontal"android:layout_marginTop="5dp"android:orientation="horizontal" ></LinearLayout></LinearLayout></RelativeLayout>

上面的ViewPager用来显示广告图片,下面的LinearLayout嵌在ViewPager底部,实现阴影效果。里面包括TextView来显示广告标语,和一个LinearLayout来显示广告切换状态指示点。写完布局,就可以为这个ViewPager加载数据,增加动态效果了,主要代码如下,注释清晰:

package com.example.banner;import java.util.ArrayList;
import java.util.List;import android.os.Bundle;
import android.os.SystemClock;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v4.view.ViewPager.OnPageChangeListener;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.LinearLayout.LayoutParams;
import android.app.Activity;public class MainActivity extends Activity {private List<ImageView> mImageList;/** 广告条正下方的标语 */private String[] imageDescriptionArray = { //"巩俐不低俗,我就不能低俗", //"扑树又回来啦!再唱经典老歌引万人大合唱", //"揭秘北京电影如何升级", //"乐视网TV版大派送", //"热血屌丝的反杀" };/** 记录上一次点的位置,默认为0 */private int previousPointEnale = 0;private ViewPager mViewPager;private LinearLayout llPointGroup;private TextView tvDescription;/** 记录是否停止循环播放 */private boolean isStop = false;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);init();// 开启子线程,让广告条以2秒的频率循环播放new Thread(new Runnable() {@Overridepublic void run() {while (!isStop) {SystemClock.sleep(2000);runOnUiThread(new Runnable() {public void run() {mViewPager.setCurrentItem(mViewPager.getCurrentItem() + 1);}});}}}).start();}private void init() {llPointGroup = (LinearLayout) findViewById(R.id.ll_point_group);tvDescription = (TextView) findViewById(R.id.tv_image_description);mImageList = new ArrayList<ImageView>();int[] imageIds = new int[] { R.drawable.a, R.drawable.b, R.drawable.c, R.drawable.d, R.drawable.e };ImageView mImageView;LayoutParams params;// 初始化广告条资源for (int id : imageIds) {mImageView = new ImageView(this);mImageView.setBackgroundResource(id);mImageList.add(mImageView);// 初始化广告条正下方的"点"View dot = new View(this);dot.setBackgroundResource(R.drawable.point_background);params = new LayoutParams(5, 5);params.leftMargin = 10;dot.setLayoutParams(params);dot.setEnabled(false);llPointGroup.addView(dot);}mViewPager = (ViewPager) findViewById(R.id.viewpager);mViewPager.setAdapter(new MyAdapter());// 设置广告条跳转时,广告语和状态语的变化mViewPager.setOnPageChangeListener(new MyListener());// 初始化广告条,当前索引Integer.MAX_VALUE的一半int index = (Integer.MAX_VALUE / 2) - (Integer.MAX_VALUE / 2 % mImageList.size());mViewPager.setCurrentItem(index); // 设置当前选中的Page,会触发onPageChangListener.onPageSelected方法}private class MyListener implements OnPageChangeListener {@Overridepublic void onPageScrollStateChanged(int arg0) {// TODO Auto-generated method stub}@Overridepublic void onPageScrolled(int arg0, float arg1, int arg2) {// TODO Auto-generated method stub}@Overridepublic void onPageSelected(int arg0) {// 获取新的位置int newPosition = arg0 % imageDescriptionArray.length;// 设置广告标语tvDescription.setText(imageDescriptionArray[newPosition]);// 消除上一次的状态点llPointGroup.getChildAt(previousPointEnale).setEnabled(false);// 设置当前的状态点“点”llPointGroup.getChildAt(newPosition).setEnabled(true);// 记录位置previousPointEnale = newPosition;}}/*** ViewPager数据适配器*/private class MyAdapter extends PagerAdapter {@Overridepublic int getCount() {// 将viewpager页数设置成Integer.MAX_VALUE,可以模拟无限循环return Integer.MAX_VALUE;}/*** 复用对象 true 复用view false 复用的是Object*/@Overridepublic boolean isViewFromObject(View arg0, Object arg1) {// TODO Auto-generated method stubreturn arg0 == arg1;}/*** 销毁对象* * @param position*            被销毁对象的索引位置*/@Overridepublic void destroyItem(ViewGroup container, int position, Object object) {container.removeView(mImageList.get(position % mImageList.size()));}/*** 初始化一个对象* * @param position*            初始化对象的索引位置*/@Overridepublic Object instantiateItem(ViewGroup container, int position) {container.addView(mImageList.get(position % mImageList.size()));return mImageList.get(position % mImageList.size());}}@Overrideprotected void onDestroy() {// activity销毁时候,关闭循环播放isStop = true;super.onDestroy();}}

需要注意的是,为了达到广告条循环播放的效果,故不能将ViewPager所展示的总数设置较小的定值,这样若ViewPager划过这个定值的时候,页面会定住,用户体验就不太理想化了,为了能达到这个循环的效果,只能将ViewPager展示总数设置成一个很大的值,以便来给用户造成无限循环的假象。那么这个值该取多大合适呢?思前想后,觉得在PagerAdapter的getCount方法中,返回Integer.MAX_VALUE这个值,这个值2147483647,无论如何用户也不可以拿手机没事划上个好几亿次吧。

到此还要注意的地方就是,因为getCount中返回Integer.MAX_VALUE这么大数值,为了达到有图循环的效果,避免Bug,所以其后每次涉及到position索引的地方都得用position和资源尺度取余的结果。

此外,在“点”的初始化的时候,应当设置“点”的索引为int index = (Integer.MAX_VALUE / 2) - (Integer.MAX_VALUE / 2 % mImageList.size());

而不能简单设置成0,若是设置成0,就无法制造出循环播放的“假象”,不信试试设置0,往左滑动。

关于“点”的资源,没有用到图片,下面是资源代码,贴出来:

广告条获得焦点:point_bg_enable.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"android:shape="oval" ><corners android:radius="0.5dp" /><solid android:color="#AAFFFFFF" /></shape>

广告条普通样式:point_bg_normal.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"android:shape="oval" ><corners android:radius="0.5dp" /><solid android:color="#55000000" /></shape>

广告条的状态选择器:point_background.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android"><item android:drawable="@drawable/point_bg_enable" android:state_enabled="true"></item><item android:drawable="@drawable/point_bg_normal" android:state_enabled="false"></item></selector>

以下是效果图:

最后,还需要实现广告的自动循环播放,这个很简单,只要开启一个新线程,在线程中每隔2000ms循环更新一下ViewPager就行。就是在ViewPager中获取当前展示的Item的索引,加上1之后,设置展示这个值即可。还得注意程序的严谨性啊,当activity销毁的时候,这个新线程里负责循环播放的代码是徐璈停止执行的。故设置一个boolean的变量isStop,在while循环的时候,判断是否开启/关闭,在activity的onDestory方法中,设置其为true,即停止循环播放!

源码请在这里下载

Android自定义控件——仿淘宝、网易、彩票等广告条、Banner的制作相关推荐

  1. Android基础控件——ViewFlipper的使用,仿淘宝头条垂直滚动广告条

    ViewFlipper的使用,仿淘宝头条垂直滚动广告条 学习,学习,学以致用 ViewFlipper是安卓自带的控件,很多人可能很少知道这个控件,这个控件很简单,也很好理解,能不能用上实战就看你们的本 ...

  2. Android自定义控件-仿淘宝ios客户端天猫商品详情界面

    仿照淘宝和聚美优品,在商品详情页,向上拖动时,可以加载下一页.使用ViewDragHelper,滑动比较流畅. scrollView滑动到底部的时候,再行向上拖动时,添加了一些阻力. 项目地址:htt ...

  3. Android自定义控件-仿淘宝ios客户端天猫商品详情界面动效

    效果图 源码和例子 github:https://github.com/teisun/Android-PullPushScrollView  csdn:http://download.csdn.net ...

  4. ViewFlipper实现文字轮播(仿淘宝头条垂直滚动广告)

    ViewFlipper实现文字轮播(仿淘宝头条垂直滚动广告) 广告条目可以单独写成布局文件,然后在布局文件或者代码中添加到总布局中 从源码可以看出,其实ViewFlipper间接的继承了FrameLa ...

  5. Android一点 仿淘宝购物车动画

    首先看看ios上的淘宝购物车的动画效果ios淘宝购物车动画 我们实现的效果 看特效是分为两个界面,一个是主view,一个是弹出层.弹出层是用dialog实现的,只是加入了弹出的动画,这里就不分析了,我 ...

  6. 百度地图API,改变驾车路线颜色(仿淘宝快递查询,一条路线两个颜色)

    想仿淘宝做一个物流查询,分为:寄件点.当前点. 收件点 和 路线图. 快递已走的路径(寄件点到当前点的颜色)和未走的路径(当前点到收件点)用 颜色 进行区分. 利用百度地图提供的API(当时遇到了点问 ...

  7. Android——仿淘宝头条垂直滚动广告

    淘宝App大家用的都比较多了哈,最近看淘宝头条比较多,就来写个小例子吧. 垂直滚动广告的实现原理其实比较简单,就是定时更新列表内容嘛,然后列表切换的时候再加点炫酷的动画就OK了.如果对Android控 ...

  8. Android/安卓仿淘宝直播点赞效果/qq空间点赞效果动画

    之前玩淘宝误入它的直播频道,发现它的直播界面的点赞效果挺好看,然后发现QQ控件点赞有类似动画,于是趁有空花了点时间玩玩. 先上个效果图: 添加了一个按钮模拟点赞,点击多少次就出现多个水果,他们的运动轨 ...

  9. Android之仿淘宝商品详情浏览效果

    一:先来几张效果图,没有弄gif动画,也就是商品详情滑动到底部继续上滑查看图文详情. 二:实现步骤: 1.自定义一个父容器ScrollViewContainer装载两个ScrollView. pack ...

最新文章

  1. Linux bash命令操作和VI编辑器操作
  2. 决策树(Decision Tree)原理
  3. Qt Linguist 开发人员 programmers
  4. JAVA中使用XFire调用WebService接口
  5. memcpy和strcpy函数
  6. ISA2006之SP1的作用
  7. 纳英特九宫医疗机器人编程_机器人大赛|我校王子航、阮云天成功进入世界机器人华东赛区决赛...
  8. 微芯片TWIZ5200: W5200 以太网 PICtail Plus 板
  9. 计算机智能化音乐制作,基于单片机的音乐发生器设计.docx
  10. javaweb调用第三方短信接口
  11. linux命令行 teamview,linux下安装team viewer的方法
  12. 保留字符串中的大写字母(汇编语言)
  13. javascript与Jscript区别
  14. 怎么注册Github?用手机2分钟完成注册,互联网就是互相连接
  15. Oracle数据库中,deprecate和desupport的区别,以及Oracle 12.2中的deprecate 的参数
  16. 【图形学】18 光照模型(三、镜面反射的Shader实现)
  17. Python爬虫-专业数据库书名爬取
  18. 打开桌面计算机投屏到扩展屏,电脑投屏到电视显示不完全解决办法
  19. ​LaTex2023 软件下载+TeXstudio编辑器最新版+保姆级安装教程
  20. 阿里 c语言研发笔试题,阿里巴巴集团2014校园招聘笔试题

热门文章

  1. 透过付费通12周年揭秘生活细节中数字背后的内涵
  2. OpenFOAM学习之旅-1
  3. 移植QTE时钟到UP-MobNet-II实验箱LED显示屏
  4. IOS RSA加密解密
  5. 实现分派问题的回溯算法java_工作分配问题 Java 回溯 | 学步园
  6. 在python中超简单安装mxnet_在Docker容器中搭建MXNet/Gluon开发环境
  7. 一文搞懂match、match_phrase与match_phrase_prefix的检索过程
  8. skrollr.js中文教程
  9. 【有用工具】画图工具之Graphviz学习笔记
  10. 顺序栈的实现以及初应用