如何在片段中实现onBackPressed并到达HomeFragment?

时间:2017-03-17 13:41:49

标签: android android-fragments onbackpressed

我正在使用3 Fragment(HomeFragment,RegisterFragment和NewsFragment)。当我点击Back Button时,如何从NewsFragment移动到直接HomeFragment。当我点击后退按钮时,我不想移动到其他片段。

5 个答案:

答案 0 :(得分:1)

我创建了一个实用程序类来控制我的片段导航。

以下是本课程的内容:

public class FragmentController {

    private static final String TAG = FragmentController.class.getCanonicalName();
    private static FragmentController mInstance;
    private ArrayList<BaseFragment> mFragmentsList;
    private BaseActivity mActivity;
    private FrameLayout mFragmentContainer;

    public FragmentController(BaseActivity activity) {
        set(activity);
    }

    public static FragmentController getInstance(BaseActivity activity) {
        if (mInstance == null)
            mInstance = new FragmentController(activity);
        return mInstance;
    }

    public static void setInstance(FragmentController mInstance) {
        FragmentController.mInstance = mInstance;
    }

    public void set(BaseActivity activity) {
        mActivity = activity;
        if (mActivity instanceof MainActivity) {
            mFragmentContainer = ((MainActivity) mActivity).getFragmentContainer();
        }
        mFragmentsList = new ArrayList<>();
    }

    public void addFirstFragment(BaseFragment fragment) {
        mFragmentsList.add(fragment);
    }

    public void presentFragment(BaseFragment fragment, boolean removeAllFromBackstack) {
        try {
            Log.d(TAG, "presentFragment: " + fragment.getTagFm());
            if (mActivity.getCurrentFocus() != null) {
                ViewUtils.hideKeyboard(mActivity.getCurrentFocus());
            }
            FragmentTransaction ft = mActivity.getSupportFragmentManager().beginTransaction();
            ft.setCustomAnimations(R.anim.fade_in, R.anim.fade_out);
            ft.replace(mFragmentContainer.getId(), fragment, fragment.getTagFm());
            ft.addToBackStack(fragment.getTagFm());
            ft.commitAllowingStateLoss();
            if (mFragmentsList.size() != 0)
                if (removeAllFromBackstack) {
                    if (mFragmentsList.size() == 2) {
                        mFragmentsList.remove(1);
                    } else if (mFragmentsList.size() > 2) {
                        mFragmentsList.subList(1, mFragmentsList.size()).clear();
                    }
                }
            if (!isFragmentPresent(fragment))
                mFragmentsList.add(fragment);
        } catch (Exception e) {
            e.printStackTrace();


 }
}

public void removeSecondFragment() {
    mFragmentsList.remove(1);
}

private boolean isFragmentPresent(BaseFragment fragment) {
    for (BaseFragment baseFragment : mFragmentsList) {
        if (baseFragment.getTagFm().equals(fragment.getTagFm()))
            return true;
    }
    return false;
}

public BaseFragment getCurrentFragment() {
    return mFragmentsList.get(mFragmentsList.size() - 1);
}

public ArrayList<BaseFragment> getFragmentsList() {
    return mFragmentsList;
}

}

现在,我在Activity

中实例化这个类
mFragmentController = FragmentController.getInstance(this);

现在,我从onBackPressed()

执行此操作Activity
@Override
public void onBackPressed() {
    if (mFragmentController.getFragmentsList().size() == 1) {
        finish();
    } 
    else {
        mFragmentController.getFragmentsList().remove(mFragmentController.getFragmentsList().size() - 1);
        mFragmentController.presentFragment(mFragmentController.getFragmentsList().get(mFragmentController.getFragmentsList().size() - 1), false);
    }
}

FragmentController课程中,您会看到我在getTagFm()课程中使用方法BaseFragment。这基本上是为了识别哪个片段存在于que中而哪些片段不存在。 BaseFragment类将是这样的:

public class BaseFragment extends Fragment {

