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

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


当前回答

你应该添加接口到你的项目如下;

public interface OnBackPressed {

     void onBackPressed();
}

然后,你应该在你的片段上实现这个接口;

public class SampleFragment extends Fragment implements OnBackPressed {

    @Override
    public void onBackPressed() {
        //on Back Pressed
    }

}

你可以在你的onBackPressed事件下面触发这个onBackPressed事件,如下所示;

public class MainActivity extends AppCompatActivity {
       @Override
        public void onBackPressed() {
                Fragment currentFragment = getSupportFragmentManager().getFragments().get(getSupportFragmentManager().getBackStackEntryCount() - 1);
                if (currentFragment instanceof OnBackPressed) {  
                    ((OnBackPressed) currentFragment).onBackPressed();
                }
                super.onBackPressed();
        }
}

其他回答

我只是使用findFragmentById和转换到片段,并调用处理onBackpressed的方法。这个示例显示了检查这是否是订单流程的第一步,如果弹出一个对话框片段来确认退出订单。

@Override
    public void onBackPressed() {
        //check if first fragment in wizard is loaded, if true get abandon confirmation before going back
        OrderFragment frag =(OrderFragment)getSupportFragmentManager().findFragmentById(R.id.fragContainer);
        if (frag==null || (frag!=null && frag.getOrderStage()<1)){
            AlertDialogFragment.show(getSupportFragmentManager(), R.string.dialog_cancel_order,R.string.dialog_cancel_order_msg, R.string.dialog_cancel_order_pos,R.string.dialog_order_quiz_neg, DIALOG_ID_CANCEL);
        }else {
            super.onBackPressed();
        }
    }

你可以像这样使用父活动的onBackPressedDispatcher:

val backpress = requireActivity().onBackPressedDispatcher.addCallback(viewLifecycleOwner, true) {
            // here dispatcher works for any action when back pressed
}

你也可以从fragment中启用/禁用backpress按钮,如下所示:

backpress.isEnabled = true/false

如果你想要那种功能,你需要在你的活动中覆盖它,然后给你所有的片段添加一个YourBackPressed接口,当你按下后退按钮时,你就会在相关的片段上调用这个接口。

编辑:我想补充我之前的答案。

如果我今天要这样做,我将使用广播,或者如果我希望其他面板同步更新到主/主内容面板,则可能使用有序广播。

支持库中的LocalBroadcastManager可以帮助解决这个问题,你只需要在onBackPressed中发送广播,并在你的片段中订阅。我认为Messaging是一种更加解耦的实现,可伸缩性更好,所以它是我现在的官方实现建议。只要使用Intent的动作作为你信息的过滤器。发送你新创建的ACTION_BACK_PRESSED,从你的活动发送它,并在相关片段中监听它。

使用导航组件,你可以这样做:

Java

public class MyFragment extends Fragment {

@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    // This callback will only be called when MyFragment is at least Started.
    OnBackPressedCallback callback = new OnBackPressedCallback(true /* enabled by default */) {
        @Override
        public void handleOnBackPressed() {
            // Handle the back button event
        }
    });
    requireActivity().getOnBackPressedDispatcher().addCallback(this, callback);

    // The callback can be enabled or disabled here or in handleOnBackPressed()
}
...
}

科特林

class MyFragment : Fragment() {

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)

    // This callback will only be called when MyFragment is at least Started.
    val callback = requireActivity().onBackPressedDispatcher.addCallback(this) {
        // Handle the back button event
    }

    // The callback can be enabled or disabled here or in the lambda
}
...
}

片段: 创建一个BaseFragment,放置一个方法:

 public boolean onBackPressed();

活动:

@Override
public void onBackPressed() {
    List<Fragment> fragments = getSupportFragmentManager().getFragments();
    if (fragments != null) {
        for (Fragment fragment : fragments) {
            if (!fragment.isVisible()) continue;

            if (fragment instanceof BaseFragment && ((BaseFragment) fragment).onBackPressed()) {
                return;
            }
        }
    }

    super.onBackPressed();
}

你的活动将在附加的和可见的片段上运行,并对它们中的每一个调用onBackPressed(),如果其中一个返回'true'(意味着它已经被处理,所以没有进一步的操作),则中止。