利用ViewPager实现图片循环滚动

Android中的ListView可以实现屏幕上下滑动来浏览数据,ViewPager则实现了左右滑动的效果。我们可以拿它做很多事情,从最简单的导航,到页面菜单等等。ViewPager类提供了多界面切换的新效果。新效果有如下特征:

[1] 当前显示一组界面中的其中一个界面。

[2] 当用户通过左右滑动界面时,当前的屏幕显示当前界面和下一个界面的一部分。

[3]滑动结束后,界面自动跳转到当前选择的界面中。

下面的代码实现了一个图片循环滚动的功能。首先是布局文件,使用了一个ViewPager控件:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    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" >
    </android.support.v4.view.ViewPager>

    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_alignBottom="@id/viewpager"
        android:background="#33000000"
        android:orientation="vertical"
        android:padding="5dip" >

        <TextView
            android:id="@+id/tv_image_description"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_horizontal"
            android:text="第一个引导页面"
            android:textColor="@android:color/white"
            android:textSize="14sp" />

        <LinearLayout
            android:id="@+id/ll_points"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="5dip"
            android:layout_gravity="center_horizontal"
            android:orientation="horizontal" >
        </LinearLayout>
    </LinearLayout>

</RelativeLayout>

ViewPager的适配器是PagerAdapter,它是基类提供适配器来填充页面ViewPager内部。

接下来实现一个继承PagerAdapter的MyAdapter类,实现一个PagerAdapter,必须至少覆盖以下方法:

instantiateItem(ViewGroup, int)
destroyItem(ViewGroup, int, Object)
getCount()
isViewFromObject(View, Object)
package com.example.viewpagertest;

import java.util.List;

import android.support.v4.view.PagerAdapter;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;

class ViewPagerAdapter extends PagerAdapter {
	private List<ImageView> mImageViewList;
	public ViewPagerAdapter(List<ImageView> imageViewList) {
		super();
		this.mImageViewList = imageViewList;
	}
	/**
	 * 该方法将返回所包含的 Item总个数。为了实现一种循环滚动的效果,返回了基本整型的最大值,这样就会创建很多的Item,
	 * 其实这并非是真正的无限循环。
	 */
	@Override
	public int getCount() {
		return Integer.MAX_VALUE;
	}
         /**
	 * 判断出去的view是否等于进来的view 如果为true直接复用
	 */
	@Override
	public boolean isViewFromObject(View arg0, Object arg1) {
		return arg0 == arg1;
	}
	/**
	 * 销毁预加载以外的view对象, 会把需要销毁的对象的索引位置传进来,就是position,
	 * 因为mImageViewList只有五条数据,而position将会取到很大的值,
	 * 所以使用取余数的方法来获取每一条数据项。
	 */
	@Override
	public void destroyItem(ViewGroup container, int position, Object object) {
		container.removeView(mImageViewList.get(position % mImageViewList.size()));
	}
	/**
	 * 创建一个view,
	 */
	@Override
	public Object instantiateItem(ViewGroup container, int position) {
		container.addView(mImageViewList.get(position % mImageViewList.size()));
		return mImageViewList.get(position % mImageViewList.size());
	}
}
最后是主界面部分的代码:

package com.example.viewpagertest;

import java.util.ArrayList;
import java.util.List;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.SystemClock;
import android.support.v4.view.ViewPager;
import android.support.v4.view.ViewPager.OnPageChangeListener;
import android.view.View;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.LinearLayout.LayoutParams;
import android.widget.TextView;

public class MainActivity extends Activity implements OnPageChangeListener {

