Fragment中 onHiddenChanged()方法

      Fragment 我们大家经常用的一个“碎片”控件,在fragment的切换中我们会用到hide(),show()方法,当然了这只是fragment之间切换的一种方法,今天我们我们不讲fragment是怎么切换的,而是谈谈fragment中的onHiddenChanged()方法。

  最近我在项目中遇到一个对于新手(也包括我啊)来说比较蛋疼的BUG,先看一下问题所在,然后我在讲解。


    大家发现问题所在了吗?   “工作”,“应用”,“统计”,“我的”,这四个模块都是fragment页面,在“统计”页面中又有“同事”,“我的”两个fragment组成,而在每一个页面中都会有一个popupwindow弹出,(这个popupwindow是我自定义的,之中设置了setOutsideTouchable(false),后面会有详细介绍),当我切换“同事”,“我的”两个fragment时,popupwindow会消失,点击列表进去日志页面时也会消失,点击空白处不会消失,(这些都没问题),但是当我切换 “工作”,“应用”,“统计”,“我的”四个fragment时,popupwindow不会消失(问题所在),这是为什么呢?

当我切换“同事”,“我的”两个fragment时,popupwindow会消失。是因为我在“同事”,“我的”两个fragment中分别设置了:

 @Override
    public void onPause() {
        super.onPause();
        if (timeChoosePopupWindow.isShowing()){
            timeChoosePopupWindow.dismiss();
        }
    }

点击空白处不会消失

setOutsideTouchable(false)
好了!我们先看一下,popupwindow:


/**
 * 任务列表中的时间筛选
 */
public class TimeChoosePopupWindow extends PopupWindow{
    private View conentView;
    private Activity activity;
    private TextView tv_start;
    private TextView tv_end;
    private Button bt_submit;
    private TimePickerView timePickerView;

    private String time_start ;
    private String time_end ;

    private Boolean isEndTime = false;//判断选择的是开始时间还是结束时间
    private LinearLayout ll_content;

    public TimeChoosePopupWindow(Activity activity) {
        this.activity = activity;
        initView();
        setOutsideTouchable(false);
    }

    @Override
    public void showAsDropDown(View anchor) {
        setAnimationStyle(R.anim.bottom_enter); //PopupWindow 显示 的动画效果
        super.showAsDropDown(anchor);
    }

    @Override
    public void dismiss() {
        setAnimationStyle(R.anim.bottom_exit);//PopupWindow 消失 的动画效果
        super.dismiss();
    }

