Android高手进阶教程(二十八)之---Android ViewPager控件的使用(基于ViewPager的横向相册)!!!
大家好,相信大家用的ListView控件一定很多的,是竖向滑动的,复用convertView,我们可以加载成千上万的数据,但有时候我们会有 这个需求比如相册,我们想横向滑动,并且数据有好多,这时候ViewPager控件就派上用场了,ViewPager使用时候我们需要导入第三方包 android-support-v4.jar包,这是谷歌提供的,这个包里有Fragment ViewPager等控件,用户导入这个包,在3.0以前就可以使用Fragment控件了~
下面就开始讲下ViewPager的用 法,ViewPager和ViewFlipper用法类似,但是更好用,左右滑动效果好,而且有类似于ListView的Adapter--- PagerAdapter基类,这样的话可以回收内存,复用等。PagerAdapter的几个方法里常用的有:
- void destroyItem(View container, int position, Object object)
- 这里是左右滑动的时候,回收较早前的itemView.
- int getCount()
- ViewPager里显示内容的条数.
- Object instantiateItem(View container, int position)
- 始化ItemView.
为 了让大家容易掌握,我写了一个简单的例子,简单实现相册横向滑动功能,首先自定义了ViewPager的itemView---- ViewPagerItemView,这里做了初始化View的定义,以及回收内存重新加载等,数据源是JSONObject.其次是实现了 PagerAdapter的适配器ViewPagerAdater,这里的数据源是JSONArray.然后ViewPager在名为 ViewPagerDemoActivity.java的Activity里显示。下面是具体实现步骤:
第一步:新建一个Android工程ViewPagerDemoActivity,目录结构如下图所示:

