前言:经常会看到有一些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;
-
-
-
-
-
-
- public class MainActivity extends Activity {
-
- private List<ImageView> views = new ArrayList<ImageView>();
- private List<ADInfo> infos = new ArrayList<ADInfo>();
- 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 < imageUrls.length; i ++){
- ADInfo info = new ADInfo();
- info.setUrl(imageUrls[i]);
- info.setContent("图片-->" + i );
- infos.add(info);
- }
-
-
- views.add(ViewFactory.getImageView(this, infos.get(infos.size() - 1).getUrl()));
- for (int i = 0; i < infos.size(); i++) {
- views.add(ViewFactory.getImageView(this, infos.get(i).getUrl()));
- }
-
- views.add(ViewFactory.getImageView(this, infos.get(0).getUrl()));
-
-
- cycleViewPager.setCycle(true);
-
-
- cycleViewPager.setData(views, infos, mAdCycleViewListener);
-
- cycleViewPager.setWheel(true);
-
-
- cycleViewPager.setTime(2000);
-
- cycleViewPager.setIndicatorCenter();
- }
-
- private ImageCycleViewListener mAdCycleViewListener = new ImageCycleViewListener() {
-
- @Override
- public void onImageClick(ADInfo info, int position, View imageView) {
- if (cycleViewPager.isCycle()) {
- position = position - 1;
- Toast.makeText(MainActivity.this,
- "position-->" + info.getContent(), Toast.LENGTH_SHORT)
- .show();
- }
-
- }
-
- };
-
-
-
-
- private void configImageLoader() {
-
- @SuppressWarnings("deprecation")
- DisplayImageOptions options = new DisplayImageOptions.Builder().showStubImage(R.drawable.icon_stub)
- .showImageForEmptyUri(R.drawable.icon_empty)
- .showImageOnFail(R.drawable.icon_error)
- .cacheInMemory(true)
- .cacheOnDisc(true)
-
- .build();
-
- ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(getApplicationContext()).defaultDisplayImageOptions(options)
- .threadPriority(Thread.NORM_PRIORITY - 2).denyCacheImageMultipleSizesInMemory()
- .discCacheFileNameGenerator(new Md5FileNameGenerator()).tasksProcessingOrder(QueueProcessingType.LIFO).build();
- ImageLoader.getInstance().init(config);
- }
- }
2.主文件ui_main.xml代码如下:
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="vertical" >
-
-
- <fragment
- android:id="@+id/fragment_cycle_viewpager_content"
- android:name="cn.androiddevelop.cycleviewpager.lib.CycleViewPager"
- android:layout_width="match_parent"
- android:layout_height="180dip" />
-
-
- <RelativeLayout
- android:layout_width="fill_parent"
- android:layout_height="0dip"
- android:layout_weight="1">
-
- <TextView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_centerInParent="true"
- android:text="content"/>
- </RelativeLayout>
-
- </LinearLayout>
3.CycleViewPager类代码如下:
- 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;
-
-
-
-
- @SuppressLint("NewApi")
- public class CycleViewPager extends Fragment implements OnPageChangeListener {
-
- private List<ImageView> imageViews = new ArrayList<ImageView>();
- 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<ADInfo> 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<ImageView> views, List<ADInfo> list, ImageCycleViewListener listener) {
- setData(views, list, listener, 0);
- }
-
-
-
-
-
-
-
-
-
- public void setData(List<ImageView> views, List<ADInfo> 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 < indicators.length; i++) {
- View view = LayoutInflater.from(getActivity()).inflate(
- R.layout.view_cycle_viewpager_indicator, null);
- indicators[i] = (ImageView) view.findViewById(R.id.image_indicator);
- indicatorLayout.addView(view);
- }
-
- adapter = new ViewPagerAdapter();
-
-
- setIndicator(0);
-
- viewPager.setOffscreenPageLimit(3);
- viewPager.setOnPageChangeListener(this);
- viewPager.setAdapter(adapter);
- if (showPosition < 0 || showPosition >= views.size())
- showPosition = 0;
- if (isCycle) {
- showPosition = showPosition + 1;
- }
- viewPager.setCurrentItem(showPosition);
-
- }
-
-
-
-
- public void setIndicatorCenter() {
- RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(
- RelativeLayout.LayoutParams.WRAP_CONTENT,
- RelativeLayout.LayoutParams.WRAP_CONTENT);
- params.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
- params.addRule(RelativeLayout.CENTER_HORIZONTAL);
- indicatorLayout.setLayoutParams(params);
- }
-
-
-
-
-
-
-
- public void setCycle(boolean isCycle) {
- this.isCycle = isCycle;
- }
-
-
-
-
-
-
- public boolean isCycle() {
- return isCycle;
- }
-
-
-
-
-
-
- public void setWheel(boolean isWheel) {
- this.isWheel = isWheel;
- isCycle = true;
- if (isWheel) {
- handler.postDelayed(runnable, time);
- }
- }
-
-
-
-
-
-
- public boolean isWheel() {
- return isWheel;
- }
-
- final Runnable runnable = new Runnable() {
-
- @Override
- public void run() {
- if (getActivity() != null && !getActivity().isFinishing()
- && isWheel) {
- long now = System.currentTimeMillis();
-
- if (now - releaseTime > time - 500) {
- handler.sendEmptyMessage(WHEEL);
- } else {
- handler.sendEmptyMessage(WHEEL_WAIT);
- }
- }
- }
- };
-
-
-
-
- public void releaseHeight() {
- getView().getLayoutParams().height = RelativeLayout.LayoutParams.MATCH_PARENT;
- refreshData();
- }
-
-
-
-
-
-
-
- public void setTime(int time) {
- this.time = time;
- }
-
-
-
-
- public void refreshData() {
- if (adapter != null)
- adapter.notifyDataSetChanged();
- }
-
-
-
-
- public void hide() {
- viewPagerFragmentLayout.setVisibility(View.GONE);
- }
-
-
-
-
-
-
- public BaseViewPager getViewPager() {
- return viewPager;
- }
-
-
-
-
-
-
-
- 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) {
- isScrolling = true;
- return;
- } else if (arg0 == 0) {
- 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);
- }
-
-
-
-
-
-
- public void setScrollable(boolean enable) {
- viewPager.setScrollable(enable);
- }
-
-
-
-
-
-
- public int getCurrentPostion() {
- return currentPosition;
- }
-
-
-
-
-
-
-
- private void setIndicator(int selectedPosition) {
- for (int i = 0; i < indicators.length; i++) {
- indicators[i]
- .setBackgroundResource(R.drawable.icon_point);
- }
- if (indicators.length > selectedPosition)
- indicators[selectedPosition]
- .setBackgroundResource(R.drawable.icon_point_pre);
- }
-
-
-
-
-
- public void disableParentViewPagerTouchEvent(BaseViewPager parentViewPager) {
- if (parentViewPager != null)
- parentViewPager.setScrollable(false);
- }
-
-
-
-
-
-
-
- public static interface ImageCycleViewListener {
-
-
-
-
-
-
-
- public void onImageClick(ADInfo info, int postion, View imageView);
- }
- }
CycleViewPager类为实现可循环,可轮播的ViewPager的核心类,继承自Fragment,具体实现原理就不多说了,代码中都有相关的注释。
ok,接下来的其他类就不多说了。自己下载Demo学习吧。
本博文Demo下载链接地址如下:
http://download.csdn.net/detail/stevenhu_223/8675717
另外,还有一种通过自定义ViewPager实现和本博文相同效果的广告界面Demo,这里就不再贴代码,可以通过如下地址下载:
http://download.csdn.net/detail/stevenhu_223/8697903