Android-Fragment嵌套(ViewPaper+Fra

作者: MonkeyLei | 来源:发表于2019-07-21 16:46 被阅读1次

最近做一个币行情显示的功能,接口已有,重点就是搞懂字段,然后进行显示。另外还得定时刷新(每隔10s请求刷新一次),同时如果刷新过程价格有涨幅需要分别以不同的颜色(红色表示涨,绿色表示下降)进行渐变显示。

简单说下颜色变化:由于小萌新尝试过程本来是想每个item进行颜色动画动画或者说定时进行颜色的改变,但是发现实际过程模拟器出现了线程溢出问题,初步尝试发现每个item进行颜色渐变的动画,不如间隔的进行整体刷新,刷新过程中利用新数据与当前数据进行对比,进行颜色变化。另外,如果当前已经是红色或者绿色,下次刷新间隔缩短到3s进行颜色默认恢复,然后再恢复到10s进行渐变处理,达到整体效果。 可能说起来模糊,直接看效果:

image

定时刷新采用 handler.postDelayed(runnable, 10000); 实现。为了处理界面不可见时,停止定时器的触发,则需要考虑再多个地方进行 handler.removeCallbacks(runnable);的调用处理。我想你不希望界面不可见或者销毁了,定时器还在运行的状态吧,那样或许还会导致泄漏,崩溃等问题!!!

1. 不自觉的想到需要在 **onDestroyView **中进行释放

image

结构:HomeActivity->Fragment(多碎片切换利用Hide/Show的方式)->Viewpaper+Fragment(设置了infosViewPaper.setOffscreenPageLimit(3);)的方式

image

问题来了:

  1. Fragment利用Hide/Show的方式切换时,只会触发碎片的onHiddenChanged的周期回调,但是其碎片(ViewPaper+Fragment)的onHiddenChanged并不会触发,其他生命周期也不会被触发 - 因为子碎片并没有被重建(setOffscreenPageLimit(3),至少容纳三个碎片) - 也就是说底部导航切换的情况下,子碎片(比如市值界面)的生命周期情况并不知晓!!

2. 自选和市值子碎片切换的时候(ViewPaper切换方式), 只会触发setUserVisibleHint周期回调

3. 当点击市值中条目进行页面跳转时,触发onPause->onStop->(切换回来时触发)onResume

So,针对2、3 只需要在onResume(需要注意第一次启动也会触发的问题)、setUserVisibleHint中处理下定时器的开启关闭即可

    @Override
    public void onResume() {
        super.onResume();
        if (!bFirstStart){
            ///< 定时请求列表并做数据变化对比,然后做刷新动画处理
            handler.postDelayed(runnable, 10000);
        }
        bFirstStart = false;
        Log.i(TAG, mParam1 + "onResume");
    }

   @Override
    public void setUserVisibleHint(boolean isVisibleToUser) {
        super.setUserVisibleHint(isVisibleToUser);
        if (!isVisibleToUser) {
            handler.removeCallbacks(runnable);
        }else{
            ///< 定时请求列表并做数据变化对比,然后做刷新动画处理
            handler.postDelayed(runnable, 10000);
        }
        Log.i(TAG, mParam1 + "setUserVisibleHint isVisibleToUser="+isVisibleToUser);
    }

针对1,由于子碎片没有触发,而主碎片切换的情况下会回调onHiddenChanged方法,这个时候就可以在主碎片的onHiddenChanged中调用子碎片的onHiddenChanged方法,主动进行回调:

主碎片处理:

      @Override
    public void onHiddenChanged(boolean hidden) {
        super.onHiddenChanged(hidden);
        ///< 由于父Fragemnt没有重新创建View,因此只能通过该方式主动调用子碎片的生命周期
        if (null != getCurrentFragment()){
            getCurrentFragment().onHiddenChanged(hidden);
        }
        Log.i(TAG, mParam1 + "onHiddenChanged");
    }

其中获取当前碎片的方法 getCurrentFragment:

  /**
     * 获取当前的Fragment
     * @return
     */
    private Fragment getCurrentFragment() {
        if (null == infosViewPaper){
            return null;
        }
        FragmentManager manager = getChildFragmentManager();
        final int currentItem = infosViewPaper.getCurrentItem();
        Fragment fragment = manager.findFragmentByTag(makeFragmentName(infosViewPaper.getId(), currentItem));
        return fragment;
    }

然后子碎片同样处理下:

    @Override
    public void onHiddenChanged(boolean hidden) {
        super.onHiddenChanged(hidden);
        if (hidden){
            handler.removeCallbacks(runnable);
        }else{
            ///< 定时请求列表并做数据变化对比,然后做刷新动画处理
            handler.postDelayed(runnable, 10000);
        }
        Log.i(TAG, mParam1 + "onHiddenChanged hidden=" + hidden);
    }

这样就完成了所有可见不可见的情况的处理。有时候发现还是蛮烦的,当然如果对碎片的生命周期了解很熟的话,应该就不会那么烦了!!!

还有就是额外补充下(关于通用适配器封装相关):关于通用BaseAdapter资源释放的问题,需要主动调用Adapter的onDetachedFromRecyclerView方法

     @Override
    public void onDetach() {
        super.onDetach();
        ///< 适配器资源释放
        if (null != marketValueAdapter &&
                null != xrerecycleView) {
            marketValueAdapter.onDetachedFromRecyclerView(xrerecycleView);
        }
        Log.i(TAG, mParam1 + "onDetach");
    }

然后,通用适配器就可以做具体释放处理

BaseAdapter.java

    private WeakReference<Context> contextWeakReference = null;

    /**
     * 适配器资源释放
     * @param recyclerView
     */
    @Override
    public void onDetachedFromRecyclerView(RecyclerView recyclerView) {
        super.onDetachedFromRecyclerView(recyclerView);
        if (null != contextWeakReference){
            contextWeakReference.clear();
            contextWeakReference = null;
        }
    }

差不多这个定时就可以了。也避免了一些泄漏崩溃啥的,同时还有就是关于rxjava不停同时请求导致内存溢出的问题 - 尽量逻辑上有个顺序:

1. 比如说当前请求是首次请求,等首次请求结束后再开启定时刷新功能;

2. 手动刷新过程首先停止定时刷新,避免数据混淆和干扰导致界面等问题(可以理解为多线程的安全),等手动刷新结束后再开启定时刷新

3. 由于防止定时多次刷新问题,再下一次进行定时刷新时清空/释放上次刷新请求,然后进行新的刷新

经过逻辑的稍微更严谨处理以及相关资源处理,目前还是能经得住测试的。当然小萌新还得加强各方面的深入(比如rx深入),另外关于自己封装的BaseAdapter通用适配器以及通用请求MonkeyLei:Android-基本的MVP结构的模板工程(泛型,Rx通用请求,BaseAdapter实践目录链接)还得再考虑验证和完善......

相关文章

  • Android-Fragment嵌套(ViewPaper+Fra

    最近做一个币行情显示的功能,接口已有,重点就是搞懂字段,然后进行显示。另外还得定时刷新(每隔10s请求刷新一次),...

  • Android-Fragment

    有的没的Fragment 生命周期 一些要点: 1.3.0版本之后才引入fragment,所以minSdk要大于1...

  • Android-Fragment

    今天我们来总结一下常用的Fragment,以及开发中那些是要注意的? 1.Fragmet选哪个包? 我们在创建Fr...

  • android-fragment

    动态fragment的情况下: 每次都需要的重新生成事务对象

  • Android-Fragment的生命周期懒加载xiao习

    上一篇我们相对以前较为深点的认识了下Fragment的生命周期回调函数Android-Fragment的生命周期较...

  • Android-Fragment基础

    Activity和Fragment生命周期的关系: onCreate()系统会在创建Fragment调用此方法 o...

  • 嵌套规则

    块元素能嵌套所有元素p不能嵌套块,只能嵌套行内行内元素不能嵌套块元素行内可以嵌套行内,但是不能嵌套自己a可以嵌套任...

  • Sass/Scss--2

    八.嵌套-选择器嵌套 Sass 的嵌套分为三种: 选择器嵌套 属性嵌套 伪类嵌套 html 结构: 选中 h...

  • React-Native Context跨层级的组件通信

    如图:APP界面嵌套A嵌套B嵌套C嵌套D嵌套E嵌套F...... 场景一:从APP界面获取数据,需要F来显示,怎么...

  • Android-Fragment简要分析

    注意:文章对Fragment源码的分析基于support v4的Fragment包,版本号为25.3.1 Frag...

网友评论

    本文标题:Android-Fragment嵌套(ViewPaper+Fra

    本文链接:https://www.haomeiwen.com/subject/slcvlctx.html