使用ViewPager实现左右滑动效果

使用ViewPager实现左右滑动效果

热度 10已有 439 次阅读 2012-5-29 14:20 |系统分类:Android| ViewPager, 滑动效果

        上部分中,我们已经讲解了通过系统提供的ViewFlipper来实现简单的图片滑动的效果。在这部分中,我们来讲解更加复杂的滑动界面是怎么实现的。
 
        在这部分的讲解中,我们使用了Android提供另一个非常有用的控件ViewPager。使用这个控件,需要用到google提到的一个包——android-support-v4.jar,这个包中包含了一些非常有用的类,其中就是ViewPager类来实现页面之间的切换操作,关于android-support-v4.jar的详细信息,大家可以访问google官方网站: http://developer.android.com/sdk/compatibility-library.html。
 
        具体的把Android提供的android-support-v4.jar导入工程,并add build path的方法这里不做介绍,可以参考以上提供的网址,里面会有详细的说明,步骤比较简单。
 
        下面通过两个例子来讲解一下比较复杂的滑动界面的实现。
 
一、Demo1
 
        Demo1实现的效果是我们在浏览新闻网页时经常会看到的,屏幕的上半部分是图片,下半部分是文字的介绍,而顶部是一个导航的工具栏可以供用户选择退出或者回到主菜单等。用户通过左右的滑动屏幕,实现翻页的效果。而在屏幕的最底部,会有对当前所处页面的指示标记。
 
        主布局文件main.xml的内容如下:

[代码]xml代码:

01 <?xml version="1.0" encoding="utf-8"?>
02 <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
03     android:layout_width="fill_parent"
04     android:layout_height="fill_parent"
05     android:orientation="vertical" >
06      
07      <LinearLayout
08         android:layout_width="fill_parent"
09         android:layout_height="wrap_content"
10         android:orientation="vertical" >
11      <include android:id="@+id/item_header"
12           layout="@layout/item_header" />
13      <android.support.v4.view.ViewPager
14          android:id="@+id/myviewpager"
15          android:layout_width="fill_parent"
16          android:layout_height="wrap_content"/>
17      </LinearLayout>
18      
19      <LinearLayout
20         android:layout_width="fill_parent"
21         android:layout_height="fill_parent"
22         android:orientation="vertical" >
23          
24       <RelativeLayout 
25          android:layout_width="fill_parent" 
26          android:layout_height="wrap_content" 
27          android:orientation="vertical" >
28           
29        <LinearLayout 
30           android:id="@+id/mybottomviewgroup" 
31           android:layout_width="fill_parent" 
32           android:layout_height="wrap_content" 
33           android:layout_alignParentBottom="true" 
34           android:layout_marginBottom="40dp" 
35           android:gravity="center_horizontal" 
36           android:orientation="horizontal" 
37            
38        </LinearLayout
39       
40       </RelativeLayout>
41      </LinearLayout>
42       
43 </FrameLayout>
       
        最外层是LinearLayout,其中包括两个Linearlayout,第一个LinearLayout是显示新闻的主界面,而第二个LinearLayout是为了在底部存放指示当前界面的标记图片。值得注意的是第一个LinearLayout中包括又包括两部分,一个是通过include引入的item_header视图,一个是ViewPager控件,在这里还要注意ViewPager空间的布局方式。代码如下:

[代码]xml代码:

01 <LinearLayout
02         android:layout_width="fill_parent"
03         android:layout_height="wrap_content"
04         android:orientation="vertical" >
05      <include android:id="@+id/item_header"
06           layout="@layout/item_header" />
07      <android.support.v4.view.ViewPager
08          android:id="@+id/myviewpager"
09          android:layout_width="fill_parent"
10          android:layout_height="wrap_content"/>
11      </LinearLayout>
       
        另外,在layout文件夹下还定义了item01——item06六个布局文件作为ViewPager的六个页面,在JAVA代码中会把它们分别添加进ViewPager。Item_header.xml布局定义了屏幕上方的导航栏,通过include的方式引入了main.xml布局文件。
 
        Demo1的JAVA代码如下:

[代码]java代码:

