Android自定义控件——仿淘宝、网易、彩票等广告条、Banner的制作
来源:互联网 发布:jq数组是否包含某值 编辑:程序博客网 时间:2024/06/05 14:32
最近翻看以前的某项目时,发现了一个极其常用的效果——广告条,或者也称不上自定义组件,但是使用频率还是相当普遍的。
打开市面上各大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.ViewPager
- android:id="@+id/viewpager"
- android:layout_width="match_parent"
- android:layout_height="200dp" />
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_alignBottom="@id/viewpager"
- android:background="#33000000"
- android:orientation="vertical"
- android:padding="5dp" >
- <TextView
- android: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" />
- <LinearLayout
- android: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;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- init();
- // 开启子线程,让广告条以2秒的频率循环播放
- new Thread(new Runnable() {
- @Override
- public 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 {
- @Override
- public void onPageScrollStateChanged(int arg0) {
- // TODO Auto-generated method stub
- }
- @Override
- public void onPageScrolled(int arg0, float arg1, int arg2) {
- // TODO Auto-generated method stub
- }
- @Override
- public 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 {
- @Override
- public int getCount() {
- // 将viewpager页数设置成Integer.MAX_VALUE,可以模拟无限循环
- return Integer.MAX_VALUE;
- }
- /**
- * 复用对象 true 复用view false 复用的是Object
- */
- @Override
- public boolean isViewFromObject(View arg0, Object arg1) {
- // TODO Auto-generated method stub
- return arg0 == arg1;
- }
- /**
- * 销毁对象
- *
- * @param position
- * 被销毁对象的索引位置
- */
- @Override
- public void destroyItem(ViewGroup container, int position, Object object) {
- container.removeView(mImageList.get(position % mImageList.size()));
- }
- /**
- * 初始化一个对象
- *
- * @param position
- * 初始化对象的索引位置
- */
- @Override
- public Object instantiateItem(ViewGroup container, int position) {
- container.addView(mImageList.get(position % mImageList.size()));
- return mImageList.get(position % mImageList.size());
- }
- }
- @Override
- protected 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的制作
- Android自定义控件——仿淘宝、网易、彩票等广告条、Banner的制作
- Android自定义控件——仿淘宝、网易、彩票等广告条、Banner的制作
- Android基础控件——ViewFlipper的使用,仿淘宝头条垂直滚动广告条
- Android基础控件——ViewFlipper的使用,仿淘宝头条垂直滚动广告条
- Android基础控件——Dialog的自定义,仿淘宝、天猫、京东等商城广告弹窗
- 自定义控件:垂直轮播的小贴士Banner,仿 淘宝app的“淘宝头条”
- Android【垂直滚动广告条】仿淘宝头条1号店京东—垂直滚动广告条
- Android【垂直滚动广告条】仿淘宝头条1号店京东—垂直滚动广告条
- Android广告条效果--使用Volley实现网络图片的自动轮播(仿淘宝、网易广告页轮播效果)
- 自定义广告Banner条
- Android中仿淘宝头条,自定义控件,向上滚动
- 自定义的android 广告banner
- 自定义View----Banner广告条
- android——仿网易今日头条等自定义频道listview 或者grideview等item上移到另一个view中
- Android仿淘宝头条向上滚动广告条的效果ViewFlipper
- VerticalBannerView 是一个 android 平台下的自定义控件,通常用来展示广告,类似淘宝头条
- Android自定义View——仿1号店垂直滚动广告条实现
- 撰阻追茁足钻租籽奏阻兹族追嘴渍租卓钻
- Android自定义控件——仿ios开关按钮
- VMWare虚拟机下为Ubuntu 12.04.1配置静态IP(NAT方式)
- java.util.Vector中的Vector的详细用法
- 琢赘仔族撞左琢篆总做妆撰踪字昨缀着邹
- Android自定义控件——仿淘宝、网易、彩票等广告条、Banner的制作
- 【水模拟】#62 A. Irrational problem
- S3C2440启动代码2440init.s彻底解析
- android 自定义控件--(圆盘形菜单控件)
- CF 248 C. Ryouko's Memory Note
- abstract 抽象类
- Dijkstra算法
- RMI学习笔记
- 【cocos2d-x-3.1.1系列2】cocos2d-x3.1.1移植安卓过程