26

我正在做一个项目,我需要能够使用每个片段中的后退按钮在以前的片段之间导航,我有通过在操作栏中使用后退箭头编写的方法,但是,我希望能够在按下的后退按钮上使用相同的功能。我不想使用后台堆栈。有没有办法做到这一点?

编辑

我希望能够在用户单击后退按钮时调用下面的返回上一个方法,而不是使用后退堆栈。我需要在片段中使用 gobackpressed 方法。这可能吗?我希望这是清晰和简洁的。对于上述造成的任何混淆,我们深表歉意。

返回上一个

public void gobackToPreviousFragment(String preFragmentTag, Fragment preFragment){

    FragmentManager  fm = getSupportFragmentManager();

    FragmentTransaction ft = fm.beginTransaction();
    ft.setCustomAnimations(R.animator.close_slide_in,R.animator.close_slide_out);

    ft.show(preFragment);

    //**BY REMOVING FRAGMENT, WHEN USER TRIES TO REVISIT, FRAGMENT IS BLACK**

    ft.remove(fm.findFragmentByTag(Misc.currentContentFragmentTag));
    ft.addToBackStack(null);
    ft.commit();

    Misc.currentContentFragmentTag = preFragmentTag;

    createBar(preFragment);
}

直走

public void gotoNextFragment(String nextTag, Fragment nextFragment){

    FragmentManager  fm = getSupportFragmentManager();

    FragmentTransaction ft = fm.beginTransaction();
    ft.setCustomAnimations(R.animator.enter_slide_in, R.animator.enter_slide_out);

    boolean newlyCreated = false;
    if(nextFragment == null){
        nextFragment = Fragment.instantiate(this, nextTag);
        newlyCreated = true;
    }

    //hide current fragment
    ft.hide(fm.findFragmentByTag(Misc.currentContentFragmentTag));

    if(newlyCreated){
        ft.add(R.id.content_frame, nextFragment, nextTag);
    }
    else{
        ft.show(nextFragment);
    }

    ft.addToBackStack(null);
    ft.commit();
    Misc.currentContentFragmentTag = nextTag;

    createBar(nextFragment);
}

这些是我来回导航的方式,我希望能够在 onBackPressed() 上实现返回方法。这有意义吗?

4

9 回答 9

35

我没有找到关于这个问题的任何好的答案,所以这是我的解决方案。

如果您想在每个片段中获取 backPress,请执行以下操作。

创建接口OnBackPressedListener

public interface OnBackPressedListener {
    void onBackPressed();
}

每个想要被通知的片段都backPress 实现了这个接口

在父活动中,您可以覆盖onBackPressed()

@Override
public void onBackPressed() {
    List<Fragment> fragmentList = getSupportFragmentManager().getFragments();
    if (fragmentList != null) {
        //TODO: Perform your logic to pass back press here
        for(Fragment fragment : fragmentList){
           if(fragment instanceof OnBackPressedListener){
               ((OnBackPressedListener)fragment).onBackPressed();
           }
        }
    }
}
于 2015-08-11T13:49:16.620 回答
24

为什么不想使用后台堆栈?如果存在潜在问题或困惑,也许我们可以为您解决。

如果您想坚持您的要求,只需覆盖 Activity 的 onBackPressed() 方法,并在单击 ActionBar 中的后退箭头时调用您正在调用的任何方法。

编辑:如何解决“黑屏”片段回栈问题:

您可以通过向片段管理器添加一个 backstack 侦听器来解决该问题。该侦听器检查片段返回堆栈是否为空并相应地完成活动:

您可以在 Activity 的 onCreate 方法中设置该侦听器:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    FragmentManager fm = getFragmentManager();
    fm.addOnBackStackChangedListener(new OnBackStackChangedListener() {
        @Override
        public void onBackStackChanged() {
            if(getFragmentManager().getBackStackEntryCount() == 0) finish();
        }
    });
}
于 2013-08-12T14:54:55.407 回答
3

在您想要处理后退按钮的片段中,您应该将内容附加到 oncreateview 中的视图

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View v = inflater.inflate(R.layout.second_fragment, container, false);
    v.setOnKeyListener(pressed);
    return v;
}



@Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
    // TODO Auto-generated method stub
    if( keyCode == KeyEvent.KEYCODE_BACK ){
            // back to previous fragment by tag
            myfragmentclass fragment = (myfragmentclass) getActivity().getSupportFragmentManager().findFragmentByTag(TAG);
            if(fragment != null){
                (getActivity().getSupportFragmentManager().beginTransaction()).replace(R.id.cf_g1_mainframe_fm, fragment).commit();
            }
            return true;
        }
        return false;
    }
};
于 2013-10-16T14:49:45.593 回答
3
requireActivity().onBackPressedDispatcher.addCallback(viewLifecycleOwner, object : OnBackPressedCallback(true) {
            override fun handleOnBackPressed() {
                Log.w("a","")
            }
        })
于 2020-08-06T11:38:04.643 回答
2

您可以尝试覆盖onCreateAnimation、参数和捕获enter==false。这将在每次后按之前触发。

@Override
public Animation onCreateAnimation(int transit, boolean enter, int nextAnim) {            
        if(!enter){
            //leaving fragment
            Log.d(TAG,"leaving fragment");
        }
        return super.onCreateAnimation(transit, enter, nextAnim);
    }
于 2014-01-23T09:55:10.070 回答
2

对于片段,您可以简单地添加

  getActivity().onBackPressed();

到你的代码

于 2017-07-10T14:19:24.843 回答
2

这对我有用:D

    @Override
    public void onResume() {
    super.onResume();

    if(getView() == null){
        return;
    }

    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){
                // handle back button's click listener
                return true;
            }
            return false;
        }
    });}
于 2020-07-24T06:01:53.247 回答
1

我找到了一种没有接口的新方法。您只需将以下代码添加到Fragment 的 onCreate() 方法

//overriding the fragment's oncreate 
override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        //calling onBackPressedDispatcher and adding call back

        requireActivity().onBackPressedDispatcher.addCallback(this) {

      //do stuff here
            
        }
    }
于 2020-08-18T05:58:47.847 回答
-6

用这个:

@Override
public void onBackPressed() {
    int fragments = getFragmentManager().getBackStackEntryCount();
    if (fragments == 1) {
        finish();
    }
    super.onBackPressed();
}
于 2015-02-23T01:01:02.773 回答