Android 如何将onBackPressedCallback添加到片段?
我已经在几个地方看到了这一点,但由于网上没有例子,我不知道我是否误解了它的含义,所以我不能完全理解如何实现它 我想知道这是否意味着我可以在片段中添加一个回调,在它进入活动之前提取Android 如何将onBackPressedCallback添加到片段?,android,Android,我已经在几个地方看到了这一点,但由于网上没有例子,我不知道我是否误解了它的含义,所以我不能完全理解如何实现它 我想知道这是否意味着我可以在片段中添加一个回调,在它进入活动之前提取onBackPressed() 在我的片段中,我已经实现了 implements OnBackPressedCallBack @Override public boolean handleOnBackPressed() { Log.d(TAG, "handleOnBackPressed: hello");
onBackPressed()
在我的片段中,我已经实现了
implements OnBackPressedCallBack
@Override
public boolean handleOnBackPressed() {
Log.d(TAG, "handleOnBackPressed: hello");
return true;
}
然后实施该方法
implements OnBackPressedCallBack
@Override
public boolean handleOnBackPressed() {
Log.d(TAG, "handleOnBackPressed: hello");
return true;
}
但它不是拿起它直接进入主要活动onBackPressed()
我进一步阅读,发现我的片段需要从片段活动中扩展出来
public class MainExampleFragment extends FragmentActivity implements View.OnClickListener, OnBackPressedCallback {
而不是
appCompatActivity.getSuppportFragmentManager
召唤
FragmentActivity.getSupportFragmentManager
相反,这会在尝试设置捆绑包时抛出Fragment.newInstance方法并出错
有人知道这方面的信息吗?谢谢
AppCompatActivity扩展碎片Activity扩展
ComponentActivity(androidx.fragment.app.ComponentActivity)扩展了
(androidx.core.app.ComponentActivity)
因此,addOnBackPressedCallback也应该适用于AppCompatActivity更新的方法 现在很容易将backpress处理程序添加到任何具有
不推荐的方法:不要使用 您不能在片段内直接处理反压的
onBackpressed
相反,您可以通过某种方式将onBackPressed
事件传递给当前显示的片段
一种基本的方法是创建这样的接口:
interface BackHandler {
handleBackPressed(): Boolean
}
然后在你的片段上实现如下:
class YourFragment : Fragment(), BackHandler {
...
override handleBackPressed(): Boolean {
// do Your thing here
}
...
}
在您的活动中,请在按下时执行此操作:
class YourActivity: Activity() {
...
override onBackPressed() {
val currentFragment = supportFragmentManager.findFragmentById(yourviewid)
if (currentFragment is BackHandler) {
(currentFragment as BackHandler).handleBackPressed()
} else {
super.onBackPressed()
}
}
...
}
这只是一种方法。您还可以使用类似于
EventBus
或其他实现的东西。关键的一点是Android没有为片段提供这种开箱即用的功能。正如@Derek Zhu所指出的,如果您在活动中覆盖onBackPressed,那么片段的onBackPressed回调就不起作用。我发现如果我想在活动中也使用它,那么我也需要在backpressedDispatcher.addCallback中使用on
活动:
onBackPressedDispatcher.addCallback(
this,
object : OnBackPressedCallback(true) {
override fun handleOnBackPressed() {
Log.d(TAG, "Activity back pressed invoked")
// Do custom work here
// if you want onBackPressed() to be called as normal afterwards
if (isEnabled) {
isEnabled = false
requireActivity().onBackPressed()
}
}
}
)
片段:
requireActivity().onBackPressedDispatcher.addCallback(
this,
object : OnBackPressedCallback(true) {
override fun handleOnBackPressed() {
Log.d(TAG, "Fragment back pressed invoked")
// Do custom work here
// if you want onBackPressed() to be called as normal afterwards
if (isEnabled) {
isEnabled = false
requireActivity().onBackPressed()
}
}
}
)
上面的结果是,将调用back pressed片段,然后调用Activity back pressed。这就是我所做的
public class MyFragment extends Fragment {
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requireActivity().getOnBackPressedDispatcher().addCallback(this, onBackPressedCallback);
}
private final OnBackPressedCallback onBackPressedCallback = new OnBackPressedCallback(true /* Enabled by default */) {
@Override
public void handleOnBackPressed() {
// Handle the back button event
if (fieldsModified()) {
// User made changes on EditText on the Fragment. Confirm exit to avoid loss of data
AlertDialog.Builder builder= new AlertDialog.Builder(getContext());
builder.setMessage(msg_confirm_close_form);
builder.setPositiveButton(R.string.btn_yes, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
closeFragment();
}
});
builder.setNegativeButton(R.string.btn_no, null);
builder.show();
}
else {
closeFragment();
}
}
private void closeFragment() {
// Disable to close fragment
this.setEnabled(false);
requireActivity().getOnBackPressedDispatcher().onBackPressed();
}
};
}
您必须在片段中实现回调,以便通过来自您活动的调度程序截获onBackPressed事件。如果有人不知道我正在更新片段和AppCompacTActivity的OnBackPressedCallBack,并且我在这里嵌套了片段
零碎
public class MessageFragment extends Fragment {
public MessageFragment() {
// Required empty public constructor
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
// This callback will only be called when MyFragment is at least Started.
OnBackPressedCallback callback = new OnBackPressedCallback(true ) {
@Override
public void handleOnBackPressed() {
// Handle the back button event
FragmentManager fm= getFragmentManager();
if (fm != null) {
if (fm.getBackStackEntryCount() > 0) {
fm.popBackStack();
Log.e( "backpress Frag","back" );
}
List<Fragment> fragList = fm.getFragments();
if (fragList != null && fragList.size() > 0) {
for (Fragment frag : fragList) {
if (frag == null) {
continue;
}
if (frag.isVisible()) {
Log.e( "backpress Frag","Visible" );
}
}
}
}
}
};
requireActivity().getOnBackPressedDispatcher().addCallback(this, callback);
super.onCreate( savedInstanceState );
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View root=inflater.inflate( R.layout.fragment_listning, container, false );
return root;
}
在back Press上使用事件总线我遇到了完全相同的问题,因为我在activity中重写了OnBackPress(),并且在某些情况下没有调用super方法,因此,fragment没有接收已调度的事件调用请记住,OnBackPressedCallback
是在最新版本的AppCompat中引入的,该版本是androidx。AppCompat:AppCompat:1.1.0-rc01
截至今天的Requiresponsibility()。getOnBackPressedDispatcher()。onBackPressed()当我写这一行时,应用程序崩溃了。为什么?这种方法对我很有效@SunilChaudhary此片段附加的活动也扩展了androidx.appcompat.app.AppCompatActivity
-可能要检查您扩展的活动类型,并检查您使用的是androidx appcompat依赖项的最新版本。我正在使用androidx.appcompat:appcompat:1.3.0-alpha02这可能也是一种使用接口的方法。但现在这已经过时了,做一些简单的事情,比如在backButtonPress上回调,要做的工作要多得多。顺便说一句,你在“你不能直接处理片段内部的onBackpressed”这句话中是错误的。您可以以不同的方式添加OnBackPressed。请参阅,这是一种不推荐的方法。。我甚至不记得这里有这个。这个答案是在新方法出现前几年发布的。你可以忽略这一点。我会在有时间的时候更新我的答案。