利用ViewPager实现图片循环滚动

来源:互联网 发布:arp mac地址 编辑:程序博客网 时间:2024/06/07 18:35

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, * 其实这并非是真正的无限循环。 */@Overridepublic int getCount() {return Integer.MAX_VALUE;}         /** * 判断出去的view是否等于进来的view 如果为true直接复用 */@Overridepublic boolean isViewFromObject(View arg0, Object arg1) {return arg0 == arg1;}/** * 销毁预加载以外的view对象, 会把需要销毁的对象的索引位置传进来,就是position, * 因为mImageViewList只有五条数据,而position将会取到很大的值, * 所以使用取余数的方法来获取每一条数据项。 */@Overridepublic void destroyItem(ViewGroup container, int position, Object object) {container.removeView(mImageViewList.get(position % mImageViewList.size()));}/** * 创建一个view, */@Overridepublic 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() {@Overridepublic void handleMessage(Message msg) {super.handleMessage(msg);mViewPager.setCurrentItem(mViewPager.getCurrentItem() + 1);}};@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setView();initView();}public void setView() {setContentView(R.layout.activity_splash_viewpager);// 自动切换页面功能new Thread(new Runnable() {@Overridepublic 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[]{    "第一个引导页面",    "第二个引导页面",    "第三个引导页面",    "第四个引导页面",    "第五个引导页面"    };    }@Overridepublic void onPageScrollStateChanged(int arg0) {}@Overridepublic void onPageScrolled(int arg0, float arg1, int arg2) {}@Overridepublic 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();}@Overrideprotected 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://blog.csdn.net/linghu_java/article/details/8696630


0 0
原创粉丝点击