zoukankan      html  css  js  c++  java
  • ViewPager之引导页

    一、概述

    ViewPager是android-support-v4中提供的类,它是一个容器类,常用于页面之间的切换。

    本文介绍ViewPager最基础的应用:在多个View之间进行切换,亦即ViewPager的每个页面是个View。

    这种模式适合每个页面的逻辑较为简单的情况,比如去实现“小红书”引导页这样的效果:

    二、实现思路

    2.1 页面如何布局

    这个引导页一共有三个页面,毫无疑问上面的标题和配图是隶属于viewpager不同页面内部的,而下面的俩按钮则是直接放在Activity的布局中。

    那indicator呢?虽然在不同的页面红点的位置不一样,但它不能放在页面的布局中,否则,三个点就会跟配图一样整体滑动了……

    2.2 代码如何实现

    ViewPager是什么鬼呢?其实它就是个ViewGroup,用法跟ListView类似,重点在于实现这样一个Adapter:

     1     private class ViewPagerAdapter extends PagerAdapter {
     2         @Override
     3         public int getCount() {
     4             return 0; //ViewPager总共有几个页面
     5         }
     6 
     7         @Override
     8         public boolean isViewFromObject(View view, Object object) {
     9             return false; //判断一个页面(View)是否与instantiateItem方法返回的Object一致
    10         }
    11         
    12         @Override
    13         public Object instantiateItem(ViewGroup container, int position) {
    14             return super.instantiateItem(container, position); //创建一个页面
    15         }
    16         
    17         @Override
    18         public void destroyItem(ViewGroup container, int position, Object object) {
    19             super.destroyItem(container, position, object); //销毁一个页面
    20         }
    21     }

      [转载请保留本文地址:http://www.cnblogs.com/snser/p/5700751.html] 

    三、开始干活

    3.1 摆出activity和每个页面的布局

    viewpager_view.xml (activity的布局)

     1 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
     2     xmlns:tools="http://schemas.android.com/tools"
     3     android:layout_width="match_parent"
     4     android:layout_height="match_parent"
     5     android:background="@drawable/viewpager_view_bg"
     6     tools:context="${relativePackage}.${activityClass}" >
     7     
     8     <android.support.v4.view.ViewPager
     9         android:id="@+id/viewpager_view_pager"
    10         android:layout_width="match_parent"
    11         android:layout_height="match_parent"
    12         android:background="@drawable/viewpager_view_bg" />
    13     
    14     <ImageView 
    15         android:id="@+id/viewpager_view_point"
    16         android:layout_width="66.7dp"
    17         android:layout_height="10dp"
    18         android:layout_centerHorizontal="true"
    19         android:layout_above="@+id/viewpager_view_register"
    20         android:layout_marginBottom="20dp"
    21         android:src="@drawable/viewpager_view_point_1" />
    22     
    23     <Button
    24         android:id="@+id/viewpager_view_register"
    25         android:layout_width="190dp"
    26         android:layout_height="45dp"
    27         android:layout_centerHorizontal="true"
    28         android:layout_above="@+id/viewpager_view_login"
    29         android:layout_marginBottom="10dp"
    30         android:background="@drawable/viewpager_view_register_bg"
    31         android:textSize="19sp"
    32         android:textColor="#FFFFFF"
    33         android:text="@string/viewpager_view_register" />
    34     
    35     <Button
    36         android:id="@+id/viewpager_view_login"
    37         android:layout_width="190dp"
    38         android:layout_height="45dp"
    39         android:layout_alignParentBottom="true"
    40         android:layout_centerHorizontal="true"
    41         android:layout_marginBottom="50dp"
    42         android:background="@drawable/viewpager_view_login_bg"
    43         android:textSize="19sp"
    44         android:textColor="#999999"
    45         android:text="@string/viewpager_view_login" />
    46     
    47 </RelativeLayout>

    viewpager_view_page.xml (页面的布局):

     1 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
     2     xmlns:tools="http://schemas.android.com/tools"
     3     android:layout_width="match_parent"
     4     android:layout_height="match_parent"
     5     tools:context="${relativePackage}.${activityClass}" >
     6     
     7     <TextView
     8         android:id="@+id/viewpager_view_page_title"
     9         android:layout_width="wrap_content"
    10         android:layout_height="wrap_content"
    11         android:layout_marginTop="30dp"
    12         android:layout_centerHorizontal="true"
    13         android:textSize="20sp"
    14         android:textColor="#333333"
    15         android:text="@string/viewpager_view_page_title_1" />
    16     
    17     <ImageView 
    18         android:id="@+id/viewpager_view_page_content"
    19         android:visibility="visible"
    20         android:layout_width="match_parent"
    21         android:layout_height="385dp"
    22         android:layout_marginTop="75dp"
    23         android:layout_gravity="center_horizontal"
    24         android:scaleType="centerInside"
    25         android:src="@drawable/viewpager_view_page_content_1" />
    26     
    27 </RelativeLayout>

    3.2 简要介绍一下即将出炉的核心代码

      1 public class ViewPagerViewActivity extends Activity implements View.OnClickListener {
      2     
      3     private ViewPager mPager;
      4     private ImageView mImgPoint;
      5     
      6     private SparseArray<View> mPageCache = new SparseArray<View>();
      7 
      8     @Override
      9     protected void onCreate(Bundle savedInstanceState) {
     10         super.onCreate(savedInstanceState);
     11         setContentView(R.layout.viewpager_view);
     12         initView();
     13     }
     14     
     15     private void initView() {
     16         mPager = (ViewPager)findViewById(R.id.viewpager_view_pager);
     17         mImgPoint = (ImageView)findViewById(R.id.viewpager_view_point);
     18         mPager.setAdapter(new ViewPagerAdapter(ViewPagerViewActivity.this));
     19         mPager.addOnPageChangeListener(new OnViewPageChangeListener());
     20         findViewById(R.id.viewpager_view_register).setOnClickListener(this);
     21         findViewById(R.id.viewpager_view_login).setOnClickListener(this);
     22     }
     23     
     24     private class ViewPagerAdapter extends PagerAdapter {
     25         private final int mCount = 3;
     26         private LayoutInflater mInflater;
     27         
     28         private ViewPagerAdapter(Context context) {
     29             mInflater = LayoutInflater.from(context);
     30         }
     31 
     32         @Override
     33         public int getCount() {
     34             return mCount;
     35         }
     36 
     37         @Override
     38         public boolean isViewFromObject(View view, Object obj) {
     39             return view == obj;
     40         }
     41         
     42         @Override
     43         public Object instantiateItem(ViewGroup container, int position) {
     44             View page = mPageCache.get(position);
     45             if (page == null) {
     46                 page = mInflater.inflate(R.layout.viewpager_view_page, container, false);
     47                 TextView txtTitle = (TextView)page.findViewById(R.id.viewpager_view_page_title);
     48                 ImageView imgContent = (ImageView)page.findViewById(R.id.viewpager_view_page_content);
     49                 switch (position) {
     50                     case 0:
     51                         txtTitle.setText(R.string.viewpager_view_page_title_1);
     52                         imgContent.setImageResource(R.drawable.viewpager_view_page_content_1);
     53                         break;
     54                     case 1:
     55                         txtTitle.setText(R.string.viewpager_view_page_title_2);
     56                         imgContent.setImageResource(R.drawable.viewpager_view_page_content_2);
     57                         break;
     58                     case 2:
     59                         txtTitle.setText(R.string.viewpager_view_page_title_3);
     60                         imgContent.setImageResource(R.drawable.viewpager_view_page_content_3);
     61                         break;
     62                     default:
     63                         break;
     64                 }
     65                 mPageCache.append(position, page);
     66             }
     67             container.addView(page);
     68             return page;
     69         }
     70         
     71         @Override
     72         public void destroyItem(ViewGroup container, int position, Object object) {
     73             container.removeView((View)object);
     74         }
     75     }
     76     
     77     private class OnViewPageChangeListener implements OnPageChangeListener {
     78         @Override
     79         public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
     80         }
     81 
     82         @Override
     83         public void onPageSelected(int position) {
     84             switch (position) {
     85                 case 0:
     86                     mImgPoint.setImageResource(R.drawable.viewpager_view_point_1);
     87                     break;
     88                 case 1:
     89                     mImgPoint.setImageResource(R.drawable.viewpager_view_point_2);
     90                     break;
     91                 case 2:
     92                     mImgPoint.setImageResource(R.drawable.viewpager_view_point_3);
     93                     break;
     94                 default:
     95                     break;
     96             }
     97         }
     98 
     99         @Override
    100         public void onPageScrollStateChanged(int state) {
    101         }
    102     }
    103 
    104     @Override
    105     public void onClick(View v) {
    106         finish();
    107     }
    108 }

    重点关注下 ViewPagerAdapter :

    在 instantiateItem 方法中会inflate出新的页面,再根据不同的position对页面进行对应的初始化工作,同时在ViewPager中添加当前页面。

    而在 destroyItem 方法中,只需要将当前页面从ViewPager中移除即可。

    同时,需要给ViewPager设置一个 OnPageChangeListener ,以便在页面切换的时候更新Indicator对应的小红点位置。

    3.3 关于缓存

    可以看到,上面的代码在 instantiateItem 方法中用到了页面缓存,亦即每个position对应的页面只需要inflate一次。

    那为什么会有缓存的需求呢?这是因为ViewPager每次加载当前页面的同时,会自动预加载(instantiateItem)与当前页面左右相隔的两个页面,同时会销毁(destroyItem)与当前页面不相邻的页面。

    设想一下,滑动到第三个页面时,第一个页面会被销毁掉,而滑回第二个页面时,又会重新创建第一个页面。如果不加以缓存,就会造成页面的重复inflate从而浪费资源、降低性能。

     [转载请保留本文地址:http://www.cnblogs.com/snser/p/5700751.html] 

    四、demo工程

    保存下面的图片,扩展名改成 .zip 即可

     [转载请保留本文地址:http://www.cnblogs.com/snser/p/5700751.html] 

  • 相关阅读:
    使用C# impersonation进行windows帐号的校验
    今天,如何将你现有的网站移动互联网化【译】
    吐槽一下拖延的生活状态
    Web前端开发工程师编程能力飞升之路【转】
    公司框架集成log4net时遇到的问题
    我所认知的电子商务解决方案
    Web开发攻城狮,欲善其事先利其器
    调用Web Service服务出现响应消息的内容类型text/html与绑定text/xml的内容类型不匹配
    服务器 '***' 上的 MSDTC 不可用
    Firefox中无法使用window.close()关闭窗口
  • 原文地址:https://www.cnblogs.com/snser/p/5700751.html
Copyright © 2011-2022 走看看