ViewPager复用调研

本文详细探讨了ViewPager在滑动过程中的View创建与销毁机制,包括顺序滑动和直接跳转两种情况。研究发现,ViewPager最多存在6个View,且在创建新View前会销毁旧View,但缺乏自有的View重用机制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、要调研的问题:

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的创建和销毁

78、ViewPager复用调研 - 呵呵 加油 - 呵呵 加油

 

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个孩子(刚进入页面时);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值