BackHandledFragment
import androidx.fragment.app.Fragment;
import androidx.viewpager.widget.ViewPager;
public abstract class BackHandledFragment extends Fragment implements FragmentBackHandler {
public BackHandledFragment() {
}
@Override
public final boolean onBackPressed() {
return interceptBackPressed()
|| (getBackHandleViewPager() == null
? BackHandlerHelper.handleBackPress(this)
: BackHandlerHelper.handleBackPress(getBackHandleViewPager()));
}
public boolean interceptBackPressed() {
return false;
}
/**
* 2.1 版本已经不在需要单独对ViewPager处理
* @deprecated
*/
@Deprecated
public ViewPager getBackHandleViewPager() {
return null;
}
}
BackHandlerHelper
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentPagerAdapter;
import androidx.fragment.app.FragmentStatePagerAdapter;
import androidx.viewpager.widget.PagerAdapter;
import androidx.viewpager.widget.ViewPager;
import java.util.List;
public class BackHandlerHelper {
/**
* 将back事件分发给 FragmentManager 中管理的子Fragment,如果该 FragmentManager 中的所有Fragment都
* 没有处理back事件,则尝试 FragmentManager.popBackStack()
*
* @return 如果处理了back键则返回 <b>true</b>
* @see #handleBackPress(Fragment)
* @see #handleBackPress(FragmentActivity)
*/
public static boolean handleBackPress(FragmentManager fragmentManager) {
List<Fragment> fragments = fragmentManager.getFragments();
if (fragments == null) return false;
for (int i = fragments.size() - 1; i >= 0; i--) {
Fragment child = fragments.get(i);
if (isFragmentBackHandled(child)) {
return true;
}
}
if (fragmentManager.getBackStackEntryCount() > 0) {
fragmentManager.popBackStack();
return true;
}
return false;
}
/**
* 将back事件分发给Fragment中的子Fragment,
* 该方法调用了 {@link #handleBackPress(FragmentManager)}
*
* @return 如果处理了back键则返回 <b>true</b>
*/
public static boolean handleBackPress(Fragment fragment) {
return handleBackPress(fragment.getChildFragmentManager());
}
/**
* 将back事件分发给Activity中的子Fragment,
* 该方法调用了 {@link #handleBackPress(FragmentManager)}
*
* @return 如果处理了back键则返回 <b>true</b>
*/
public static boolean handleBackPress(FragmentActivity fragmentActivity) {
return handleBackPress(fragmentActivity.getSupportFragmentManager());
}
/**
* 将back事件分发给ViewPager中的Fragment,{@link #handleBackPress(FragmentManager)} 已经实现了对ViewPager的支持,所以自行决定是否使用该方法
*
* @return 如果处理了back键则返回 <b>true</b>
* @see #handleBackPress(FragmentManager)
* @see #handleBackPress(Fragment)
* @see #handleBackPress(FragmentActivity)
*/
public static boolean handleBackPress(ViewPager viewPager) {
if (viewPager == null) return false;
PagerAdapter adapter = viewPager.getAdapter();
if (adapter == null) return false;
int currentItem = viewPager.getCurrentItem();
Fragment fragment;
if (adapter instanceof FragmentPagerAdapter) {
fragment = ((FragmentPagerAdapter) adapter).getItem(currentItem);
} else if (adapter instanceof FragmentStatePagerAdapter) {
fragment = ((FragmentStatePagerAdapter) adapter).getItem(currentItem);
} else {
fragment = null;
}
return isFragmentBackHandled(fragment);
}
/**
* 判断Fragment是否处理了Back键
*
* @return 如果处理了back键则返回 <b>true</b>
*/
public static boolean isFragmentBackHandled(Fragment fragment) {
return fragment != null
&& fragment.isVisible()
&& fragment.getUserVisibleHint() //for ViewPager
&& fragment instanceof FragmentBackHandler
&& ((FragmentBackHandler) fragment).onBackPressed();
}
}
FragmentBackHandler
public interface FragmentBackHandler {
boolean onBackPressed();
}
使用方法:
1、 在Activity中覆盖onBackPressed()方法
public class MyActivity extends FragmentActivity {
@Override
public void onBackPressed() {
if (!BackHandlerHelper.handleBackPress(this)) {
super.onBackPressed();
}
}
}
2、实现 FragmentBackHandler
public class MyFragment extends Fragment implements FragmentBackHandler {
@Override
public boolean onBackPressed() {
if (handleBackPressed) {
//外理返回键
return true;
} else {
// 如果不包含子Fragment
// 或子Fragment没有外理back需求
// 可如直接 return false;
// 注:如果Fragment/Activity 中可以使用ViewPager 代替 this
//
return BackHandlerHelper.handleBackPress(this);
}
}
}
注:
改代码是在https://github.com/ikidou/FragmentBackHandler基础上进行兼容Android X和适配Android Q。