Android高手进阶教程(二十八)之---Android ViewPager控件的使用(基于ViewPager的横向相册)!!!

分类: Android高手进阶 Android基础教程 2012-09-14 18:10 29759人阅读 评论(35) 收藏 举报

android相册layoutobjectclassloaderencoding

大家好,相信大家用的ListView控件一定很多的,是竖向滑动的,复用convertView,我们可以加载成千上万的数据,但有时候我们会有 这个需求比如相册,我们想横向滑动,并且数据有好多,这时候ViewPager控件就派上用场了,ViewPager使用时候我们需要导入第三方包 android-support-v4.jar包,这是谷歌提供的,这个包里有Fragment ViewPager等控件,用户导入这个包,在3.0以前就可以使用Fragment控件了~

下面就开始讲下ViewPager的用 法,ViewPager和ViewFlipper用法类似,但是更好用,左右滑动效果好,而且有类似于ListView的Adapter--- PagerAdapter基类,这样的话可以回收内存,复用等。PagerAdapter的几个方法里常用的有:

[java] view plaincopy

  1. void destroyItem(View container, int position, Object object)
  2. 这里是左右滑动的时候,回收较早前的itemView.

[java] view plaincopy

  1. int getCount()
  2. ViewPager里显示内容的条数.

[java] view plaincopy

  1. Object instantiateItem(View container, int position)
  2. 始化ItemView.

为 了让大家容易掌握,我写了一个简单的例子,简单实现相册横向滑动功能,首先自定义了ViewPager的itemView---- ViewPagerItemView,这里做了初始化View的定义,以及回收内存重新加载等,数据源是JSONObject.其次是实现了 PagerAdapter的适配器ViewPagerAdater,这里的数据源是JSONArray.然后ViewPager在名为 ViewPagerDemoActivity.java的Activity里显示。下面是具体实现步骤:

第一步:新建一个Android工程ViewPagerDemoActivity,目录结构如下图所示:

第二步:新建一个ViewPagerItemView.java这里是相册的ItemView,代码如下:

[java] view plaincopy

  1. package com.tutor.viewpager;
  2. import org.json.JSONException;
  3. import org.json.JSONObject;
  4. import android.content.Context;
  5. import android.graphics.Bitmap;
  6. import android.util.AttributeSet;
  7. import android.view.LayoutInflater;
  8. import android.view.View;
  9. import android.widget.FrameLayout;
  10. import android.widget.ImageView;
  11. import android.widget.TextView;
  12. /**
  13. * @author frankiewei
  14. * 相册的ItemView,自定义View.方便复用.
  15. */
  16. public class ViewPagerItemView extends FrameLayout {
  17. /**
  18. * 图片的ImageView.
  19. */
  20. private ImageView mAlbumImageView;
  21. /**
  22. * 图片名字的TextView.
  23. */
  24. private TextView mALbumNameTextView;
  25. /**
  26. * 图片的Bitmap.
  27. */
  28. private Bitmap mBitmap;
  29. /**
  30. * 要显示图片的JSONOBject类.
  31. */
  32. private JSONObject mObject;
  33. public ViewPagerItemView(Context context){
  34. super(context);
  35. setupViews();
  36. }
  37. public ViewPagerItemView(Context context, AttributeSet attrs) {
  38. super(context, attrs);
  39. setupViews();
  40. }
  41. //初始化View.
  42. private void setupViews(){
  43. LayoutInflater inflater = LayoutInflater.from(getContext());
  44. View view = inflater.inflate(R.layout.viewpager_itemview, null);
  45. mAlbumImageView = (ImageView)view.findViewById(R.id.album_imgview);
  46. mALbumNameTextView = (TextView)view.findViewById(R.id.album_name);
  47. addView(view);
  48. }
  49. /**
  50. * 填充数据,共外部调用.
  51. * @param object
  52. */
  53. public void setData(JSONObject object){
  54. this.mObject = object;
  55. try {
  56. int resId = object.getInt("resid");
  57. String name = object.getString("name");
  58. //实战中如果图片耗时应该令其一个线程去拉图片异步,不然把UI线程卡死.
  59. mAlbumImageView.setImageResource(resId);
  60. mALbumNameTextView.setText(name);
  61. } catch (JSONException e) {
  62. e.printStackTrace();
  63. }
  64. }
  65. /**
  66. * 这里内存回收.外部调用.
  67. */
  68. public void recycle(){
  69. mAlbumImageView.setImageBitmap(null);
  70. if ((this.mBitmap == null) || (this.mBitmap.isRecycled()))
  71. return;
  72. this.mBitmap.recycle();
  73. this.mBitmap = null;
  74. }
  75. /**
  76. * 重新加载.外部调用.
  77. */
  78. public void reload(){
  79. try {
  80. int resId = mObject.getInt("resid");
  81. //实战中如果图片耗时应该令其一个线程去拉图片异步,不然把UI线程卡死.
  82. mAlbumImageView.setImageResource(resId);
  83. }catch (JSONException e) {
  84. e.printStackTrace();
  85. }
  86. }
  87. }

