簡體   English   中英

如何將 onBackPressedCallback 添加到片段?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM