zoukankan      html  css  js  c++  java
  • ViewPager -- Fragment 切换卡顿 性能优化

    当ViewPager切换到当前的Fragment时,Fragment会加载布局并显示内容,如果用户这时快速切换ViewPager,即Fragment需要加载UI内容,而又频繁地切换Fragment,就容易产生卡顿现象(类似在ListView快速滑动的同时加载图片容易卡顿)。

      

    ===========================、处理方案 ===============================

    1.Fragment轻量化

    如果ViewPager加载的Fragment都比较轻量,适当精简Fragment的布局,可提高Fragment加载的速度,从而减缓卡顿现象。

    2.防止Fragment被销毁

    ViewPager在切换的时候,如果频繁销毁和加载Fragment,就容易产生卡顿现象,阻止Fragment的销毁可有效减缓卡顿现象。

    (1)    在PagerAdapter里覆盖destroyItem方法可阻止销毁Fragment

     @Override       
    public void destroyItem(ViewGroup container, int position, Object object) {
        //super.destroyItem(container, position, object);
    }

    (2)    通过PagerAdapter的setOffscreenPageLimit()方法可以设置保留几个Fragment,适当增大参数可防止Fragment频繁地被销毁和创建。

    风险:在Fragment比较多的情况下,部分低端机型容易产生OOM问题。


    3.Fragment内容延迟加载

    (1) 描述

    在切换到当前Fragment的时候,并不立刻去加载Fragment的内容,而是先加载一个简单的空布局,然后启动一个延时任务,延时时长为T,当用户在该Fragment停留时间超过T时,继续执行加载任务;而当用户切换到其他Fragment,停留时间低于T,则取消该延时任务。

    (2) 具体操作

    首先,设置延迟任务

     private Runnable LOAD_DATA = new Runnable() {        
    @Override
    public void run() {
    //在这里数据内容加载到Fragment上
    }
    };

    启动任务

     @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 

        //初始化视图,这里最好先设置一个进度对话框,提示用户正在加载数据
        initView();
        //启动任务,这里设置500毫秒后开始加载数据    handler.postDelayed(LOAD_DATA,500)
        return view;
    }

    若用户切换到其他Fragment则取消任务

    //判断Fragment是否可视的重载方法
    @Override
    public void setUserVisibleHint(boolean isVisibleToUser) {
      super.setUserVisibleHint(isVisibleToUser);
        if(!isVisibleToUser)
         mHandler.removeCallbacks(LOAD_DATA);
    }

    (3) 注意

    使用setUserVisibleHint判断用户是否切换到其他Fragment,这样的做法有个缺陷,因为会在ViewPager开始滑动的时候取消延时任务,而在滑动偏移量不足的情况下,ViewPager会继续回滚到当前Fragment,导致当前Fragment的加载任务被取消而又不会重新启动加载任务。

      这里我使用的做法是,给ViewPager增加一个OnPageChangeListener,,该监听器的onPageSelected(position)能监听ViewPager当前切换到哪个Fragment,在这里将其他Fragment的延迟加载任务取消掉。

    ================项目中用到的代码片段==========================================================

    Timer timer = new Timer();
                    timer.schedule(new TimerTask() {
                        @Override
                        public void run() {
                            getActivity().runOnUiThread(new Runnable() {
                                
                                @Override
                                public void run() {
                                    // TODO Auto-generated method stub
                                    
                                    geticard();
                                }
                            });
                        }
                    }, 500);
  • 相关阅读:
    heat模板
    Leetcode812.Largest Triangle Area最大三角形面积
    Leetcode812.Largest Triangle Area最大三角形面积
    Leetcode811.Subdomain Visit Count子域名访问计数
    Leetcode811.Subdomain Visit Count子域名访问计数
    Leetcode806.Number of Lines To Write String写字符串需要的行数
    Leetcode806.Number of Lines To Write String写字符串需要的行数
    Leetcode819.Most Common Word最常见的单词
    Leetcode819.Most Common Word最常见的单词
    Leetcode783.Minimum Distance Between BST Nodes二叉搜索树结点最小距离
  • 原文地址:https://www.cnblogs.com/spring87/p/4308247.html
Copyright © 2011-2022 走看看