ViewPager的view复用

本文介绍了Android中ViewPager组件的视图复用机制,详细解释了Adapter中的instantiateItem()和destroyItem()方法如何实现视图的缓存与复用,以减少内存消耗并提高性能。

关于ViewPager的view复用主要了解Adapter中各个函数的执行过程。

  • instantiateItem()方法: 滑动到一个新的item时被调用。

  • destroyItem(): 当用户滑到第3个item的时候被调用。先调用这个方法来回收第一个item,然后调用instantiateItem()方法来实例化第3个item。

所以,可以在destroyItem()的时候将要被remove掉的view回收起来,然后在instantiateItme()的时候重复利用这个view。这样,就只会有3个ViewHolder实例存在:当前显示的、上一个、下一个

代码:

class MyViewPagerAdapter extends PagerAdapter {
        private LinkedList<View> mViewCache = null;

        public MyViewPagerAdapter() {
            mViewCache = new LinkedList<>();    
        }

        @Override
        public int getCount() {
            return 10;
        }

        @Override
        public boolean isViewFromObject(View view, Object object) {
            return view == object;
        }


        @Override
        public Object instantiateItem(ViewGroup container, int position) {
            holder = null;
            View convertView = null;
            if (mViewCache.size() == 0) {
                convertView = View.inflate(ExperimentActivity.this, R.layout.item_exper_viewpager, null);
                holder = new ViewHolder();
                holder.ivPic = (ImageView) convertView.findViewById(R.id.iv_title_pic);
                holder.ivBg = (ImageView) convertView.findViewById(R.id.iv_bg_pic);
                holder.tvName = (TextView) convertView.findViewById(R.id.tv_exper_name);
                holder.tvNum = (TextView) convertView.findViewById(R.id.tv_num);
                holder.vLine = convertView.findViewById(R.id.v_line);

                convertView.setTag(holder);
            } else {
                convertView = mViewCache.removeFirst();
                holder = (ViewHolder) convertView.getTag();
            }


        holder.tvName.setText("string");
            holder.tvNum.setText("string");

            container.addView(convertView);
            return convertView;
        }


        @Override
        public void destroyItem(ViewGroup container, int position, Object object) {
            container.removeView((View) object);
            mViewCache.add((View) object);
        }

        //View复用
        public final class ViewHolder {
            public TextView tvName;
            public TextView tvNum;
            public ImageView ivPic;
            public ImageView ivBg;
            public View vLine;
        }
    }

自己结合网上看到的理解,有问题欢迎提出。

ViewPager中可以不使用Fragment,直接使用View。 ### 原理 ViewPager既可以使用Fragment作为页面内容,也可以使用普通的View作为页面内容。使用View时,不需要像使用Fragment那样进行复杂的生命周期管理,直接将View添加到ViewPager的适配器中即可。 ### 实现步骤 1. **布局文件**:在布局文件中添加ViewPager组件。 ```xml <androidx.viewpager.widget.ViewPager android:id="@+id/viewPager" android:layout_width="match_parent" android:layout_height="match_parent"/> ``` 2. **创建View**:准备要显示的View,可以通过LayoutInflater从布局文件中加载。 ```java LayoutInflater inflater = LayoutInflater.from(context); View view1 = inflater.inflate(R.layout.view1_layout, null); View view2 = inflater.inflate(R.layout.view2_layout, null); ``` 3. **创建适配器**:自定义一个PagerAdapter,并重写相关方法。 ```java import android.view.View; import android.view.ViewGroup; import androidx.viewpager.widget.PagerAdapter; import java.util.List; public class ViewPagerAdapter extends PagerAdapter { private List<View> viewList; public ViewPagerAdapter(List<View> viewList) { this.viewList = viewList; } @Override public int getCount() { return viewList.size(); } @Override public boolean isViewFromObject(View view, Object object) { return view == object; } @Override public Object instantiateItem(ViewGroup container, int position) { View view = viewList.get(position); container.addView(view); return view; } @Override public void destroyItem(ViewGroup container, int position, Object object) { container.removeView((View) object); } } ``` 4. **设置适配器**:将适配器设置给ViewPager。 ```java import androidx.viewpager.widget.ViewPager; import java.util.ArrayList; import java.util.List; public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ViewPager viewPager = findViewById(R.id.viewPager); List<View> viewList = new ArrayList<>(); LayoutInflater inflater = LayoutInflater.from(this); View view1 = inflater.inflate(R.layout.view1_layout, null); View view2 = inflater.inflate(R.layout.view2_layout, null); viewList.add(view1); viewList.add(view2); ViewPagerAdapter adapter = new ViewPagerAdapter(viewList); viewPager.setAdapter(adapter); } } ``` ### 优缺点 - **优点**: - 简单直接,不需要处理Fragment的生命周期,减少了代码的复杂度。 - 内存占用相对较少,因为不需要为每个页面创建Fragment实例。 - **缺点**: - 缺乏Fragment的复用性和生命周期管理机制,在处理复杂页面逻辑时可能会比较麻烦。 - 不便于与系统的一些功能(如导航组件)集成。 ### 适用场景 适用于页面数量较少、页面逻辑简单的场景,例如引导页、图片轮播等。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值