其中ViewPagerItemView使用的xml文件viewpager_itemView.xml代码如下:

[java] view plaincopy

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. android:layout_width="fill_parent"
  4. android:layout_height="fill_parent"
  5. >
  6. <ImageView
  7. android:id="@+id/album_imgview"
  8. android:layout_width="fill_parent"
  9. android:layout_height="fill_parent"
  10. android:contentDescription="@string/app_name"
  11. android:scaleType="fitXY"
  12. />
  13. <TextView
  14. android:id="@+id/album_name"
  15. android:layout_width="wrap_content"
  16. android:layout_height="wrap_content"
  17. android:layout_gravity="bottom|center_horizontal"
  18. android:textColor="#B2191919"
  19. />
  20. </FrameLayout>

第三步:新建一个ViewPagerAdapter.java继承与PagerAdapter,代码如下:

[java] view plaincopy

  1. package com.tutor.viewpager;
  2. import java.util.HashMap;
  3. import org.json.JSONArray;
  4. import org.json.JSONException;
  5. import org.json.JSONObject;
  6. import android.content.Context;
  7. import android.os.Parcelable;
  8. import android.support.v4.view.PagerAdapter;
  9. import android.support.v4.view.ViewPager;
  10. import android.view.View;
  11. /**
  12. * @author frankiewei
  13. * 相册的适配器.
  14. */
  15. public class ViewPagerAdapter extends PagerAdapter {
  16. /**
  17. * 上下文
  18. */
  19. private Context mContext;
  20. /**
  21. * 数据源,这里是JSONARRAY
  22. */
  23. private JSONArray mJsonArray;
  24. /**
  25. * Hashmap保存相片的位置以及ItemView.
  26. */
  27. private HashMap<Integer, ViewPagerItemView> mHashMap;
  28. public ViewPagerAdapter(Context context,JSONArray arrays) {
  29. this.mContext = context;
  30. this.mJsonArray = arrays;
  31. mHashMap = new HashMap<Integer, ViewPagerItemView>();
  32. }
  33. //这里进行回收,当我们左右滑动的时候,会把早期的图片回收掉.
  34. @Override
  35. public void destroyItem(View container, int position, Object object) {
  36. ViewPagerItemView itemView = (ViewPagerItemView)object;
  37. itemView.recycle();
  38. }
  39. @Override
  40. public void finishUpdate(View view) {
  41. }
  42. //这里返回相册有多少条,和BaseAdapter一样.
  43. @Override
  44. public int getCount() {
  45. return mJsonArray.length();
  46. }
  47. //这里就是初始化ViewPagerItemView.如果ViewPagerItemView已经存在,
  48. //重新reload,不存在new一个并且填充数据.
  49. @Override
  50. public Object instantiateItem(View container, int position) {
  51. ViewPagerItemView itemView;
  52. if(mHashMap.containsKey(position)){
  53. itemView = mHashMap.get(position);
  54. itemView.reload();
  55. }else{
  56. itemView = new ViewPagerItemView(mContext);
  57. try {
  58. JSONObject dataObj = (JSONObject) mJsonArray.get(position);
  59. itemView.setData(dataObj);
  60. } catch (JSONException e) {
  61. e.printStackTrace();
  62. }
  63. mHashMap.put(position, itemView);
  64. ((ViewPager) container).addView(itemView);
  65. }
  66. return itemView;
  67. }
  68. @Override
  69. public boolean isViewFromObject(View view, Object object) {
  70. return view == object;
  71. }
  72. @Override
  73. public void restoreState(Parcelable arg0, ClassLoader arg1) {
  74. }
  75. @Override
  76. public Parcelable saveState() {
  77. return null;
  78. }
  79. @Override
  80. public void startUpdate(View view) {
  81. }
  82. }

