关于Fragment中返回键(onBackPressed)的处理

2 篇文章 0 订阅
1 篇文章 0 订阅
关于Fragment中返回键(onBackPressed)的处理

我们在Android开发中怎么处理返回键的?常见的两种方法:

  • 在Activity中实现如下代码,来监听“返回键”
@Override
    public void onBackPressed() {
        // 这里做返回键的处理
        super.onBackPressed();
    }
  • 或者
@Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK) {

            //这里做返回键的处理
        }

        return super.onKeyDown(keyCode, event);
    }

在Activity中,我们可以通过以上两个方法处理返回键的逻辑,可是在fragment中,没有以上两个方法。我们怎么单独处理每个fragment中的返回键呢?

这里提供一个方法,可供参考:

如上文所叙述的那样,在Activity中实现如下代码

package com.example.onbackpressed;
import android.app.FragmentTransaction;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;

public class MainActivity extends ActionBarActivity implements BackHandledInterface{

    private PlaceholderFragment mPlaceholderFragment;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        if (savedInstanceState == null) {
            FragmentTransaction beginTransaction = getFragmentManager()
                    .beginTransaction();
            beginTransaction.add(R.id.container, new PlaceholderFragment(),
                    "placeholderfragment");
            beginTransaction.commit();
        }
    }

    @Override
    public void setSelectedFragment(PlaceholderFragment selectedFragment) {
        this.mPlaceholderFragment = selectedFragment;
    }


    @Override
    public void onBackPressed() {

        if (mPlaceholderFragment == null|| !mPlaceholderFragment.onBackPressed()) {
            //处理
        } else {
            //处理
            super.onBackPressed();
        }
    }

    }

由以上代码可以看到,在Activity刚被创建时,就实例化了fragment

package com.example.onbackpressed;

import android.app.Activity;
import android.app.Fragment;

public class PlaceholderFragment extends Fragment {

    private BackHandledInterface mBackHandledInterface;
    private int i=1;

    @Override
    public void onAttach(Activity activity) {

        super.onAttach(activity);

        if (!(getActivity() instanceof BackHandledInterface)) {
            throw new ClassCastException(
                    "Hosting Activity must implement BackHandledInterface");
        } else {
            this.mBackHandledInterface = (BackHandledInterface) getActivity();
        }
    }

    @Override
    public void onStart() {
        mBackHandledInterface.setSelectedFragment(this);
        super.onStart();
    }


    public boolean onBackPressed() {
        i++;

        return i>3;
    }

}

在fragment中,fragment刚被Activity创建关联时,fragment会执行生命周期的onAttach方法,在该拿到了Activity的实例,判断Activity是不是实现了BackHandledInterface接口,如果已经实现(我把他理解为继承),这里可以通过面向接口的思想,把Activity转换成“父类”,(如果没有实现BackHandledInterface,报出类型转换异常)。

BackHandledInterface 接口代码如下:

package com.lemeng.weishi.interfaces;

import com.lemeng.weishi.PlaceholderFragment;

public interface BackHandledInterface {

    public abstract void setSelectedFragment(PlaceholderFragment selectedFragment);
}

接着fragment会执行生命周期的onStart方法,通过BackHandledInterface接口(父类)引用调用自己的setSelectedFragment方法,把fragment自己的实例引用传递个了接口的“子类”(Activity)。

这样做的好处是,Activity那边拿到的实例应用,永远都是当前显示的fragment的实例。在Activity中执行onBackPressed时,总是执行的是,当前显示的fragment的中的onBackPressed。

进过上面一个来回,我们拿到了fragment的实例,然后,在Activity的onBackPressed方法中通过判断fragment中的onBackPressed方法返回的boolean值做相应的逻辑处理。

这里还存在一个问题,就是,当有多个Fragment时,我们在Activity中setSelectedFragment这个方法就需要改进。

 @Override
        public void setSelectedFragment(PlaceholderFragment selectedFragment) {
            this.mPlaceholderFragment = selectedFragment;
        }

现在进行改进:如下创建一个接口BackFragmentInterFace。

package com.lemeng.weishi.interfaces;

public interface BackFragmentInterFace {

    public boolean onBackPressed();
}

然后我们的要实现返回键的Fragment实现这个接口
这样写有什么好处?

我们每个Activity中有很多个fragment,我们如果通过不断地判断当前显示的是哪个fragment,然后再去做相应的逻辑处理,就会变麻烦。

会产生如下繁琐的判断逻辑(以下代码可以看出,要进行大量的判断显示隐藏,然后做出相应的处理逻辑相对繁琐复杂):

@Override
    public void onBackPressed() {
        if (getFragmentManager().findFragmentByTag("loginfragment") != null
                && getFragmentManager().findFragmentByTag("loginfragment")
                        .isVisible()) {
            finish();
            return;
        } else if (getFragmentManager().findFragmentByTag("registfragment") != null
                && getFragmentManager().findFragmentByTag("registfragment")
                        .isVisible()) {
            getFragmentManager().popBackStack();

        } else if (getFragmentManager().findFragmentByTag("resetfragment") != null
                && getFragmentManager().findFragmentByTag("resetfragment")
                        .isVisible()) {
            getFragmentManager().popBackStack();

        }
    }

通过比较,大家应该发现这种在fragment中监听返回键的方式的优雅之处了。

  • 4
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值