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的适配器也非常easy

    

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

时间: 2024-10-15 11:28:24

android ViewPager实现 跑马灯切换图片+多种切换动画的相关文章

android TextView实现跑马灯效果(字体滚动)

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/activity_main" androi

android 怎么实现跑马灯效果

自定义控件 FocusedTextView, 使android系统误以为它拥有焦点 1 public class FocusedTextView extends TextView { 2 public FocusedTextView(Context context, AttributeSet attrs, int defStyle) { 3 super(context, attrs, defStyle); 4 // TODO Auto-generated constructor stub 5 }

Android:TextView文字跑马灯的效果实现

解决TextView文字显示不全的问题. 简单设置跑马灯的效果: <TextView android:id="@+id/textView" android:layout_width="match_parent" android:layout_height="wrap_content" android:ellipsize="marquee" android:focusable="true" androi

android 自定义文字跑马灯 支持拖拽,按住停止滚动,自定义速度

android的textview自带跑马灯效果,一般使用足够了.不过也有不一般的情况,所以我实现了一个自定义textview控件,用来针对这种不一般情况下的跑马灯效果实现. ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57

android开发_ListView跑马灯

Focus on technology, enjoy life!-- QQ:804212028 浏览链接:http://blog.csdn.net/y18334702058/article/details/44624305 主题:ListView跑马灯 -TextView之所以需要跑马灯,是由于文字太长,或者是为了展现这种效果. 关键代码: android:singleLine="true" android:ellipsize="marquee" android:f

android textview 实现跑马灯效果

跑马灯效果最重要的就是四个属性,分别是: android:ellipsize="marquee" android:focusable="true" android:focusableInTouchMode="true" android:singleLine="true" 控件的宽度,不一定是具体的值,可以是math_parent,如果想让textview中的文字滚动的话,那里面内容的长度肯定是要大于控件的长度的,不然滚动还有啥

Android TextView实现跑马灯

TextView实现跑马灯的效果:例子一: 这个例子可以解决给一个TextView实现跑马灯的效果,但是不能解决给所有的TextView实现跑马灯的效果. <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:singleLine="true" android:ellipsize="marquee&quo

android ellipsize的使用及实现跑马灯效果总结

参考资料: http://blog.csdn.net/huiwolf2008/article/details/7901084 http://www.cnblogs.com/Gaojiecai/archive/2013/06/18/3142783.html 在TextView 和 EditText中,可以使用ellipsize来设置文字溢出隐藏,如:“一段很长的文本...” 用法如下: 在xml中 android:ellipsize = "end" 省略号在结尾 android:elli

Android TextView 横向滚动(跑马灯效果)

Android TextView 中当文字比较多时希望它横向滚动显示,下面是一种亲测可行的方法. 效果图: 1.自定义TextView,重写isFocused()方法返回true,让自定义TextView一直处于获取焦点状态. package com.example.shen.marqueedemo; import android.content.Context; import android.util.AttributeSet; import android.widget.TextView;