第二步:新建一个ViewPagerItemView.java这里是相册的ItemView,代码如下:
- package com.tutor.viewpager;
- import org.json.JSONException;
- import org.json.JSONObject;
- import android.content.Context;
- import android.graphics.Bitmap;
- import android.util.AttributeSet;
- import android.view.LayoutInflater;
- import android.view.View;
- import android.widget.FrameLayout;
- import android.widget.ImageView;
- import android.widget.TextView;
- /**
- * @author frankiewei
- * 相册的ItemView,自定义View.方便复用.
- */
- public class ViewPagerItemView extends FrameLayout {
- /**
- * 图片的ImageView.
- */
- private ImageView mAlbumImageView;
- /**
- * 图片名字的TextView.
- */
- private TextView mALbumNameTextView;
- /**
- * 图片的Bitmap.
- */
- private Bitmap mBitmap;
- /**
- * 要显示图片的JSONOBject类.
- */
- private JSONObject mObject;
- public ViewPagerItemView(Context context){
- super(context);
- setupViews();
- }
- public ViewPagerItemView(Context context, AttributeSet attrs) {
- super(context, attrs);
- setupViews();
- }
- //初始化View.
- private void setupViews(){
- LayoutInflater inflater = LayoutInflater.from(getContext());
- View view = inflater.inflate(R.layout.viewpager_itemview, null);
- mAlbumImageView = (ImageView)view.findViewById(R.id.album_imgview);
- mALbumNameTextView = (TextView)view.findViewById(R.id.album_name);
- addView(view);
- }
- /**
- * 填充数据,共外部调用.
- * @param object
- */
- public void setData(JSONObject object){
- this.mObject = object;
- try {
- int resId = object.getInt("resid");
- String name = object.getString("name");
- //实战中如果图片耗时应该令其一个线程去拉图片异步,不然把UI线程卡死.
- mAlbumImageView.setImageResource(resId);
- mALbumNameTextView.setText(name);
- } catch (JSONException e) {
- e.printStackTrace();
- }
- }
- /**
- * 这里内存回收.外部调用.
- */
- public void recycle(){
- mAlbumImageView.setImageBitmap(null);
- if ((this.mBitmap == null) || (this.mBitmap.isRecycled()))
- return;
- this.mBitmap.recycle();
- this.mBitmap = null;
- }
- /**
- * 重新加载.外部调用.
- */
- public void reload(){
- try {
- int resId = mObject.getInt("resid");
- //实战中如果图片耗时应该令其一个线程去拉图片异步,不然把UI线程卡死.
- mAlbumImageView.setImageResource(resId);
- }catch (JSONException e) {
- e.printStackTrace();
- }
- }
- }
其中ViewPagerItemView使用的xml文件viewpager_itemView.xml代码如下:
- <?xml version="1.0" encoding="utf-8"?>
- <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- >
- <ImageView
- android:id="@+id/album_imgview"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- android:contentDescription="@string/app_name"
- android:scaleType="fitXY"
- />
- <TextView
- android:id="@+id/album_name"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="bottom|center_horizontal"
- android:textColor="#B2191919"
- />
- </FrameLayout>
第三步:新建一个ViewPagerAdapter.java继承与PagerAdapter,代码如下:
- package com.tutor.viewpager;
- import java.util.HashMap;
- import org.json.JSONArray;
- import org.json.JSONException;
- import org.json.JSONObject;
- import android.content.Context;
- import android.os.Parcelable;
- import android.support.v4.view.PagerAdapter;
- import android.support.v4.view.ViewPager;
- import android.view.View;
- /**
- * @author frankiewei
- * 相册的适配器.
- */
- public class ViewPagerAdapter extends PagerAdapter {
- /**
- * 上下文
- */
- private Context mContext;
- /**
- * 数据源,这里是JSONARRAY
- */
- private JSONArray mJsonArray;
- /**
- * Hashmap保存相片的位置以及ItemView.
- */
- private HashMap<Integer, ViewPagerItemView> mHashMap;
- public ViewPagerAdapter(Context context,JSONArray arrays) {
- this.mContext = context;
- this.mJsonArray = arrays;
- mHashMap = new HashMap<Integer, ViewPagerItemView>();
- }
- //这里进行回收,当我们左右滑动的时候,会把早期的图片回收掉.
- @Override
- public void destroyItem(View container, int position, Object object) {
- ViewPagerItemView itemView = (ViewPagerItemView)object;
- itemView.recycle();
- }
- @Override
- public void finishUpdate(View view) {
- }
- //这里返回相册有多少条,和BaseAdapter一样.
- @Override
- public int getCount() {
- return mJsonArray.length();
- }
- //这里就是初始化ViewPagerItemView.如果ViewPagerItemView已经存在,
- //重新reload,不存在new一个并且填充数据.
- @Override
- public Object instantiateItem(View container, int position) {
- ViewPagerItemView itemView;
- if(mHashMap.containsKey(position)){
- itemView = mHashMap.get(position);
- itemView.reload();
- }else{
- itemView = new ViewPagerItemView(mContext);
- try {
- JSONObject dataObj = (JSONObject) mJsonArray.get(position);
- itemView.setData(dataObj);
- } catch (JSONException e) {
- e.printStackTrace();
- }
- mHashMap.put(position, itemView);
- ((ViewPager) container).addView(itemView);
- }
- return itemView;
- }
- @Override
- public boolean isViewFromObject(View view, Object object) {
- return view == object;
- }
- @Override
- public void restoreState(Parcelable arg0, ClassLoader arg1) {
- }
- @Override
- public Parcelable saveState() {
- return null;
- }
- @Override
- public void startUpdate(View view) {
- }
- }
第四步:修改主Activity类ViewPagerDemoActivity.java代码如下:
- package com.tutor.viewpager;
- import org.json.JSONArray;
- import org.json.JSONException;
- import org.json.JSONObject;
- import android.app.Activity;
- import android.os.Bundle;
- import android.support.v4.view.ViewPager;
- /**
- * @author frankiewei
- * ViewPager控件使用的Demo.
- */
- public class ViewPagerDemoActivity extends Activity {
- /**
- * 这里定义了相册的总数100条.
- */
- private static final int ALBUM_COUNT = 100;
- /**
- * 相册的资源,实战开发中都是网络数据或者本地相册.
- */
- private static final int ALBUM_RES[] = {
- R.drawable.test1,R.drawable.test2,R.drawable.test3,
- R.drawable.test4,R.drawable.test5,R.drawable.test6
- };
- private ViewPager mViewPager;
- /**
- * 适配器.
- */
- private ViewPagerAdapter mViewPagerAdapter;
- /**
- * 数据源.
- */
- private JSONArray mJsonArray;
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- setupViews();
- }
- private void setupViews(){
- //初始化JSonArray,给ViewPageAdapter提供数据源用.
- mJsonArray = new JSONArray();
- for(int i = 0;i<ALBUM_COUNT; i++){
- JSONObject object = new JSONObject();
- try {
- object.put("resid", ALBUM_RES[i % ALBUM_RES.length]);
- object.put("name", "Album " + i);
- mJsonArray.put(object);
- } catch (JSONException e) {
- e.printStackTrace();
- }
- }
- mViewPager = (ViewPager)findViewById(R.id.viewpager);
- mViewPagerAdapter = new ViewPagerAdapter(this, mJsonArray);
- mViewPager.setAdapter(mViewPagerAdapter);
- }
- }
其中main.xml布局代码如下:
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- android:orientation="vertical" >
- <android.support.v4.view.ViewPager
- android:id="@+id/viewpager"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- />
- </LinearLayout>
第五步运行查看效果:

