是否有一种方法,我们可以实现onBackPressed()在Android片段类似的方式,我们实现在Android活动?

因为Fragment的生命周期没有onBackPressed()。在android3.0片段中是否有其他替代方法来覆盖onBackPressed() ?


当前回答

更新:OnBackPressedDispatcher应该被使用。

指南如何使用可在developer.android.com/guide/navigation/navigation-custom-back


你可以在activity中注册fragment来处理背按:

interface BackPressRegistrar {
    fun registerHandler(handler: BackPressHandler)
    fun unregisterHandler(handler: BackPressHandler)
}

interface BackPressHandler {
    fun onBackPressed(): Boolean
}

用法:

在片段:

private val backPressHandler = object : BackPressHandler {
    override fun onBackPressed(): Boolean {
        showClosingWarning()
        return false
    }
}

override fun onResume() {
    super.onResume()
    (activity as? BackPressRegistrar)?.registerHandler(backPressHandler)
}

override fun onStop() {
    (activity as? BackPressRegistrar)?.unregisterHandler(backPressHandler)
    super.onStop()
}

在活动:

class MainActivity : AppCompatActivity(), BackPressRegistrar {


    private var registeredHandler: BackPressHandler? = null
    override fun registerHandler(handler: BackPressHandler) { registeredHandler = handler }
    override fun unregisterHandler(handler: BackPressHandler) { registeredHandler = null }

    override fun onBackPressed() {
        if (registeredHandler?.onBackPressed() != false) super.onBackPressed()
    }
}

其他回答

新的和更好的方法:以下片段中的代码段将帮助您捕获反按事件。

JAVA

@Override
public void onAttach(@NonNull Context context) {
    super.onAttach(context);

    OnBackPressedCallback callback = new OnBackPressedCallback(true) {
        @Override
        public void handleOnBackPressed() {
            Toast.makeText(mContext, "back pressed", Toast.LENGTH_SHORT).show();
            
            // And when you want to go back based on your condition
            if (yourCondition) {
                this.setEnabled(false);
                requireActivity().onBackPressed();
            }
        }
    };

    requireActivity().getOnBackPressedDispatcher().addCallback(this, callback);
}

科特林

activity?.onBackPressedDispatcher?.addCallback(viewLifecycleOwner, object : OnBackPressedCallback(true) {
    override fun handleOnBackPressed() {

    }
})

像这样执行 Fragment_1 -> Fragment_2 -> Fragment_3

    Button btn = (Button) rootView.findViewById(R.id.your_button_id);
    btn.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {

            Fragment_2 nextFrag= new Fragment_2();
            getActivity().getSupportFragmentManager().beginTransaction()
                    .replace(R.id.content_frame, nextFrag,getTag())
                    .addToBackStack(null)
                    .commit();

        }
    });

Fragment_3 -> Fragment_2 -> Fragment_1

Step_1:在Base Activity中创建一个可公开访问的字符串

step2:每当一个新的Fragment被激活时,在Base Activity中改变String的值

Step_3:然后添加onBackPressed()方法,并将字符串值传递给另一个方法,其中fagments可以被替换

在基础活动中

public static String currentFragment=null;

@Override
public void onBackPressed() 
{
        displayPreviousFragment(currentFragment);
}

public void displayPreviousFragment(String currentFragment)
{
    //creating fragment object
    Fragment fragment = null;

    //initializing the fragment object which is selected
    switch (currentFragment)
    {
        case "Fragment_2"    :   fragment = new Fargment_1();     break;
        case "Fragment_3"    :   fragment = new Fragment_2();     break;
    }

    //replacing the fragment
    if (fragment != null) {
        FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
        ft.replace(R.id.frame_to_replace_fragment, fragment);
        ft.commit();
    }
}

在Fragment_2 在OnCreateView方法内

BaseActivity.currentFragment="Fragment_2";

在Fragment_3 在OnCreateView方法内

BaseActivity.currentFragment="Fragment_3";

在kotlin的情况下使用这个onAttach回调

        override fun onAttach(context: Context) {
          super.onAttach(context)
           val callback: OnBackPressedCallback = object : 
                 OnBackPressedCallback(true) {
                 override fun handleOnBackPressed() {
                 // your onbackpressed code 


            }
          }
      requireActivity().onBackPressedDispatcher.addCallback(this, callback)
      }
   @Override
   public boolean onKeyDown(int keyCode, KeyEvent event)
    {
       if ((keyCode == KeyEvent.KEYCODE_BACK))
  {
           finish();
    }
       return super.onKeyDown(keyCode, event);
    }

注释任何下键相关的方法现在addToBackStack将工作。 谢谢

我是这样做的,对我很管用

简单的界面

FragmentOnBackClickInterface.java

public interface FragmentOnBackClickInterface {
    void onClick();
}

示例实现

MyFragment.java

public class MyFragment extends Fragment implements FragmentOnBackClickInterface {

// other stuff

public void onClick() {
       // what you want to call onBackPressed?
}

然后在activity中重写onBackPressed

    @Override
public void onBackPressed() {
    int count = getSupportFragmentManager().getBackStackEntryCount();
    List<Fragment> frags = getSupportFragmentManager().getFragments();
    Fragment lastFrag = getLastNotNull(frags);
    //nothing else in back stack || nothing in back stack is instance of our interface
    if (count == 0 || !(lastFrag instanceof FragmentOnBackClickInterface)) {
        super.onBackPressed();
    } else {
        ((FragmentOnBackClickInterface) lastFrag).onClick();
    }
}

private Fragment getLastNotNull(List<Fragment> list){
    for (int i= list.size()-1;i>=0;i--){
        Fragment frag = list.get(i);
        if (frag != null){
            return frag;
        }
    }
    return null;
}