最近开发中需要做一个类似京东首页那样的广告轮播效果,于是采用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的更多相关文章

  1. Android开发之ViewPager+ActionBar+Fragment实现响应式可滑动Tab

     今天我们要实现的这个效果呢,在Android的应用中十分地常见,我们可以看到下面两张图,无论是系统内置的联系人应用,还是AnyView的阅读器应用,我们总能找到这样的影子,当我们滑动屏幕时,Tab可 ...

  2. Android开发之ViewPager的简单使用

    ViewPager是V4包中的,如果你的编译器敲不出ViewPager,那么你就需要添加,看下面: 第一步:点击+号 第二步:选择第一个Library 第三步:添加这个包: 然后点击ok-->o ...

  3. Android开发之ViewPager

    什么是ViewPager? ViewPager是安卓3.0之后提供的新特性,继承自ViewGroup,专门用以实现左右滑动切换View的效果. 如果想向下兼容就必须要android-support-v ...

  4. Android开发之ViewPager实现多页面切换及动画效果(仿Android的Launcher效果)

    Android开发中经常会有引导页或者切换页面等效果,本文采用ViewPager结合动画效果来实现仿Launcher以及页面切换的效果.源码地址在文章最后给出下载. 效果图如下:       1.Vi ...

  5. Android开发之ViewPager做新手引导界面

    先看一下我们要开发的界面(三张图片,滑到最后一个会出现开始体验的Button,下面的小红点会跟着一起滑动): 首先看一下布局文件: <?xml version="1.0" e ...

  6. 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 ...

  7. 【Android UI】Android开发之View的几种布局方式及实践

    引言 通过前面两篇: Android 开发之旅:又见Hello World! Android 开发之旅:深入分析布局文件&又是“Hello World!” 我们对Android应用程序运行原理 ...

  8. Android开发之PopupWindow

      /* *  Android开发之PopupWindow * *  Created on: 2011-8-8 *  Author: blueeagle *  Email: liujiaxiang@g ...

  9. Android 开发之旅:深入分析布局文件&又是“Hello World!”

    http://www.cnblogs.com/skynet/archive/2010/05/20/1740277.html 引言 上篇可以说是一个分水岭,它标志着我们从Android应用程序理论进入实 ...

随机推荐

  1. IAR ARM、IAR STM8、IAR MSP430共用一个IDE

    转自IAR ARM.IAR STM8.IAR MSP430共用一个IDE 试了安装好多个不同版本不同编译器的IAR,终于明白不同编译器的IAR共用IDE的条件,把几个不同编译器的IAR安装在一起,共用 ...

  2. 【UVA 11183】 Teen Girl Squad (定根MDST)

    [题意] 输入三元组(X,Y,C),有向图,定根0,输出MDST. InputThe first line of input gives the number of cases, N (N < ...

  3. 【BZOJ 2693】jzptab(莫比乌斯+分块)

    2693: jzptab Description Input 一个正整数T表示数据组数 接下来T行 每行两个正整数 表示N.M Output T行 每行一个整数 表示第i组数据的结果 Sample I ...

  4. ANDROID_MARS学习笔记_S02_015_Gson解析json串为对象集合

    package com.example.s02_e12_json3; import java.lang.reflect.Type; import java.util.Iterator; import ...

  5. php获取html checkbox的值。

    一个小错误,搞了好久: <label><input class="short" type="checkbox" id="is_onl ...

  6. 【HDOJ】2612 Find a way

    BFS. #include <iostream> #include <cstdio> #include <cstring> #include <queue&g ...

  7. Makefile第三讲:终端传值给Makefile、Makefile传值给C++代码

    摘要 终端传值给Makefile,咋传?只需在终端输入以下命令,那么就可以在Makefile文件中放心大担的使用$(abcde)这个变量了,它的值为BBB Makefile fun.h #includ ...

  8. An exception occurred during configuration of persistence layer.

    配置文件放在bin文件夹下(注意:hibernate.cfg.xml文件名不要随便改动)

  9. 1002: Prime Path

    题目链接:http://172.16.200.33/JudgeOnline/problem.php?id=1002 题意:给你两个四位数的素数,求最少经过多少步的变化能够从一个素数变到另一个素数.在变 ...

  10. Ext.Net中的Task控件的使用

    在用到Ext.Net中的Task控件的时候,写了一下基本的使用方法: 控件是在TaskManager里面的Tasks下面的Task 此控件的常用属性有,TaskID.Interval(设置间隔时间). ...