Android中Fragment可见性时机控制

2017-10-13  本文已影响0人  雾中的影子

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

不管上述哪种情况,我们在大多数情况下,都需要知道具体哪个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了,再去处理业务逻辑。
如果要做第一次显示判断,则跟第一种方式逻辑类似。

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

上一篇下一篇

猜你喜欢

热点阅读