首页 > 代码库 > android ViewPager实现 跑马灯切换图片+多种切换动画

android ViewPager实现 跑马灯切换图片+多种切换动画

最近在弄个项目,要求有跑马灯效果的图片展示。网上搜了一堆,都没有完美实现的算了还是自己写吧!

实现原理利用 ViewPager 控件,这个控件本身就支持滑动翻页很好很强大好多功能都能用上它。利用mViewPager.setCurrentItem(currentIndex); 来实现切换当前显示的view

在加一个定时器不断设置setCurrentItem 来实现跑马灯效果。

一。主要实现类 注释很详细了 一看就知道了

package com.example.marqueeimage;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Timer;
import java.util.TimerTask; 
import com.example.marqueeimage.adapter.MarqueeAdapter;
import com.example.marqueeimage.transforms.ABaseTransformer; 
import android.annotation.SuppressLint; 
import android.content.Context;  
import android.os.Handler;
import android.os.Message;
import android.support.v4.view.ViewPager;
import android.support.v4.view.ViewPager.OnPageChangeListener;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View; 
import android.view.ViewGroup;  
import android.view.animation.AccelerateInterpolator; 
import android.widget.ImageView;
import android.widget.LinearLayout;

public class MarqueeImage extends LinearLayout{
	
	private ViewPager mViewPager;
	private ArrayList<View> mPageViewList=new ArrayList<View>();//数据??
	private ImageView mImageView;
	private ImageView[] mImageViews;
	//主布????部指示当前页面的小圆点视图,LinearLayout
	private ViewGroup indicatorViewGroup;
	private LayoutInflater mInflater;//定义LayoutInflater
	private MarqueeAdapter marqueeAdapter;//适配??
	private Timer mTimer=null;//定时??
	public int currentIndex=0;//当前显示View页面的序号
	private Handler mHandler;//处理更换图片消息
	private FixedSpeedScroller scroller=null;
	private Context mContext;
	
	public MarqueeImage(Context context) {
		super(context);
		init(context); 
	}
	public MarqueeImage(Context context, AttributeSet attrs) {
		super(context, attrs);
		init(context);
	} 
    private void init(Context context){
    	mContext=context;
    	LayoutInflater.from(mContext).inflate(R.layout.marquee_image, this);
		mViewPager = (ViewPager) findViewById(R.id.marquee_image_viewpager);
	    indicatorViewGroup = (ViewGroup) findViewById(R.id.marquee_image_bottomviewgroup);
	    mViewPager.setOnPageChangeListener(new pageChangeListener());
	    mViewPager.setOnTouchListener(new OnTouchListener() { 
			@Override
			public boolean onTouch(View v, MotionEvent event) {
				if(event.getAction()==MotionEvent.ACTION_DOWN){ 
					stopAutoScroller();
		        	setScrollerTime(100); 
				}else if(event.getAction()==MotionEvent.ACTION_UP){
					startAutoScroller();
				}
				return false;
			}
		}); 
	    marqueeAdapter=new MarqueeAdapter();
		mViewPager.setAdapter(marqueeAdapter); 
	    initHandle(); 
	}
    
    /**
     * 设置滑动动画
     *  mViewPager.setPageTransformer(true,new CubeOutTransformer());
	    mViewPager.setPageTransformer(true,new AccordionTransformer());
	    mViewPager.setPageTransformer(true,new FlipHorizontalTransformer());
	    mViewPager.setPageTransformer(true,new RotateUpTransformer());
	    mViewPager.setPageTransformer(true,new ZoomOutTranformer());
	    mViewPager.setPageTransformer(true,new ZoomOutSlideTransformer());
	    mViewPager.setPageTransformer(true,new TabletTransformer());
     */
    public void setScrollerAnimation(ABaseTransformer animation){
    	 mViewPager.setPageTransformer(true,animation);
    }
    /**
     * 开始自动滚动
     */
    public boolean startAutoScroller(){  
    	return startTime();
    }
     /**
      * 停止自动滚动
      */
    public boolean stopAutoScroller(){
    	if(mTimer!=null){
    		mTimer.cancel();
        	mTimer=null;
        	return true;
    	}else{
    	   return false;	
    	} 
    }
	/**
	 * 初始化Handle
	 */
	public void initHandle(){
		 mHandler = new Handler() {
		 	 @SuppressLint("NewApi") public void handleMessage(Message msg) {
		 		  if(msg.what==1){  
				    setScrollerTime(700);
		 			mViewPager.setCurrentItem(currentIndex);
		 			if(mPageViewList.size()-1==currentIndex){ 
		 				currentIndex=0;
		 			}else{ 
				        currentIndex++;
		 			}
		 		  }
		 		};
		 	 };
	}
	/**
	 * 设置滑动时间
	 */
	public void setScrollerTime(int scrollerTime){
		try {
			if(scroller!=null){
				 scroller.setTime(scrollerTime);
			}else{
				Field mScroller;
	            mScroller = ViewPager.class.getDeclaredField("mScroller");
	            mScroller.setAccessible(true); 
	            scroller= new FixedSpeedScroller(mViewPager.getContext(),new AccelerateInterpolator());
	            scroller.setTime(scrollerTime);
	            mScroller.set(mViewPager, scroller);
			} 
        } catch (Exception e) {
        } 
	}
	/**
	 * 创建底部的导航条
	 */
	public void createNavBar(){
		 mImageViews = new ImageView[mPageViewList.size()];
		 for (int i = 0; i < mImageViews.length; i++) {
	        	mImageView = new ImageView(mContext);  
	        	mImageView.setLayoutParams(new LayoutParams(20,20));  
	        	mImageView.setPadding(20, 0, 20, 0);   
	        	if (i == 0) {
	        		mImageView.setBackgroundResource(R.drawable.page_indicator_focused);				
				} else {
					mImageView.setBackgroundResource(R.drawable.page_indicator);
				}
				
	        	mImageViews[i] = mImageView;
	        	
	        	//把指示作用的远点图片加入底部的视图中
	        	indicatorViewGroup.addView(mImageViews[i]);
			}
	 }
	