运行效果1 运行效果2
OK,今天就写到这里,代码注释写的也比较清楚,大家有什么疑问的,可以留言!下面的链接是源代码,供新手们学习用,今天就讲到这里,谢谢大家!!!
Android高手进阶教程(二十八)之---Android ViewPager控件的使用(基于ViewPager的横向相册)!!!的更多相关文章
- SpringBoot进阶教程(二十八)整合Redis事物
Redis默认情况下,事务支持被禁用,必须通过设置setEnableTransactionSupport(true)为使用中的每个redistplate显式启用.这样做会强制将当前重新连接绑定到触发m ...
- Android简易实战教程--第二十二话《自定义组合控件模拟qq登录下拉框和其中的一些”小技巧”》
转载此文章请注明出处:点击打开链接 http://blog.csdn.net/qq_32059827/article/details/52313516 首先,很荣幸此专栏能被CSDN推荐到主页.荣 ...
- SpringBoot进阶教程(二十九)整合Redis 发布订阅
SUBSCRIBE, UNSUBSCRIBE 和 PUBLISH 实现了 发布/订阅消息范例,发送者 (publishers) 不用编程就可以向特定的接受者发送消息 (subscribers). Ra ...
- (转载)Android项目实战(二十八):Zxing二维码实现及优化
Android项目实战(二十八):Zxing二维码实现及优化 前言: 多年之前接触过zxing实现二维码,没想到今日项目中再此使用竟然使用的还是zxing,百度之,竟是如此牛的玩意. 当然,项目中 ...
- (转载)Android项目实战(二十八):使用Zxing实现二维码及优化实例
Android项目实战(二十八):使用Zxing实现二维码及优化实例 作者:听着music睡 字体:[增加 减小] 类型:转载 时间:2016-11-21我要评论 这篇文章主要介绍了Android项目 ...
- Android项目实战(二十八):Zxing二维码实现及优化
前言: 多年之前接触过zxing实现二维码,没想到今日项目中再此使用竟然使用的还是zxing,百度之,竟是如此牛的玩意. 当然,项目中我们也许只会用到二维码的扫描和生成两个功能,所以不必下载完整的ja ...
- Android实战简易教程-第二十八枪(Uri转String型实例)
接上一篇文章.我们能够轻易的获取所选图片的uri,那么我们考虑怎样将获取的uri转换成String型的地址呢? 接下来我们通过实例来研究.布局文件和上篇(二十七枪)一致,我们就不再列出,直接看Main ...
- Android高手进阶教程(七)之----Android 中Preferences的使用!
http://blog.csdn.net/Android_Tutor/article/details/5531849 大家好,我们这一节讲的是Android Preferences 的学习,Prefe ...
- SpringBoot进阶教程(二十六)整合Redis之共享Session
集群现在越来越常见,当我们项目搭建了集群,就会产生session共享问题.因为session是保存在服务器上面的.那么解决这一问题,大致有三个方案,1.通过nginx的负载均衡其中一种ip绑定来实现( ...
随机推荐
- CSS中常用的字体单位:px、em、rem和%的区别
在刚接触CSS时,px用的比较多,也很好理解,可是用久了就会发现有些缺陷,特别是在做响应式开发的时候. 那这么多单位到底在什么时候用什么单位合适呢?今天就来探讨一下. 先大致解释一下这些单位的意思: ...
- sourcemap的使用
minify.bat @echo off if ""%1""=="""" goto end :loop if not e ...
- ASP.NET - 演练:创建网页以显示 XML 数据
数据通常是以 XML 格式提供给 Web 应用程序的.但是,XML 数据本质上是分层的,因此您可能希望能够在基于列表的控件中使用 XML 数据,如 GridView 或 DropDownList 控件 ...
- Excel每隔两行自动求和一次怎么操作?
今天ytkah得到一份数据,要求进行统计分析,由于是原始数据,还没处理过,数据量有点大,如下图所示(Excel每隔两行自动求和),每天的数字由两项组成,男生的人数.消费值和女生的人数和消费值,数字都在 ...
- MM1排队系统
#coding=utf-8 import time import random as rd #import math import pylab as pl def simulate(nameda,u) ...
- POJ 1273 Drainage Ditches(网络流dinic算法模板)
POJ 1273给出M条边,N个点,求源点1到汇点N的最大流量. 本文主要就是附上dinic的模板,供以后参考. #include <iostream> #include <stdi ...
- HDU 2571 命运 动态规划
命运 http://acm.hdu.edu.cn/showproblem.php?pid=2571 Problem Description 穿过幽谷意味着离大魔王lemon已经无限接近了!可谁能想到, ...
- eclipse加速
eclipse老是building workspace及自动更新问题,eclipse加速 最近用Eclipse开发oPhone的一个项目,每次打开Eclipse的时候,总是在build workspa ...
- PHP函数中默认参数的的写法
函数可以定义 C++ 风格的标量参数默认值,如下所示: Example #3 在函数中使用默认参数 <?php function makecoffee($type = "cappucc ...
- awk过滤统计不重复的行
awk以‘\t’为分隔符区分列 cat logs | grep IconsendRedirect | grep 1752 | awk -F'\t' '{print $8}'| wc -l awk过滤统 ...