    private void initView(){
        initTimePickerView();

        LayoutInflater inflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        conentView = inflater.inflate(R.layout.popup_time_choose, null);
        tv_start = (TextView) conentView.findViewById(R.id.tv_start);
        ll_content = (LinearLayout) conentView.findViewById(R.id.ll_content);
        tv_end = (TextView) conentView.findViewById(R.id.tv_end);
        bt_submit = (Button) conentView.findViewById(R.id.bt_submit);

        time_start = DateUtils.currentYM() + "-01";
        time_end = DateUtils.currentYMD();
        tv_start.setText(time_start);//起始时间为当月1号
        tv_end.setText(time_end); //结束时间为本月当天`
        setWidth(ViewGroup.LayoutParams.MATCH_PARENT);
        setHeight(ViewGroup.LayoutParams.WRAP_CONTENT);
        setContentView(conentView);

        tv_start.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                isEndTime = false;
                timePickerView.setTime(DateUtils.Str2DateYMD(time_start));
                timePickerView.show();
                ll_content.setVisibility(View.VISIBLE);
            }
        });

        tv_end.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                isEndTime = true;
                timePickerView.setTime(DateUtils.Str2DateYMD(time_end));
                timePickerView.show();
                ll_content.setVisibility(View.VISIBLE);
            }
        });

        bt_submit.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //确定
                if (onClickSureListener != null){
                    onClickSureListener.clickSure(time_start,time_end);
                }else {
                    Log.d("-----", "onClick() returned: " + "onClickSureListener == null");
                }

            }
        });
    }

    /**
     * 初始化时间选择器
     */
    private void initTimePickerView(){
        timePickerView = new TimePickerView(activity, TimePickerView.Type.YEAR_MONTH_DAY);
        //控制时间范围
        Calendar calendar = Calendar.getInstance();
        timePickerView.setRange(calendar.get(Calendar.YEAR) - 20, calendar.get(Calendar.YEAR) + 20);//要在setTime 之前才有效果哦
        timePickerView.setCyclic(true);
        timePickerView.setTime(new Date());
        timePickerView.setCancelable(false);

        timePickerView.setOnTimeSelectListener(new TimePickerView.OnTimeSelectListener() {
            @Override
            public void onTimeSelect(Date date) {
                if (!isEndTime){
                    //开始时间
                    time_start =  DateUtils.getTimeYMD(date);
                    tv_start.setText(time_start);
                }else {
                    //结束时间
                    time_end =  DateUtils.getTimeYMD(date);
                    tv_end.setText(time_end);
                }
            }
        });

        timePickerView.setOnDismissListener(new com.bigkoo.pickerview.listener.OnDismissListener() {
            @Override
            public void onDismiss(Object o) {
                ll_content.setVisibility(View.GONE);
            }
        });

    }


    //自定义点击确定接口
    public interface OnClickSureListener{
        void clickSure(String startTime,String endTime);
    }
    private OnClickSureListener onClickSureListener;

    public void setOnClickSureListener(OnClickSureListener onClickSureListener) {
        this.onClickSureListener = onClickSureListener;
    }

    /**
     * 展示popupwindow
     * @param view
     * @param time_start
     * @param time_end
     */
    public void showAsDropDown_My(View view,String time_start,String time_end){
        this.time_start = time_start;
        this.time_end = time_end;
        tv_start.setText(time_start);
        tv_end.setText(time_end);
        showAsDropDown(view);
    }

    //学习模仿写接口
    public interface OnClickCancleListener{
        //如果有取消按钮,参数就是点击取消(目的:传数据/跳转)时所需要的参数
        void clickCancle(String timeStart, String timeEnd);
    }
    private OnClickCancleListener onClickCancleListener;

    public void setOnClickCancleListener(OnClickCancleListener onClickCancleListener){

        this.onClickCancleListener = onClickCancleListener;
    }

}
具体的popupwindow实现我就不解释了,我们只针对这个问题讲解。

然后我就想把popupwindow设置为点击外部可以取消,来解决这个问题:

 public TimeChoosePopupWindow(Activity activity) {
        this.activity = activity;
        initView();
      
        setOutsideTouchable(true);
        setFocusable(true);
        setBackgroundDrawable(new BitmapDrawable());

    }
大家来看一下效果:


怎么样,大家是不是认为问题解决了,哈哈哈!!!,告诉你,还远远没有,我们再看下接下来的效果你就知道问题所在了:


    发现了吗?我们本来的需求是:点击日期选择栏弹出日期选择器的popupwindow,然后我们选择日期,改变日期选择栏的日期并进行查询,但是现在我们选择日期是点击的话,popupwindow就会消失,为什么呢?

    其实我们一开始就进入了误区,并不是popupwindow点击外部是否消失的问题,也不是点击“同事”,“我的”切换时焦点获取的问题,而是 “统计”与“工作”这三个fragment在切换时 hide(),show ()时 ,“统计”模块中“同事”,“我的”两个模块的fragment的焦点获取的问题。然后我们在 “统计”的页面中加入onHiddenChanged()的方法来切换焦点:

/**
 * Created by 李金伟 on 2017/5/2.
 * 统计
 */
public class StatisticsFragment extends BaseFragment {

    private ImageView iv_back;
    private TextView tv_colleague;
    private ImageView iv_colleague_line;
    private RelativeLayout rv_colleague;
    private TextView tv_my;
    private ImageView iv_my_line;
    private RelativeLayout rv_my;
    private FrameLayout fl_statistics_content;
    private FragmentManager fragmentManager;
    private FragmentTransaction beginTransaction;
    private OA_StatisticColleagueFragment oa_statisticcolleaguefragment;
    private OA_StatisticMyFragment oa_statisticmyfragment;
    private Fragment currentFragment;

