![](/img/trans.png)
[英]How to fix OnBackPressedCallback if it doesn't work in Fragment?
[英]How to add onBackPressedCallback to fragment?
我已經在幾個地方看到過這一點,但由於沒有在線示例,因此無法完全弄清楚如何實現它,我想知道我是否誤解了它的含義。
用於 addOnBackPressedCallback 的 android 開發人員鏈接
我想知道這是否意味着我可以在我的片段中添加一個回調以在onBackPressed()
到達活動之前獲取它。
在我的片段中,我實現了
implements OnBackPressedCallBack
然后實現了方法
@Override
public boolean handleOnBackPressed() {
Log.d(TAG, "handleOnBackPressed: hello");
return true;
}
但它沒有拿起它並直接進入主要活動onBackPressed()
。
我繼續閱讀,發現我的片段需要從 FragmentActivity 擴展
public class MainExampleFragment extends FragmentActivity implements View.OnClickListener, OnBackPressedCallback {
而不是
appCompatActivity.getSuppportFragmentManager
打電話
FragmentActivity.getSupportFragmentManager
相反,但這會在嘗試設置捆綁包時在 Fragment.newInstance 方法中引發錯誤。
有沒有人做這件事的信息,謝謝
正如@Derek Zhu 指出的那樣,似乎如果您在活動中覆蓋 onBackPressed,那么 Fragment 的 onBackPressedCallback 將不起作用。 我發現如果我還想在活動中使用它,那么我還需要在那里使用onBackPressedDispatcher.addCallback
。
活動:
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()
}
}
}
)
上面的結果是會調用Fragment backpressed,然后Activity backpressed。
這就是我所做的
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();
}
};
}
您必須在 Fragment 中實現回調,以通過調度程序從您的活動中攔截 onBackPressed 事件。
如果有人不知道我正在更新 Fragment 和 AppCompacTActivity 的 OnBackPressedCallBack 並且我在這里嵌套了 Fragment
在片段中
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;
}
你在 MainActivity 中刪除你的 OnBackpressed() 方法並添加這個新方法
OnBackPressedCallback onBackPressedCallback = new OnBackPressedCallback( true ) {
boolean doubleBackToExitPressedOnce=false;
@Override
public void handleOnBackPressed() {
if (doubleBackToExitPressedOnce) {
ActivityCompat.finishAffinity( FirstActivity.this );
Log.e( "Click", "double back" );
return;
}
this.doubleBackToExitPressedOnce = true;
Toast.makeText(FirstActivity.this,getStrin(R.string.exitapp),Toast.LENGTH_SHORT).show();
new Handler().postDelayed( new Runnable() {
@Override
public void run() {
doubleBackToExitPressedOnce=false;
}
}, 2000);
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate( savedInstanceState );
setContentView( R.layout.activity_first );
//getting bottom navigation view and attaching the listener
getOnBackPressedDispatcher().addCallback( this, onBackPressedCallback );
}
AppCompatActivity extends FragmentActivity extends ComponentActivity(androidx.fragment.app.ComponentActivity) extends (androidx.core.app.ComponentActivity)
所以 addOnBackPressedCallback 也應該適用於 AppCompatActivity
Kotlin:
val mOnBackPressedCallback= object : OnBackPressedCallback(true) {
override fun handleOnBackPressed() {
if (active) {
// Do something
} else {
// call onBackPressed() as normal afterwards
remove()
requireActivity().onBackPressed()
}
}
}
向調度程序添加回調: requireActivity().onBackPressedDispatcher.addCallback(viewLifecycleOwner, mOnBackPressedCallback)
更新方法
現在可以很容易地使用https://developer.android.com/reference/androidx/activity/OnBackPressedDispatcher向任何片段添加反壓處理程序
棄用的方法:不要使用
您不能直接處理onBackpressed
內的onBackpressed
。
您可以做的是通過某種方式將onBackPressed
事件傳遞給當前顯示的片段。
一種基本方法是像這樣創建一個界面:
interface BackHandler {
handleBackPressed(): Boolean
}
然后在您的片段上實現它,如下所示:
class YourFragment : Fragment(), BackHandler {
...
override handleBackPressed(): Boolean {
// do Your thing here
}
...
}
在您的 Activity 上onBackPressed
執行此onBackPressed
:
class YourActivity: Activity() {
...
override onBackPressed() {
val currentFragment = supportFragmentManager.findFragmentById(yourviewid)
if (currentFragment is BackHandler) {
(currentFragment as BackHandler).handleBackPressed()
} else {
super.onBackPressed()
}
}
...
}
這只是一種方法。 你也可以使用類似EventBus
或其他一些實現的東西。 關鍵是 Android 沒有為片段提供開箱即用的功能。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.