	private List<ImageView> imageViewList;
	private TextView tvDescription;
	private LinearLayout llPoints;
	private String[] imageDescriptions;
	private int previousSelectPosition = 0;
	private ViewPager mViewPager;
	private boolean isLoop = true;
	private Handler handler = new Handler() {

		@Override
		public void handleMessage(Message msg) {
			super.handleMessage(msg);

			mViewPager.setCurrentItem(mViewPager.getCurrentItem() + 1);
		}
	};

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setView();
		initView();
	}

	public void setView() {
		setContentView(R.layout.activity_splash_viewpager);

		// 自动切换页面功能
		new Thread(new Runnable() {

			@Override
			public void run() {
				while (isLoop) {
					SystemClock.sleep(2000);
					handler.sendEmptyMessage(0);
				}
			}
		}).start();
	}

	public void initView() {
		mViewPager = (ViewPager) findViewById(R.id.viewpager);
    	tvDescription = (TextView) findViewById(R.id.tv_image_description);
    	llPoints = (LinearLayout) findViewById(R.id.ll_points);
    	
    	prepareData();
    	
    	ViewPagerAdapter adapter = new ViewPagerAdapter(imageViewList);
    	mViewPager.setAdapter(adapter);
    	mViewPager.setOnPageChangeListener(this);
    	
    	tvDescription.setText(imageDescriptions[previousSelectPosition]);
    	llPoints.getChildAt(previousSelectPosition).setEnabled(true);
    	
    	/**
    	 * 2147483647 / 2 = 1073741820 - 1 
    	 * 设置ViewPager的当前项为一个比较大的数,以便一开始就可以左右循环滑动
    	 */
    	int n = Integer.MAX_VALUE / 2 % imageViewList.size();
    	int itemPosition = Integer.MAX_VALUE / 2 - n;
    	
    	mViewPager.setCurrentItem(itemPosition);
	}
	
	 private void prepareData() {
	    	imageViewList = new ArrayList<ImageView>();
	    	int[] imageResIDs = getImageResIDs();
	    	imageDescriptions = getImageDescription();
	    	
	    	ImageView iv;
	    	View view;
	    	for (int i = 0; i < imageResIDs.length; i++) {
				iv = new ImageView(this);
				iv.setBackgroundResource(imageResIDs[i]);
				imageViewList.add(iv);
				
				// 添加点view对象
				view = new View(this);
				view.setBackgroundDrawable(getResources().getDrawable(R.drawable.point_background));
				LayoutParams lp = new LayoutParams(5, 5);
				lp.leftMargin = 10;
				view.setLayoutParams(lp);
				view.setEnabled(false);
				llPoints.addView(view);
			}
	    }
	    
	    private int[] getImageResIDs() {
	    	return new int[]{
	    			R.drawable.bg1,
	    			R.drawable.bg2,
	    			R.drawable.bg3,
	    			R.drawable.pic_01,
	    			R.drawable.pic_02
	    	};
	    }
	    
	    private String[] getImageDescription() {
	    	return new String[]{
	    			"第一个引导页面",
	    			"第二个引导页面",
	    			"第三个引导页面",
	    			"第四个引导页面",
	    			"第五个引导页面"
	    	};
	    }

		@Override
		public void onPageScrollStateChanged(int arg0) {
			
		}

		@Override
		public void onPageScrolled(int arg0, float arg1, int arg2) {
			
		}

		@Override
		public void onPageSelected(int position) {
			// 改变图片的描述信息
			tvDescription.setText(imageDescriptions[position % imageViewList.size()]);
			// 切换选中的点,把前一个点置为normal状态
			llPoints.getChildAt(previousSelectPosition).setEnabled(false);
			// 把当前选中的position对应的点置为enabled状态
			llPoints.getChildAt(position % imageViewList.size()).setEnabled(true);
			previousSelectPosition = position  % imageViewList.size();
		}

	@Override
	protected void onDestroy() {
		super.onDestroy();
		isLoop = false;
	}

}

此处并不是一个真正的无限循环,只是把ViewPager要加载的数据项设置成了一个很大的数值,给人一种感觉是可以无限循环滚动的。这里实现的自动滑动,还有就是监听OnPageChangedListener,实现手动滑动,网上基本都是这种思路,在getCount()中返回一个较大的值,比如500,然后初始时设置mViewPager.currentItem(300或者其他),因为一般人不会划到那么多次。


顺便提一下ViewFlipper和ViewFlow,

1、ViewPager(android.support.v4.view.ViewPager)与ViewFlow都能够使用适配器(ViewPager--PagerAdapter;ViewFlow--BaseAdapter)进行大量数据的适配,并且ViewFlow也带有原点和标题的位置提示,二者比较相像;

2、ViewFlipper使用时主要在有限的少数页面切换中比较合适,并且能够自定义每一个切换动画,用于一个应用间的画面切换比较合适,类似于ActvityGroup;

3、ViewFlow由于提供源码,所以在扩展上更强,可根据需要自行定制,比如加入循环播放等;

4、当需要再一系列不确定数据的View中滑动时,可以考虑使用ViewFlow;如果View数目确定,应该改用Fragments或者兼容库里的ViewPager。

转自:http://m.blog.csdn.net/blog/oWeiXiao123/23455381

参考

http://blog.csdn.net/linghu_java/article/details/8696630




  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值