美文网首页
Android中Fragment可见性时机控制

Android中Fragment可见性时机控制

作者: 雾中的影子 | 来源:发表于2017-10-13 16:14 被阅读0次

    现在对于android app而言,fragment的使用已经非常广泛。大概分为两种情况:第一种是直接使用Activity装载fragment,第二种是ViewPager+Fragment,所以fragment的切换就变成了很频繁的操作。fragment的切换又分两种情况:

    • 每次创建新的实例进行替换
    • 先创建好,每次通过 show()或者hide() 方法控制显示隐藏

    不管上述哪种情况,我们在大多数情况下,都需要知道具体哪个fragment显示在用户面前或者第一次显示在用户面前这样一个时机,好让用户看到我们想展示给他的数据。下面给出两种对应的解决方案,仅供参考:

    一,通过Activity直接装载多个Fragment(多用于最外层导航tab页)

    主要方式:通过重写onHiddenChanged(boolean hidden)方法

    这个方法是V4包中Fragment的方法,当Fragment对用户可见性改变的时候,这个方法会被调用。参数 hidden 的值 为false 表示 可见, true表示不可见。要注意的是,但Fragment第一次被add到Activity的时候,这个方法不会被调用。所以要处理一下fragment 第一次对用户可见的情况。

    先写一个BaseFragment ,让所有的fragment继承自它。

    public class BaseFragment extends Fragment {
    
        protected boolean isFirstVisible = false;
    
        public BaseFragment() {
        }
    
        @Override
        public void onAttach(Context context) {
            super.onAttach(context);
            isFirstVisible = true;
        }
    
        @Override
        public void onCreate(@Nullable Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
        }
    
        @Override
        public void onActivityCreated(@Nullable Bundle savedInstanceState) {
            super.onActivityCreated(savedInstanceState);
        }
    
        @Override
        public void onStart() {
            super.onStart();
        }
    
        @Override
        public void onResume() {
            super.onResume();
        }
    
        @Override
        public void onPause() {
            super.onPause();
            isFirstVisible = false;
        }
    
        @Override
        public void onStop() {
            super.onStop();
        }
    
        @Override
        public void onDestroyView() {
            super.onDestroyView();
        }
    
        @Override
        public void onDestroy() {
            super.onDestroy();
        }
    
        @Override
        public void onDetach() {
            super.onDetach();
        }
    
    }
    
    

    主要是在BaseFragment里面定义了一个boolean类型的变量。用来表示是否是第一次可见。让所有fragment也能继承这个属性。接下来去看具体的Fragment代码:

    public class FindFragment extends BaseFragment {
    
    
        private static final String TAG = "FindFragment";
    
      
    
        @Override
        public void onResume() {
            super.onResume();
            Log.d("xls", "FindFragment onResume");
            if(isFirstVisible){
                LogUtil.d("xiong","FindFragment 第一次可见");
    
            }
        }
    
        
    
        @Override
        public void onHiddenChanged(boolean hidden) {
            Log.d("xls", "FindFragment onHiddenChanged : " + hidden);
            if (hidden) {
                //隐藏
                isFirstVisible = false;
            } else {
                //显示
                LogUtil.d("xiong","FindFragment 显示");
            }
        }
    }
    

    第一次可见在 onResume中,if语句里,后面就都是在onHiddenChanged方法里。

    二,ViewPager+Fragment配合使用

    主要方式:通过重写setUserVisibleHint方法。

    同样的先写一个BaseFragment:

    public class BaseFragment extends Fragment {
    
    
        protected boolean isVisible;
        public BaseFragment() {
            // Required empty public constructor
        }
    
    
        @Override
        public void setUserVisibleHint(boolean isVisibleToUser) {
            super.setUserVisibleHint(isVisibleToUser);
            if(isVisibleToUser){
                isVisible = true;
                onVisible();
            }else{
                isVisible = false;
                onInVisible();
            }
        }
    
        public void onVisible(){
    
        }
    
        public void onInVisible(){
    
        }
    }
    

    BaseFrament里面增加了两个方法onVisible 和 onInVisible用于给子Fragment回调。当然这个位置可以根据自己的习惯去定义回调方式。

    具体的子Fragment如下:

    public class ProducingFragment extends BaseFragment  {
    
    
    
        public ProducingFragment() {
    
        }
    
    
        @Override
        public void onResume() {
            super.onResume();
        }
    
       
        
        @Override
        public void onVisible() {
            super.onVisible();
            Log.d("xls", "producingFragment is Visible");
            if (!isResumed()) {
                return;
            }
          //do your work  here
    
        }
    
        @Override
        public void onInVisible() {
            super.onInVisible();
            Log.d("xls", "producingFragment is InVisible");
           
        }
       
    }
    

    需要注意的是,setUserVisibleHint这个方法是被系统调用的,一般最早的一次是在fragment的onResume方法被调用之前,如果这个时候你的控件都没有初始化完成,就会出问题。所以在 onVisible方法里 加了一个判断,看这个Fragment是否已经Resume了,再去处理业务逻辑。
    如果要做第一次显示判断,则跟第一种方式逻辑类似。

    以上为个人的总结,欢迎各位同道点评。。。。

    相关文章

      网友评论

          本文标题:Android中Fragment可见性时机控制

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