一、要调研的问题:
1、ViewPager有复用机制吗???
2、ViewPager中最多存在多少View???
二、测试demo代码
GuideViewDemoActivity代码:
package com.lenovo.guidedemo;
import java.util.ArrayList;
import android.app.Activity; import android.os.Bundle; import android.os.Parcelable; import android.support.v4.view.PagerAdapter; import android.support.v4.view.ViewPager; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.View.OnClickListener; import android.view.Window;
/** * * @author http://xiaxveliang.blog.163.com/ * */
public class GuideViewDemoActivity extends Activity {
private static final String TAG = "xiaxl1: " + GuideViewDemoActivity.class.getSimpleName();
private ViewPager viewPager = null; private ArrayList<View> pageViews = new ArrayList<View>();
@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Log.d(TAG, "-----onCreate--------");
this.requestWindowFeature(Window.FEATURE_NO_TITLE);
/** * 显示当前View */ setContentView(R.layout.main);
/** * 造数据 */ LayoutInflater inflater = getLayoutInflater();
for (int i = 0; i < 5; i++) { View tempView = inflater.inflate(R.layout.item01, null); // setTAG tempView.setTag(i + ""); // add pageViews.add(tempView); }
/** * 初始化UI */
viewPager = (ViewPager) findViewById(R.id.guidePages); viewPager.setAdapter(new GuidePageAdapter());
// findViewById(R.id.button1).setOnClickListener(new OnClickListener() {
@Override public void onClick(View v) { viewPager.setCurrentItem(5); } });
}
class GuidePageAdapter extends PagerAdapter {
@Override public int getCount() { Log.d(TAG, "-----getCount--------"); Log.d(TAG, "pageViews.size(): " + pageViews.size()); return pageViews.size(); }
@Override public boolean isViewFromObject(View arg0, Object arg1) { Log.d(TAG, "-----isViewFromObject--------");
if (arg0.getTag() != null) { String str = (String) arg0.getTag(); Log.d(TAG, "arg0.getTag(): " + str); }
if (arg1 instanceof View) { View tempView = (View) arg1; if (tempView.getTag() != null) { String str = (String) tempView.getTag(); Log.d(TAG, "arg1.getTag(): " + str); }
}
Log.d(TAG, "arg0 == arg1: " + (arg0 == arg1));
return arg0 == arg1; }
@Override public int getItemPosition(Object object) { Log.d(TAG, "-----getItemPosition--------");
return super.getItemPosition(object); }
@Override public void destroyItem(View arg0, int arg1, Object arg2) { Log.d(TAG, "-----destroyItem--------"); Log.d(TAG, "arg1: " + arg1);
if (arg2 instanceof View) { View tempView = (View) arg2; if (tempView.getTag() != null) { String str = (String) tempView.getTag(); Log.d(TAG, "arg2.getTag(): " + str); } }
if (pageViews.get(arg1).getTag() != null) { String str = (String) pageViews.get(arg1).getTag(); Log.d(TAG, "pageViews.get(arg1).getTag(): " + str); }
((ViewPager) arg0).removeView(pageViews.get(arg1)); }
@Override public Object instantiateItem(View arg0, int arg1) { Log.d(TAG, "-----instantiateItem--------"); Log.d(TAG, "arg1: " + arg1);
if (pageViews.get(arg1).getTag() != null) { String str = (String) pageViews.get(arg1).getTag(); Log.d(TAG, "pageViews.get(arg1).getTag(): " + str); }
((ViewPager) arg0).addView(pageViews.get(arg1)); return pageViews.get(arg1); }
@Override public void restoreState(Parcelable arg0, ClassLoader arg1) {
}
@Override public Parcelable saveState() {
return null; }
@Override public void startUpdate(View arg0) {
}
@Override public void finishUpdate(View arg0) {
} }
}
代码下载:
http://pan.baidu.com/s/1hq1Oc3y
一、测试滑动过程中View的创建和销毁

1、一页一页顺序滑动
(1)、ViewPager创建时的log(当前显示页面为index为0的页面)
-----instantiateItem-------- arg1: 0 pageViews.get(arg1).getTag(): 0 -----instantiateItem-------- arg1: 1 pageViews.get(arg1).getTag(): 1
由log可以看出,ViewPager创建了0、1两个页面,当前显示页面为index为0的页面
(2)、ViewPager向后滑动一页(当前显示界面为第1页)
-----instantiateItem-------- arg1: 2 pageViews.get(arg1).getTag(): 2
由log可以看出,ViewPager创建了0、1、2 三个页面,当前显示页面为index为1的页面
(3)、ViewPager再次向后滑动一页(当前显示界面为第2页)
-----destroyItem-------- arg1: 0 arg2.getTag(): 0 pageViews.get(arg1).getTag(): 0 -----instantiateItem-------- arg1: 3 pageViews.get(arg1).getTag(): 3
由log可以看出,ViewPager先销毁了index为0的页面,然后创建了index为3的页面。ViewPager中存在的页面为1、2、3,当前显示页面为index为2的页面
(4)、顺序滑动的结论
由以上log可以确定,顺序滑动过程中:
1)、ViewPager中最多存在3个View,最少存在两个View;
2)、在创建新的View之前,先销毁之前的无用View;
3)、顺序滑动过程中ViewPager没有自己的View重用机制,只有View的不断销毁和创建,保证ViewPager最多存在3个孩子。
(5)、顺序滑动时的性能问题
1)、View创建和销毁时,Java虚拟机对内存的回收不一定及时,可能造成内存图片的大量堆积
2)、垃圾回收很占时间,可能造成翻页卡顿
2、从第一页直接跳转到最后一页
(1)、ViewPager创建时的log(当前显示页面为index为0的页面)
-----instantiateItem-------- arg1: 0 pageViews.get(arg1).getTag(): 0 -----instantiateItem-------- arg1: 1 pageViews.get(arg1).getTag(): 1
由log可以看出,ViewPager创建了0、1两个页面,当前显示页面为index为0的页面
(2) ViewPager直接跳转到index为4的页面(当前显示界面为index为4的页面)
-----instantiateItem-------- arg1: 3 pageViews.get(arg1).getTag(): 3 -----instantiateItem-------- arg1: 4 pageViews.get(arg1).getTag(): 4
-----destroyItem-------- arg1: 0 arg2.getTag(): 0 pageViews.get(arg1).getTag(): 0 -----destroyItem-------- arg1: 1 arg2.getTag(): 1 pageViews.get(arg1).getTag(): 1
由log可以看出,ViewPager先创建了3、4两个页面,此时ViewPager存在0、1、3、4,四个孩子。然后ViewPager销毁了index为0、1的界面。此时ViewPager中存在index为3、4的界面,当前显示界面为index为4的界面。
(3)、跳转滑动的结论
由以上log可以确定,跳转滑动过程中:
1)、ViewPager中最多存在6个View(销毁View之前),最少存在两个View;
2)、在销毁旧的View之前,先创建了新的View,造成ViewPager中最多可存在6个View。如果View中图片较多,内存崩溃的可能性比较大。
3)、跳转滑动过程中ViewPager没有自己的View重用机制,只有View的不断销毁和创建,保证ViewPager最多存在6个孩子。
四、调研结论:
1)、ViewPager中没有View的重用机制(若要重用,需自己实现)
2)、ViewPager中最多存在6个孩子(跳转滑动时),最少存在2个孩子(刚进入页面时);