前言:经常会看到有一些app的banner界面可以实现循环播放多个广告图片和手动滑动循环。本以为单纯的ViewPager就可以实现这些功能。但是蛋疼的事情来了,ViewPager并不支持循环翻页。所以要实现循环还得需要自己去动手。自己在网上也找了些例子,本博文的Demo是结合自己找到的一些相关例子的基础上去改造,也希望对读者有用。
Demo实现的效果图如下:
Demo代码:
工程目录如下图:
废话不多说,上代码。
1.主Activity代码如下:
- package com.stevenhu.android.phone.ui;
- import java.util.ArrayList;
- import java.util.List;
- import com.nostra13.universalimageloader.cache.disc.naming.Md5FileNameGenerator;
- import com.nostra13.universalimageloader.core.DisplayImageOptions;
- import com.nostra13.universalimageloader.core.ImageLoader;
- import com.nostra13.universalimageloader.core.ImageLoaderConfiguration;
- import com.nostra13.universalimageloader.core.assist.QueueProcessingType;
- import com.stevenhu.android.phone.bean.ADInfo;
- import com.stevenhu.android.phone.utils.ViewFactory;
- import android.annotation.SuppressLint;
- import android.app.Activity;
- import android.os.Bundle;
- import android.view.View;
- import android.widget.ImageView;
- import android.widget.Toast;
- import cn.androiddevelop.cycleviewpager.lib.CycleViewPager;
- import cn.androiddevelop.cycleviewpager.lib.CycleViewPager.ImageCycleViewListener;
- /**
- * 描述:主页
- *
- * @author stevenhu
- * @version 2015年5月8日 上午10:47:37
- */
- public class MainActivity extends Activity {
- private List views = new ArrayList();
- private List infos = new ArrayList();
- private CycleViewPager cycleViewPager;
- private String[] imageUrls = {"http://img.taodiantong.cn/v55183/infoimg/2013-07/130720115322ky.jpg",
- "http://pic30.nipic.com/20130626/8174275_085522448172_2.jpg",
- "http://pic18.nipic.com/20111215/577405_080531548148_2.jpg",
- "http://pic15.nipic.com/20110722/2912365_092519919000_2.jpg",
- "http://pic.58pic.com/58pic/12/64/27/55U58PICrdX.jpg"};
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.ui_main);
- configImageLoader();
- initialize();
- }
- @SuppressLint("NewApi")
- private void initialize() {
- cycleViewPager = (CycleViewPager) getFragmentManager()
- .findFragmentById(R.id.fragment_cycle_viewpager_content);
- for(int i = 0; i
- package cn.androiddevelop.cycleviewpager.lib;
- import java.util.ArrayList;
- import java.util.List;
- import android.annotation.SuppressLint;
- import android.app.Fragment;
- import android.os.Bundle;
- import android.os.Message;
- import android.support.v4.view.PagerAdapter;
- import android.support.v4.view.ViewPager.OnPageChangeListener;
- import android.view.LayoutInflater;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.view.ViewGroup;
- import android.widget.FrameLayout;
- import android.widget.ImageView;
- import android.widget.LinearLayout;
- import android.widget.RelativeLayout;
- import com.stevenhu.android.phone.bean.ADInfo;
- import com.stevenhu.android.phone.ui.R;
- /**
- * 实现可循环,可轮播的viewpager
- */
- @SuppressLint("NewApi")
- public class CycleViewPager extends Fragment implements OnPageChangeListener {
- private List imageViews = new ArrayList();
- private ImageView[] indicators;
- private FrameLayout viewPagerFragmentLayout;
- private LinearLayout indicatorLayout; // 指示器
- private BaseViewPager viewPager;
- private BaseViewPager parentViewPager;
- private ViewPagerAdapter adapter;
- private CycleViewPagerHandler handler;
- private int time = 5000; // 默认轮播时间
- private int currentPosition = 0; // 轮播当前位置
- private boolean isScrolling = false; // 滚动框是否滚动着
- private boolean isCycle = false; // 是否循环
- private boolean isWheel = false; // 是否轮播
- private long releaseTime = 0; // 手指松开、页面不滚动时间,防止手机松开后短时间进行切换
- private int WHEEL = 100; // 转动
- private int WHEEL_WAIT = 101; // 等待
- private ImageCycleViewListener mImageCycleViewListener;
- private List infos;
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container,
- Bundle savedInstanceState) {
- View view = LayoutInflater.from(getActivity()).inflate(
- R.layout.view_cycle_viewpager_contet, null);
- viewPager = (BaseViewPager) view.findViewById(R.id.viewPager);
- indicatorLayout = (LinearLayout) view
- .findViewById(R.id.layout_viewpager_indicator);
- viewPagerFragmentLayout = (FrameLayout) view
- .findViewById(R.id.layout_viewager_content);
- handler = new CycleViewPagerHandler(getActivity()) {
- @Override
- public void handleMessage(Message msg) {
- super.handleMessage(msg);
- if (msg.what == WHEEL && imageViews.size() != 0) {
- if (!isScrolling) {
- int max = imageViews.size() + 1;
- int position = (currentPosition + 1) % imageViews.size();
- viewPager.setCurrentItem(position, true);
- if (position == max) { // 最后一页时回到第一页
- viewPager.setCurrentItem(1, false);
- }
- }
- releaseTime = System.currentTimeMillis();
- handler.removeCallbacks(runnable);
- handler.postDelayed(runnable, time);
- return;
- }
- if (msg.what == WHEEL_WAIT && imageViews.size() != 0) {
- handler.removeCallbacks(runnable);
- handler.postDelayed(runnable, time);
- }
- }
- };
- return view;
- }
- public void setData(List views, List list, ImageCycleViewListener listener) {
- setData(views, list, listener, 0);
- }
- /**
- * 初始化viewpager
- *
- * @param views
- * 要显示的views
- * @param showPosition
- * 默认显示位置
- */
- public void setData(List views, List list, ImageCycleViewListener listener, int showPosition) {
- mImageCycleViewListener = listener;
- infos = list;
- this.imageViews.clear();
- if (views.size() == 0) {
- viewPagerFragmentLayout.setVisibility(View.GONE);
- return;
- }
- for (ImageView item : views) {
- this.imageViews.add(item);
- }
- int ivSize = views.size();
- // 设置指示器
- indicators = new ImageView[ivSize];
- if (isCycle)
- indicators = new ImageView[ivSize - 2];
- indicatorLayout.removeAllViews();
- for (int i = 0; i time - 500) {
- handler.sendEmptyMessage(WHEEL);
- } else {
- handler.sendEmptyMessage(WHEEL_WAIT);
- }
- }
- }
- };
- /**
- * 释放指示器高度,可能由于之前指示器被限制了高度,此处释放
- */
- public void releaseHeight() {
- getView().getLayoutParams().height = RelativeLayout.LayoutParams.MATCH_PARENT;
- refreshData();
- }
- /**
- * 设置轮播暂停时间,即没多少秒切换到下一张视图.默认5000ms
- *
- * @param time
- * 毫秒为单位
- */
- public void setTime(int time) {
- this.time = time;
- }
- /**
- * 刷新数据,当外部视图更新后,通知刷新数据
- */
- public void refreshData() {
- if (adapter != null)
- adapter.notifyDataSetChanged();
- }
- /**
- * 隐藏CycleViewPager
- */
- public void hide() {
- viewPagerFragmentLayout.setVisibility(View.GONE);
- }
- /**
- * 返回内置的viewpager
- *
- * @return viewPager
- */
- public BaseViewPager getViewPager() {
- return viewPager;
- }
- /**
- * 页面适配器 返回对应的view
- *
- * @author Yuedong Li
- *
- */
- private class ViewPagerAdapter extends PagerAdapter {
- @Override
- public int getCount() {
- return imageViews.size();
- }
- @Override
- public boolean isViewFromObject(View arg0, Object arg1) {
- return arg0 == arg1;
- }
- @Override
- public void destroyItem(ViewGroup container, int position, Object object) {
- container.removeView((View) object);
- }
- @Override
- public View instantiateItem(ViewGroup container, final int position) {
- ImageView v = imageViews.get(position);
- if (mImageCycleViewListener != null) {
- v.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- mImageCycleViewListener.onImageClick(infos.get(currentPosition - 1), currentPosition, v);
- }
- });
- }
- container.addView(v);
- return v;
- }
- @Override
- public int getItemPosition(Object object) {
- return POSITION_NONE;
- }
- }
- @Override
- public void onPageScrollStateChanged(int arg0) {
- if (arg0 == 1) { // viewPager在滚动
- isScrolling = true;
- return;
- } else if (arg0 == 0) { // viewPager滚动结束
- if (parentViewPager != null)
- parentViewPager.setScrollable(true);
- releaseTime = System.currentTimeMillis();
- viewPager.setCurrentItem(currentPosition, false);
- }
- isScrolling = false;
- }
- @Override
- public void onPageScrolled(int arg0, float arg1, int arg2) {
- }
- @Override
- public void onPageSelected(int arg0) {
- int max = imageViews.size() - 1;
- int position = arg0;
- currentPosition = arg0;
- if (isCycle) {
- if (arg0 == 0) {
- currentPosition = max - 1;
- } else if (arg0 == max) {
- currentPosition = 1;
- }
- position = currentPosition - 1;
- }
- setIndicator(position);
- }
- /**
- * 设置viewpager是否可以滚动
- *
- * @param enable
- */
- public void setScrollable(boolean enable) {
- viewPager.setScrollable(enable);
- }
- /**
- * 返回当前位置,循环时需要注意返回的position包含之前在views最前方与最后方加入的视图,即当前页面试图在views集合的位置
- *
- * @return
- */
- public int getCurrentPostion() {
- return currentPosition;
- }
- /**
- * 设置指示器
- *
- * @param selectedPosition
- * 默认指示器位置
- */
- private void setIndicator(int selectedPosition) {
- for (int i = 0; i selectedPosition)
- indicators[selectedPosition]
- .setBackgroundResource(R.drawable.icon_point_pre);
- }
- /**
- * 如果当前页面嵌套在另一个viewPager中,为了在进行滚动时阻断父ViewPager滚动,可以 阻止父ViewPager滑动事件
- * 父ViewPager需要实现ParentViewPager中的setScrollable方法
- */
- public void disableParentViewPagerTouchEvent(BaseViewPager parentViewPager) {
- if (parentViewPager != null)
- parentViewPager.setScrollable(false);
- }
- /**
- * 轮播控件的监听事件
- *
- * @author minking
- */
- public static interface ImageCycleViewListener {
- /**
- * 单击图片事件
- *
- * @param position
- * @param imageView
- */
- public void onImageClick(ADInfo info, int postion, View imageView);
- }
- }
ok,接下来的其他类就不多说了。自己下载Demo学习吧。
本博文Demo下载链接地址如下:
http://download.csdn.net/detail/stevenhu_223/8675717
另外,还有一种通过自定义ViewPager实现和本博文相同效果的广告界面Demo,这里就不再贴代码,可以通过如下地址下载:
http://download.csdn.net/detail/stevenhu_223/8697903