第四步:修改主Activity类ViewPagerDemoActivity.java代码如下:

[java] view plaincopy

  1. package com.tutor.viewpager;
  2. import org.json.JSONArray;
  3. import org.json.JSONException;
  4. import org.json.JSONObject;
  5. import android.app.Activity;
  6. import android.os.Bundle;
  7. import android.support.v4.view.ViewPager;
  8. /**
  9. * @author frankiewei
  10. * ViewPager控件使用的Demo.
  11. */
  12. public class ViewPagerDemoActivity extends Activity {
  13. /**
  14. * 这里定义了相册的总数100条.
  15. */
  16. private static final int ALBUM_COUNT = 100;
  17. /**
  18. * 相册的资源,实战开发中都是网络数据或者本地相册.
  19. */
  20. private static final int ALBUM_RES[] = {
  21. R.drawable.test1,R.drawable.test2,R.drawable.test3,
  22. R.drawable.test4,R.drawable.test5,R.drawable.test6
  23. };
  24. private ViewPager mViewPager;
  25. /**
  26. * 适配器.
  27. */
  28. private ViewPagerAdapter mViewPagerAdapter;
  29. /**
  30. * 数据源.
  31. */
  32. private JSONArray mJsonArray;
  33. @Override
  34. public void onCreate(Bundle savedInstanceState) {
  35. super.onCreate(savedInstanceState);
  36. setContentView(R.layout.main);
  37. setupViews();
  38. }
  39. private void setupViews(){
  40. //初始化JSonArray,给ViewPageAdapter提供数据源用.
  41. mJsonArray = new JSONArray();
  42. for(int i = 0;i<ALBUM_COUNT; i++){
  43. JSONObject object = new JSONObject();
  44. try {
  45. object.put("resid", ALBUM_RES[i % ALBUM_RES.length]);
  46. object.put("name", "Album " + i);
  47. mJsonArray.put(object);
  48. } catch (JSONException e) {
  49. e.printStackTrace();
  50. }
  51. }
  52. mViewPager = (ViewPager)findViewById(R.id.viewpager);
  53. mViewPagerAdapter = new ViewPagerAdapter(this, mJsonArray);
  54. mViewPager.setAdapter(mViewPagerAdapter);
  55. }
  56. }

其中main.xml布局代码如下:

[java] view plaincopy

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. android:layout_width="fill_parent"
  4. android:layout_height="fill_parent"
  5. android:orientation="vertical" >
  6. <android.support.v4.view.ViewPager
  7. android:id="@+id/viewpager"
  8. android:layout_width="fill_parent"
  9. android:layout_height="fill_parent"
  10. />
  11. </LinearLayout>

第五步运行查看效果:

  

运行效果1                                             运行效果2

OK,今天就写到这里,代码注释写的也比较清楚,大家有什么疑问的,可以留言!下面的链接是源代码,供新手们学习用,今天就讲到这里,谢谢大家!!!

源代码点击进入==>

时间: 2024-07-30 10:10:52

Android高手进阶教程(二十八)之---Android ViewPager控件的使用(基于ViewPager的横向相册)!!!的相关文章

Android高手进阶教程(二十)之---Android与JavaScript方法相互调用!

在Android中通过WebView控件,可以实现要加载的页面与Android方法相互调用,我们要实现WebView中的addJavascriptInterface方法,这样html才能调用android方法,在这里我个人觉得有点和DWR相似. 为了让大家容易理解,我写了一个简单的Demo,具体步骤如下: 第一步:新建一个Android工程,命名为WebViewDemo(这里我在assets里定义了一个html页面). 第二步:修改main.xml布局文件,增加了一个WebView控件还有But