001 package com.devdiv.test.ui_test_viewpager;
002  
003 import java.util.ArrayList;
004 import android.app.Activity;
005 import android.content.Context;
006 import android.os.Bundle;
007 import android.os.Parcelable;
008 import android.support.v4.view.PagerAdapter;
009 import android.support.v4.view.ViewPager;
010 import android.support.v4.view.ViewPager.OnPageChangeListener;
011 import android.view.LayoutInflater;
012 import android.view.View;
013 import android.view.ViewGroup;
014 import android.view.ViewGroup.LayoutParams;
015 import android.view.Window;
016 import android.widget.ImageView;
017 public class UI_Test_ViewPagerActivity extends Activity {
018   
019  private ViewPager mViewPager;
020  private ArrayList<View> mPageViews;
021  private ImageView mImageView;
022  private ImageView[] mImageViews;
023   
024  //该应用的主布局LinearLayout
025  private ViewGroup mainViewGroup;
026  //主布局底部指示当前页面的小圆点视图,LinearLayout
027  private ViewGroup indicatorViewGroup;
028   
029  //定义LayoutInflater
030  LayoutInflater mInflater;
031   
032     /** Called when the activity is first created. */
033     @Override
034     public void onCreate(Bundle savedInstanceState) {
035         super.onCreate(savedInstanceState);
036         //setContentView(R.layout.main);
037          
038         //设置窗口无标题
039         requestWindowFeature(Window.FEATURE_NO_TITLE);
040          
041         //mInflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
042         mInflater = getLayoutInflater();
043          
044         mPageViews = new ArrayList<View>();
045         mPageViews.add(mInflater.inflate(R.layout.item01, null));
046         mPageViews.add(mInflater.inflate(R.layout.item02, null));
047         mPageViews.add(mInflater.inflate(R.layout.item03, null));
048         mPageViews.add(mInflater.inflate(R.layout.item04, null));
049         mPageViews.add(mInflater.inflate(R.layout.item05, null));
050         mPageViews.add(mInflater.inflate(R.layout.item06, null));
051          
052         mImageViews = new ImageView[mPageViews.size()];
053          
054         mainViewGroup = (ViewGroup) mInflater.inflate(R.layout.main, null);
055          
056         mViewPager = (ViewPager) mainViewGroup.findViewById(R.id.myviewpager);
057         indicatorViewGroup = (ViewGroup) mainViewGroup.findViewById(R.id.mybottomviewgroup);
058          
059         for (int i = 0; i < mImageViews.length; i++) {
060          mImageView = new ImageView(UI_Test_ViewPagerActivity.this); 
061          mImageView.setLayoutParams(new LayoutParams(20,20)); 
062          mImageView.setPadding(200200); 
063           
064          if (i == 0) {
065           mImageView.setBackgroundResource(R.drawable.page_indicator_focused);   
066    else {
067     mImageView.setBackgroundResource(R.drawable.page_indicator);
068    }
069     
070          mImageViews[i] = mImageView;
071           
072          //把指示作用的远点图片加入底部的视图中
073          indicatorViewGroup.addView(mImageViews[i]);
074   }
075          
076         //注意这两种用法的区别,前者无法正常显示!!
077         //setContentView(R.layout.main);
078         setContentView(mainViewGroup);
079          
080          
081         mViewPager.setAdapter(new MyPagerAdapter());
082         mViewPager.setOnPageChangeListener(new OnPageChangeListener() {
083     
084    @Override
085    public void onPageSelected(int arg0) {
086     // TODO Auto-generated method stub
087     for (int i = 0; i < mImageViews.length; i++) {
088      if(i == arg0) {
089       mImageViews[i].setBackgroundResource(R.drawable.page_indicator_focused);
090      else {
091       mImageViews[i].setBackgroundResource(R.drawable.page_indicator);
092      }
093     }
094    }
095     
096    @Override
097    public void onPageScrolled(int arg0, float arg1, int arg2) {
098     // TODO Auto-generated method stub
099      
100    }
101     
102    @Override
103    public void onPageScrollStateChanged(int arg0) {
104     // TODO Auto-generated method stub
105      
106    }
107   });
108          
109     }
110      
111     class MyPagerAdapter extends PagerAdapter {
112         @Override 
113         public int getCount() { 
114             return mPageViews.size(); 
115         
116    
117         @Override 
118         public boolean isViewFromObject(View arg0, Object arg1) { 
119             return arg0 == arg1; 
120         
121    
122         @Override 
123         public int getItemPosition(Object object) { 
124             // TODO Auto-generated method stub 
125             return super.getItemPosition(object); 
126         
127    
128         @Override 
129         public void destroyItem(View arg0, int arg1, Object arg2) { 
130             // TODO Auto-generated method stub 
131             ((ViewPager) arg0).removeView(mPageViews.get(arg1)); 
132         
133    
134         @Override 
135         public Object instantiateItem(View arg0, int arg1) { 
136             // TODO Auto-generated method stub 
137             ((ViewPager) arg0).addView(mPageViews.get(arg1)); 
138             return mPageViews.get(arg1); 
139         
140    
141         @Override 
142         public void restoreState(Parcelable arg0, ClassLoader arg1) { 
143             // TODO Auto-generated method stub 
144    
145         
146    
147         @Override 
148         public Parcelable saveState() { 
149             // TODO Auto-generated method stub 
150             return null
151         
152    
153         @Override 
154         public void startUpdate(View arg0) { 
155             // TODO Auto-generated method stub 
156    
157         
158    
159         @Override 
160         public void finishUpdate(View arg0) { 
161             // TODO Auto-generated method stub 
162    
163         }
164       
165     }
166      
167 }
 
        其中,需要注意的是在自定义MyPagerAdapter继承自PagerAdapter,需要重写其中的一些重要方法,可以类比BaseAdapter的实现便于理解,具体实现参考API文档。

[代码]java代码:

01 mImageViews = new ImageView[mPageViews.size()];
02          
03         mainViewGroup = (ViewGroup) mInflater.inflate(R.layout.main, null);
04          
05         mViewPager = (ViewPager) mainViewGroup.findViewById(R.id.myviewpager);
06         indicatorViewGroup = (ViewGroup) mainViewGroup.findViewById(R.id.mybottomviewgroup);
07          
08         for (int i = 0; i < mImageViews.length; i++) {
09          mImageView = new ImageView(UI_Test_ViewPagerActivity.this); 
10          mImageView.setLayoutParams(new LayoutParams(20,20)); 
11          mImageView.setPadding(200200); 
12           
13          if (i == 0) {
14           mImageView.setBackgroundResource(R.drawable.page_indicator_focused);   
15    else {
16     mImageView.setBackgroundResource(R.drawable.page_indicator);
17    }
18     
19          mImageViews[i] = mImageView;
20           
21          //把指示作用的远点图片加入底部的视图中
22          indicatorViewGroup.addView(mImageViews[i]);
23   }
 
        根据mPageViews的大小初始化ImageViews,也就是说ViewPager中存在几个Page就初始化几个圆点的图片进行相应的指示。并且根据位置,设置圆点的不同状态,出事情况下显示第一个Page,因此第一个圆点的图片是focused的状态。最后,通过indicatorViewGroup.addView(mImageViews[i])把所有圆点的图片添加到布局中,在屏幕上显示。
 
        底部圆点图片初始化并加入布局后,需要给ViewPager设置Adapter,这里使用的是我们自定义的MyPagerAdapter,然后执行setContentView操作。
 
        最后,为了是底部的圆点视图具有指示作用,需要为ViewPager设置监听器,来根据ViewPager的不同状态,改变底部圆点视图的状态。代码如下:

[代码]java代码:

01 mViewPager.setOnPageChangeListener(new OnPageChangeListener() {
02     
03    @Override
04    public void onPageSelected(int arg0) {
05     // TODO Auto-generated method stub
06     for (int i = 0; i < mImageViews.length; i++) {
07      if(i == arg0) {
08       mImageViews[i].setBackgroundResource(R.drawable.page_indicator_focused);
09      else {
10       mImageViews[i].setBackgroundResource(R.drawable.page_indicator);
11      }
12     }
13    }
14     
15    @Override
16    public void onPageScrolled(int arg0, float arg1, int arg2) {
17     // TODO Auto-generated method stub
18      
19    }
20     
21    @Override
22    public void onPageScrollStateChanged(int arg0) {
23     // TODO Auto-generated method stub
24      
25    }
26   });
27 <font style="BACKGROUND-COLOR: #ffffff" face="Tahoma"></font>
 
 
        Demo1运行效果如下:
 
使用ViewPager实现左右滑动效果_第1张图片
 
图1  Demo1运行效果1
 
 
图2  Demo1运行效果2
 
二、Demo2
       
        Demo2同样实现了左右滑动的效果,不过我们在不同的页面使用了不同的布局,这在实际的应用中也是很常见的。我们同样使用了ViewPager控件,具体方法和Demo1基本相同。
 
        不同在于,我们在两个页面中分别使用了ListView中GridView视图,并在代码中为它们分别绑定了不同的Adapter。ListView使用了简单的ArrayAdapter,显示一组数据。GridView使用了自定义的Adapter。
 
        由于Demo2和Demo1的内容非常相似,我们就不再展开分析,读者可以下载代码查看详细内容。
       
        Demo2运行效果如下:
 
使用ViewPager实现左右滑动效果_第2张图片
 
图3  Demo2运行效果1
 
  使用ViewPager实现左右滑动效果_第3张图片
 
图4  Demo2运行效果2
Demo1源代码下载: UI_Test_ViewPager.rar
Demo2源代码下载: UI_Test_ViewPager3.rar

你可能感兴趣的:(android,viewpager)