    @Override
    public int getLayoutResId() {
        return R.layout.fragment_statistics;
    }

    @Override
    public void initView(View view) {
        iv_back = (ImageView) view.findViewById(R.id.iv_back);
        tv_colleague = (TextView) view.findViewById(R.id.tv_colleague);
        iv_colleague_line = (ImageView) view.findViewById(R.id.iv_colleague_line);
        rv_colleague = (RelativeLayout) view.findViewById(R.id.rv_colleague);
        tv_my = (TextView) view.findViewById(R.id.tv_my);
        iv_my_line = (ImageView) view.findViewById(R.id.iv_my_line);
        rv_my = (RelativeLayout) view.findViewById(R.id.rv_my);
        fl_statistics_content = (FrameLayout) view.findViewById(R.id.fl_statistics_content);

        // 获取FragmentManager管理者
        fragmentManager = getActivity().getSupportFragmentManager();
        // 开启事务
        beginTransaction = fragmentManager.beginTransaction();

        if (oa_statisticcolleaguefragment == null) {
            oa_statisticcolleaguefragment = new OA_StatisticColleagueFragment();
            tv_colleague.setSelected(true);
            tv_my.setSelected(false);
            iv_colleague_line.setVisibility(View.VISIBLE);
            iv_my_line.setVisibility(View.INVISIBLE);
        }

        currentFragment = oa_statisticcolleaguefragment;
        // 添加事务
        beginTransaction.add(R.id.fl_statistics_content, oa_statisticcolleaguefragment);
        beginTransaction.commit();

    }

    @Override
    public void initListener() {
        rv_colleague.setOnClickListener(this);
        rv_my.setOnClickListener(this);
        iv_back.setOnClickListener(this);
    }

    @Override
    public void initData() {

    }

    @Override
    public void onClick(View view) {
        // 开启事务
        FragmentTransaction beginTransaction = fragmentManager.beginTransaction();
        switch (view.getId()) {
            case R.id.iv_back:
                //点击返回
                getActivity().finish();
                break;

            case R.id.rv_colleague:
                tv_colleague.setSelected(true);
                tv_my.setSelected(false);
                iv_colleague_line.setVisibility(View.VISIBLE);
                iv_my_line.setVisibility(View.INVISIBLE);

                if (oa_statisticcolleaguefragment == null) {
                    oa_statisticcolleaguefragment = new OA_StatisticColleagueFragment();
                }
                currentFragment = oa_statisticcolleaguefragment;
                // 替换事务 同事
                beginTransaction.replace(R.id.fl_statistics_content, oa_statisticcolleaguefragment);
                beginTransaction.commit();

                break;
            case R.id.rv_my:
                tv_colleague.setSelected(false);
                tv_my.setSelected(true);
                iv_colleague_line.setVisibility(View.INVISIBLE);
                iv_my_line.setVisibility(View.VISIBLE);
                if (oa_statisticmyfragment == null) {
                    oa_statisticmyfragment = new OA_StatisticMyFragment();
                }
                currentFragment= oa_statisticmyfragment;
                // 替换事务 我的
                beginTransaction.replace(R.id.fl_statistics_content, oa_statisticmyfragment);
                beginTransaction.commit();

                break;
        }
    }

    @Override
    public void onHiddenChanged(boolean hidden) {
        super.onHiddenChanged(hidden);
        if (hidden){
            currentFragment.onPause();
        }else {
            currentFragment.onResume();
        }
    }
}
这样问题就解决了,我们看下效果:



    public final boolean isHidden() 总结:
    如果该Fragment对象已经被隐藏,那么它返回true。默认情况下,Fragment是被显示的。能够用onHiddenChanged(boolean)回调方法获取该Fragment对象状态的改变,要注意的是隐藏状态与其他状态是正交的---也就是说,要把该Fragment对象显示给用户,Fragment对象必须是被启动并不被隐藏。

OK! 小伙伴们,这篇文章是根据我自己遇到的问题所写,还很不全面,只是针对问题而已,如果你有不明白的,还请留言哦!吐舌头




  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值