 public String getTagFm() {
        if (this.getClass().getSimpleName().equals(LoginFragment.class.getSimpleName())) {
            return Constants.TAG_FRAGMENT_LOGIN;
        } else if (this.getClass().getSimpleName().equals(OrderFragment.class.getSimpleName())) {
            return Constants.TAG_FRAGMENT_ORDER;
        } else if (this.getClass().getSimpleName().equals(ProgramFragment.class.getSimpleName())) {
            return Constants.TAG_FRAGMENT_PROGRAM;
        } 
        return Constants.TAG_FRAGMENT_ORDER;
    }

}

所有这些片段(LoginFragmentOrderFragmentProgramFragment)都延伸BaseFragment

希望这有助于某人。

答案 1 :(得分:0)

在NewsFragment中:

@Override
public boolean onKeyDown(int keyCode, KeyEvent event)  {
    if (Integer.parseInt(android.os.Build.VERSION.SDK) > 5
            && keyCode == KeyEvent.KEYCODE_BACK
            && event.getRepeatCount() == 0) {
        onBackPressed();
        return true; 
    }
    return super.onKeyDown(keyCode, event);
}


@Override
public void onBackPressed() {
   HomeFragment f = (HomeFragment) getSupportFragmentManager().findFragmentById(R.id.fragment_home);
   FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
   ft.show(f);
}

答案 2 :(得分:0)

您可能有一个Activity处理所有这些片段替换。在此Activity中,如果使用实际显示片段定义变量,则可以覆盖onBackPressed并检查它是否显示NewsFragment并将其替换为HomeFragment。

@Override
public void onBackPressed() {
    if(actualFragment instanceof NewsFragment) {
        HomeFragment homeFragment = new HomeFragment();
        FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
        transaction.replace(R.id.fragment_container, homeFragment);
        transaction.commit();
    }
}

答案 3 :(得分:0)

当我按下返回按钮时,这就形成了我的作品!

我不了解您的fragment结构,但我使用了一个layout并将其替换为相应的fragment

这是我的代码:

@Override
    //Pressed return button - returns to the results menu
    public void onResume() {
        super.onResume();
        getView().setFocusableInTouchMode(true);
        getView().requestFocus();
        getView().setOnKeyListener(new View.OnKeyListener() {
            @Override
            public boolean onKey(View v, int keyCode, KeyEvent event) {

                if (event.getAction() == KeyEvent.ACTION_UP && keyCode == KeyEvent.KEYCODE_BACK){
                    frag_name frag_name = new frag_name();
                    FragmentManager manager = getActivity().getSupportFragmentManager();
                    manager.beginTransaction().replace(R.id.yourlayout, frag_name, frag_name.getTag()).commit();
                   return true;
                }
                return false;
            }
        });
    }

答案 4 :(得分:0)

不是在后面按下检查每个片段,而是维护一个堆栈,使每个片段的轨道保持在视图层次结构中。

    Stack<Fragment> fragmentStack= new Stack<Fragment>();
    // add first fragment
    FragmentManager  fragmentManager = getSupportFragmentManager();
    FragmentTransaction ft = fragmentManager.beginTransaction();
    ft.add(R.id.container, "your fragment object");
    //push it in stack
    fragmentStack.push(homeListFragment);
    ft.commit();

// add second fragment
ResultListFragment resultListFragment = new ResultListFragment();
    ft.add(R.id.container, resultListFragment);
    fragmentStack.lastElement().onPause();
    ft.hide(fragmentStack.lastElement());
    fragmentStack.push(resultListFragment);
    ft.commit();

//now back button press logic
@Override
public void onBackPressed() {

    if (fragmentStack.size() == 2) {
        FragmentTransaction ft = fragmentManager.beginTransaction();
        fragmentStack.lastElement().onPause();
        ft.remove(fragmentStack.pop());
        fragmentStack.lastElement().onResume();
        ft.show(fragmentStack.lastElement());
        ft.commit();
    } else {
        super.onBackPressed();
    }
}