	class pageChangeListener implements OnPageChangeListener{
		@Override
		public void onPageSelected(int arg0) {
			// TODO Auto-generated method stub
			for (int i = 0; i < mImageViews.length; i++) {
				if(i == arg0) {
					mImageViews[i].setBackgroundResource(R.drawable.page_indicator_focused);
				} else {
					mImageViews[i].setBackgroundResource(R.drawable.page_indicator);
				}
			} 
		} 
		@Override
		public void onPageScrolled(int arg0, float arg1, int arg2) {
			// TODO Auto-generated method stub
			
		} 
		@Override
		public void onPageScrollStateChanged(int arg0) {
			// TODO Auto-generated method stub
			
		}
	}
  /**
   * 启动计时
   */
  private boolean startTime(){
	  if(mTimer==null){
		  mTimer = new Timer(); 
		  mTimer.schedule(new TimerTask() {                        
		        @Override
		        public void run() {
		        	Message msg=new Message();
					msg.what=1;
					mHandler.sendMessage(msg); 
		        }
		     },2000,2000); //每2秒执行一次
		  return true;
	   }else{
		  return false;
	   } 
    }
  /**
   * 设置数据
   * @param mPageViews
   */
   public void setData(ArrayList<View> pageViewList){
	  if(pageViewList!=null){
		  this.mPageViewList=pageViewList;
		  marqueeAdapter.setData(mPageViewList);//添加数据 
		  marqueeAdapter.notifyDataSetChanged();//通知数据发生改变??
		  createNavBar();//根据数据,创建导航条 
	  } 
   }
   /**
    * 清理全部数据
    */
   public void clearData(){
	   if(this.mPageViewList!=null){
		   this.mPageViewList.clear();
	   }
	  mViewPager.removeAllViews();
	  indicatorViewGroup.removeAllViews();
   }
}
 二。ViewPager的适配器也很简单

    

package com.example.marqueeimage.adapter;

import java.util.ArrayList;

import android.os.Parcelable;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.view.View;

/**
 * @author fcm
 * @Create at 2013-8-27 下午2:48:34
 * @Version 1.0
 * <p>
	Features draft description.
	主要功能介绍
   </p>
 */
public class MarqueeAdapter extends PagerAdapter{
	private ArrayList<View> mPageViews=new ArrayList<View>();
	
	/**
	 * 添加数据
	 * @param mPageViews
	 */
	public void setData(ArrayList<View> mPageViews){
		this.mPageViews=mPageViews;
	}
	@Override  
    public int getCount() {  
        return mPageViews.size();  
    }  

    @Override  
    public boolean isViewFromObject(View arg0, Object arg1) {  
        return arg0 == arg1;  
    }  

    @Override  
    public int getItemPosition(Object object) {  
        // TODO Auto-generated method stub  
        return super.getItemPosition(object);  
    }  

    @Override  
    public void destroyItem(View arg0, int arg1, Object arg2) {  
        // TODO Auto-generated method stub  
        ((ViewPager) arg0).removeView(mPageViews.get(arg1));  
    }  

    @Override  
    public Object instantiateItem(View arg0, int arg1) {  
        // TODO Auto-generated method stub  
        ((ViewPager) arg0).addView(mPageViews.get(arg1));  
        return mPageViews.get(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  

    } 
	
}
三。控制滑动速度  这个很重要 设置自动滚动默认的速度的很快 效果很差,用FixedSpeedScroller继承Scroller来实现控制viewpaper滑动速度 这部分来自网络

     

package com.example.marqueeimage;

import android.annotation.SuppressLint;
import android.content.Context;
import android.view.animation.Interpolator;
import android.widget.Scroller;

public class FixedSpeedScroller extends Scroller {

    private int mDuration =500;
    
    public void setTime(int scrollerTime){
    	mDuration=scrollerTime;
    }
    public FixedSpeedScroller(Context context) {
        super(context);
    }

    public FixedSpeedScroller(Context context, Interpolator interpolator) {
        super(context, interpolator);
    }

    @SuppressLint("NewApi") public FixedSpeedScroller(Context context, Interpolator interpolator, boolean flywheel) {
        super(context, interpolator, flywheel);
    }


    @Override
    public void startScroll(int startX, int startY, int dx, int dy, int duration) {
        // Ignore received duration, use fixed one instead
        super.startScroll(startX, startY, dx, dy, mDuration);
    }

    @Override
    public void startScroll(int startX, int startY, int dx, int dy) {
        // Ignore received duration, use fixed one instead
        super.startScroll(startX, startY, dx, dy, mDuration);
    }
}
四。布局文件:

  

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" 
    android:id="@+id/marquee_image_layout"
    android:orientation="vertical">
     
    <!--拖动 -->
   <android.support.v4.view.ViewPager
	        android:id="@+id/marquee_image_viewpager"
	        android:layout_width="wrap_content"
	        android:layout_height="0dp"
	        android:layout_weight="1"  
	        />
   <LinearLayout  
      android:id="@+id/marquee_image_bottomviewgroup"  
      android:layout_width="fill_parent"  
      android:layout_height="wrap_content"    
      android:gravity="center_horizontal"  
      android:orientation="horizontal" >   
   </LinearLayout>   
     
</LinearLayout>
五。 最后一步就是修改默认动画,实现比较绚丽的效果 这部分来自网络 大约有10种左右动画吧

     

    源码下载地址:http://download.csdn.net/download/nn955/7465547