Android高手进阶教程(十六)之---Android中万能的BaseAdapter(Spinner,ListView,GridView)的使用!

大家好!今天给大家讲解一下BaseAdapter(基础适配器)的用法,适配器的作用主要是用来给诸如(Spinner,ListView,GridView)来填充数据的.而(Spinner,ListView,GridView)都有自己的适配器(记起来麻烦).但是BaseAdapter(一招鲜)对他们来说却是通用的,为什么这么说呢,首先我们看一下API文档: 我们看一下BaseAdapter已经实现了ListAdapter和SpinnerAdapter的接口,而GridView的适配器是实现了List

Android项目实战(二十八):Zxing二维码实现及优化

原文:Android项目实战(二十八):Zxing二维码实现及优化 前言: 多年之前接触过zxing实现二维码,没想到今日项目中再此使用竟然使用的还是zxing,百度之,竟是如此牛的玩意. 当然,项目中我们也许只会用到二维码的扫描和生成两个功能,所以不必下载完整的jar包,使用简化版的即可,下文可见. 这篇文章讲述:1.如果快速在项目中集成zxing,实现扫描和生成二维码功能 2.根据项目需求去修改源码实现我们的要求并进行优化 一.快速集成zxing二维码 1.下载库文件 : http://do

Android实战简易教程-第二十八枪(Uri转String型实例)

接上一篇文章.我们能够轻易的获取所选图片的uri,那么我们考虑怎样将获取的uri转换成String型的地址呢? 接下来我们通过实例来研究.布局文件和上篇(二十七枪)一致,我们就不再列出,直接看MainActivity.java: package com.example.userphoto; import java.io.File; import android.app.Activity; import android.content.Intent; import android.database

Android实战简易教程-第十八枪(ViewPager组件详解)

对于ViewPager组件我们知道: 1)ViewPager类直接继承了ViewGroup类,所有它是一个容器类,可以在其中添加其他的view类. 2)ViewPager类需要一个PagerAdapter适配器类给它提供数据. 3)ViewPager经常和Fragment一起使用,并且提供了专门的FragmentPagerAdapter和FragmentStatePagerAdapter类供Fragment中的ViewPager使用. 下面我们通过实例看一下ViewPager的使用. 一 实现V

从零开始学android&lt;GridView网格视图.二十八.&gt;

GridView组件是以网格的形式显示所有的组件,例如:在制作相册的时候,所有的图片都会以相同大小显示在不同的格子之中,就可以依靠此组件完成,此组件的继承结构如下所示: java.lang.Object ? android.view.View ? android.view.ViewGroup ? android.widget.AdapterView<T extends android.widget.Adapter> ? android.widget.AbsListView ? android.

Android高手进阶教程(五)之----Android 中LayoutInflater的使用!

原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://weizhulin.blog.51cto.com/1556324/311450 大家好我们这一节讲的是LayoutInflater的使用,在实际开发种LayoutInflater这个类还是非常有用的,它的作用类似于 findViewById(), 不同点是LayoutInflater是用来找layout下xml布局文件,并且实例化!而findViewById()是找具体xml下的

【Android Studio安装部署系列】二十八、Android Studio查看其它APP的布局结构

概述 日常使用别家的APP过程中,会遇到一些比较好看的布局,这时候我们就想学习一下别人的布局结构,以便参考. (1)手机连接电脑.设置手机为USB调试模式 参考<[Android Studio安装部署系列]七.真机运行项目> (2)运行Android Studio,打开 Tools--Android--Android Device Monitor 注意:android Studio3.1开始只能通过命令行的方式启动Android Device Monitor. 双击sdk安装目录/tools/

Android高手进阶教程(三)之----Android 中自定义View的应用.

大家好我们今天的教程是在Android 教程中自定义View 的学习,对于初学着来说,他们习惯了Android 传统的页面布局方式,如下代码: <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertic