Android开发之ViewPager实现轮播图(轮播广告)效果的自定义View
最近开发中需要做一个类似京东首页那样的广告轮播效果,于是采用ViewPager自己自定义了一个轮播图效果的View。
主要原理就是利用定时任务器定时切换ViewPager的页面。
效果图如下:
主页面布局实现如下:
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
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="match_parent" /> <LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:padding="5dp"
android:gravity="center"
android:orientation="horizontal"> <View
android:id="@+id/v_dot1"
android:layout_width="8dp"
android:layout_height="8dp"
android:background="@drawable/dot_black" /> <View
android:id="@+id/v_dot2"
android:layout_width="8dp"
android:layout_height="8dp"
android:layout_marginLeft="5dp"
android:background="@drawable/dot_white" /> <View
android:id="@+id/v_dot3"
android:layout_width="8dp"
android:layout_height="8dp"
android:layout_marginLeft="5dp"
android:background="@drawable/dot_white" /> <View
android:id="@+id/v_dot4"
android:layout_width="8dp"
android:layout_height="8dp"
android:layout_marginLeft="5dp"
android:background="@drawable/dot_white" /> <View
android:id="@+id/v_dot5"
android:layout_width="8dp"
android:layout_height="8dp"
android:layout_marginLeft="5dp"
android:background="@drawable/dot_white" /> </LinearLayout>
</RelativeLayout>
轮播效果视图类代码实现如下:
package com.czm.customview; import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit; import android.content.Context;
import android.graphics.drawable.Drawable;
import android.os.Handler;
import android.os.Message;
import android.os.Parcelable;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v4.view.ViewPager.OnPageChangeListener;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.ImageView.ScaleType; /**
* ViewPager实现的轮播图广告自定义视图,如京东首页的广告轮播图效果;
* 既支持自动轮播页面也支持手势滑动切换页面
* @author caizhiming
*
*/ public class SlideShowView extends FrameLayout { //轮播图图片数量
private final static int IMAGE_COUNT = 5;
//自动轮播的时间间隔
private final static int TIME_INTERVAL = 5;
//自动轮播启用开关
private final static boolean isAutoPlay = true; //自定义轮播图的资源ID
private int[] imagesResIds;
//放轮播图片的ImageView 的list
private List<ImageView> imageViewsList;
//放圆点的View的list
private List<View> dotViewsList; private ViewPager viewPager;
//当前轮播页
private int currentItem = 0;
//定时任务
private ScheduledExecutorService scheduledExecutorService;
//Handler
private Handler handler = new Handler(){ @Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
super.handleMessage(msg);
viewPager.setCurrentItem(currentItem);
} }; public SlideShowView(Context context) {
this(context,null);
// TODO Auto-generated constructor stub
}
public SlideShowView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
// TODO Auto-generated constructor stub
}
public SlideShowView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
// TODO Auto-generated constructor stub
initData();
initUI(context);
if(isAutoPlay){
startPlay();
} }
/**
* 开始轮播图切换
*/
private void startPlay(){
scheduledExecutorService = Executors.newSingleThreadScheduledExecutor();
scheduledExecutorService.scheduleAtFixedRate(new SlideShowTask(), 1, 4, TimeUnit.SECONDS);
}
/**
* 停止轮播图切换
*/
private void stopPlay(){
scheduledExecutorService.shutdown();
}
/**
* 初始化相关Data
*/
private void initData(){
imagesResIds = new int[]{
R.drawable.pic1,
R.drawable.pic2,
R.drawable.pic3,
R.drawable.pic4,
R.drawable.pic5, };
imageViewsList = new ArrayList<ImageView>();
dotViewsList = new ArrayList<View>(); }
/**
* 初始化Views等UI
*/
private void initUI(Context context){
LayoutInflater.from(context).inflate(R.layout.layout_slideshow, this, true);
for(int imageID : imagesResIds){
ImageView view = new ImageView(context);
view.setImageResource(imageID);
view.setScaleType(ScaleType.FIT_XY);
imageViewsList.add(view);
}
dotViewsList.add(findViewById(R.id.v_dot1));
dotViewsList.add(findViewById(R.id.v_dot2));
dotViewsList.add(findViewById(R.id.v_dot3));
dotViewsList.add(findViewById(R.id.v_dot4));
dotViewsList.add(findViewById(R.id.v_dot5)); viewPager = (ViewPager) findViewById(R.id.viewPager);
viewPager.setFocusable(true); viewPager.setAdapter(new MyPagerAdapter());
viewPager.setOnPageChangeListener(new MyPageChangeListener());
} /**
* 填充ViewPager的页面适配器
* @author caizhiming
*/
private class MyPagerAdapter extends PagerAdapter{ @Override
public void destroyItem(View container, int position, Object object) {
// TODO Auto-generated method stub
//((ViewPag.er)container).removeView((View)object);
((ViewPager)container).removeView(imageViewsList.get(position));
} @Override
public Object instantiateItem(View container, int position) {
// TODO Auto-generated method stub
((ViewPager)container).addView(imageViewsList.get(position));
return imageViewsList.get(position);
} @Override
public int getCount() {
// TODO Auto-generated method stub
return imageViewsList.size();
} @Override
public boolean isViewFromObject(View arg0, Object arg1) {
// TODO Auto-generated method stub
return arg0 == arg1;
}
@Override
public void restoreState(Parcelable arg0, ClassLoader arg1) {
// TODO Auto-generated method stub } @Override
public Parcelable saveState() {
// TODO Auto-generated method stub
return null;
} @Override
public void startUpdate(View arg0) {
// TODO Auto-generated method stub } @Override
public void finishUpdate(View arg0) {
// TODO Auto-generated method stub } }
/**
* ViewPager的监听器
* 当ViewPager中页面的状态发生改变时调用
* @author caizhiming
*/
private class MyPageChangeListener implements OnPageChangeListener{ boolean isAutoPlay = false; @Override
public void onPageScrollStateChanged(int arg0) {
// TODO Auto-generated method stub
switch (arg0) {
case 1:// 手势滑动,空闲中
isAutoPlay = false;
break;
case 2:// 界面切换中
isAutoPlay = true;
break;
case 0:// 滑动结束,即切换完毕或者加载完毕
// 当前为最后一张,此时从右向左滑,则切换到第一张
if (viewPager.getCurrentItem() == viewPager.getAdapter().getCount() - 1 && !isAutoPlay) {
viewPager.setCurrentItem(0);
}
// 当前为第一张,此时从左向右滑,则切换到最后一张
else if (viewPager.getCurrentItem() == 0 && !isAutoPlay) {
viewPager.setCurrentItem(viewPager.getAdapter().getCount() - 1);
}
break;
}
} @Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
// TODO Auto-generated method stub } @Override
public void onPageSelected(int pos) {
// TODO Auto-generated method stub currentItem = pos;
for(int i=0;i < dotViewsList.size();i++){
if(i == pos){
((View)dotViewsList.get(pos)).setBackgroundResource(R.drawable.dot_black);
}else {
((View)dotViewsList.get(i)).setBackgroundResource(R.drawable.dot_white);
}
}
} } /**
*执行轮播图切换任务
*@author caizhiming
*/
private class SlideShowTask implements Runnable{ @Override
public void run() {
// TODO Auto-generated method stub
synchronized (viewPager) {
currentItem = (currentItem+1)%imageViewsList.size();
handler.obtainMessage().sendToTarget();
}
} }
/**
* 销毁ImageView资源,回收内存
* @author caizhiming
*/
private void destoryBitmaps() { for (int i = 0; i < IMAGE_COUNT; i++) {
ImageView imageView = imageViewsList.get(i);
Drawable drawable = imageView.getDrawable();
if (drawable != null) {
//解除drawable对view的引用
drawable.setCallback(null);
}
}
} }
如何引用上面自定义的轮播图效果视图View呢?其实很引用普通的View类似,实现如下:
<com.czm.customview.SlideShowView
android:id="@+id/slideshowView"
android:layout_width="335dp"
android:layout_height="120dp"
android:layout_centerHorizontal="true"
/>
Android开发之ViewPager实现轮播图(轮播广告)效果的自定义View的更多相关文章
- Android开发之ViewPager+ActionBar+Fragment实现响应式可滑动Tab
今天我们要实现的这个效果呢,在Android的应用中十分地常见,我们可以看到下面两张图,无论是系统内置的联系人应用,还是AnyView的阅读器应用,我们总能找到这样的影子,当我们滑动屏幕时,Tab可 ...
- Android开发之ViewPager的简单使用
ViewPager是V4包中的,如果你的编译器敲不出ViewPager,那么你就需要添加,看下面: 第一步:点击+号 第二步:选择第一个Library 第三步:添加这个包: 然后点击ok-->o ...
- Android开发之ViewPager
什么是ViewPager? ViewPager是安卓3.0之后提供的新特性,继承自ViewGroup,专门用以实现左右滑动切换View的效果. 如果想向下兼容就必须要android-support-v ...
- Android开发之ViewPager实现多页面切换及动画效果(仿Android的Launcher效果)
Android开发中经常会有引导页或者切换页面等效果,本文采用ViewPager结合动画效果来实现仿Launcher以及页面切换的效果.源码地址在文章最后给出下载. 效果图如下: 1.Vi ...
- Android开发之ViewPager做新手引导界面
先看一下我们要开发的界面(三张图片,滑到最后一个会出现开始体验的Button,下面的小红点会跟着一起滑动): 首先看一下布局文件: <?xml version="1.0" e ...
- Android开发之viewpager导报错误解决方法:错误代码 Caused by: java.lang.ClassNotFoundException: Didn't find class
作者:程序员小冰,CSDN博客:http://blog.csdn.net/qq_21376985 Caused by: java.lang.ClassNotFoundException: Didn't ...
- 【Android UI】Android开发之View的几种布局方式及实践
引言 通过前面两篇: Android 开发之旅:又见Hello World! Android 开发之旅:深入分析布局文件&又是“Hello World!” 我们对Android应用程序运行原理 ...
- Android开发之PopupWindow
/* * Android开发之PopupWindow * * Created on: 2011-8-8 * Author: blueeagle * Email: liujiaxiang@g ...
- Android 开发之旅:深入分析布局文件&又是“Hello World!”
http://www.cnblogs.com/skynet/archive/2010/05/20/1740277.html 引言 上篇可以说是一个分水岭,它标志着我们从Android应用程序理论进入实 ...
随机推荐
- SQL Server 2005 版本的操作系统兼容性详细列表
操作系统要求(32 位) 此表显示对于每种 32 位版本的 SQL Server 2005,操作系统是否可以运行其服务器软件. 有关如何在 Windows Server 2008 上安装 SQL Se ...
- CentOS 如何将.deb 文件 转换.rpm
CentOS 如何将.deb 文件 转换.rpm [root@localhost tmp]#tar zxvf alien_8.88.tar.gz [root@localhost alien]#perl ...
- 在eclipse中使用jetty插件替代m2e开发调试maven web项目
第一步在相应的web项目上配置jetty插件,配置如下: <plugin> <groupId>org.mortbay.jetty</groupId> <art ...
- 【转】BCSphere入门教程01:Immediate Alert--不错
原文网址:http://www.ituring.com.cn/article/117570 写在前面 智能硬件开发的起点是智能硬件,在本教程中的每一章节,首先会列出您的蓝牙智能硬件所需要支持的Serv ...
- 生成AWK快照的方法
1.首先在用oracle用户登陆执行sqlplus命令用dba用户执行: exec DBMS_WORKLOAD_REPOSITORY.CREATE_SNAPSHOT (flush_level=> ...
- calabash-android Win10 入门笔记
参考官方文档:https://developer.xamarin.com/guides/testcloud/calabash/ 概述 Calabash是一个BDD的UI自动化验收测试框架, ...
- 找回linux丢失的磁盘空间
最近一台服务器空间总是报警,磁盘空间不足. 使用 df 命令查看,磁盘空间耗用接近 100%,将机器上过期的数据以及日志清理掉,但是空间很快又是接近 100%. 使用 du 查看,想找出磁盘空间被耗用 ...
- 【转】linux下安装opencv
Installation in Linux These steps have been tested for Ubuntu 10.04 but should work with other distr ...
- nyoj 116 士兵杀敌(二)【线段树单点更新+求和】
士兵杀敌(二) 时间限制:1000 ms | 内存限制:65535 KB 难度:5 描述 南将军手下有N个士兵,分别编号1到N,这些士兵的杀敌数都是已知的. 小工是南将军手下的军师,南将军经常 ...
- nyoj 123 士兵杀敌(四) 树状数组【单点查询+区间修改】
士兵杀敌(四) 时间限制:2000 ms | 内存限制:65535 KB 难度:5 描述 南将军麾下有百万精兵,现已知共有M个士兵,编号为1~M,每次有任务的时候,总会有一批编号连在一起人请战 ...