|
14 | 14 | import android.view.View;
|
15 | 15 | import android.view.ViewGroup;
|
16 | 16 | import android.view.ViewTreeObserver.OnWindowFocusChangeListener;
|
| 17 | +import android.window.OnBackInvokedCallback; |
| 18 | +import android.window.OnBackInvokedDispatcher; |
17 | 19 | import androidx.activity.OnBackPressedCallback;
|
18 | 20 | import androidx.annotation.NonNull;
|
19 | 21 | import androidx.annotation.Nullable;
|
@@ -170,6 +172,8 @@ public class FlutterFragment extends Fragment
|
170 | 172 | protected static final String ARG_SHOULD_AUTOMATICALLY_HANDLE_ON_BACK_PRESSED =
|
171 | 173 | "should_automatically_handle_on_back_pressed";
|
172 | 174 |
|
| 175 | + private boolean hasRegisteredBackCallback = false; |
| 176 | + |
173 | 177 | @RequiresApi(18)
|
174 | 178 | private final OnWindowFocusChangeListener onWindowFocusChangeListener =
|
175 | 179 | Build.VERSION.SDK_INT >= 18
|
@@ -1023,6 +1027,20 @@ public void handleOnBackPressed() {
|
1023 | 1027 | }
|
1024 | 1028 | };
|
1025 | 1029 |
|
| 1030 | + private final OnBackInvokedCallback onBackInvokedCallback = |
| 1031 | + Build.VERSION.SDK_INT >= 33 |
| 1032 | + ? new OnBackInvokedCallback() { |
| 1033 | + // TODO(garyq): Remove SuppressWarnings annotation. This was added to workaround |
| 1034 | + // a google3 bug where the linter is not properly running against API 33, causing |
| 1035 | + // a failure here. See b/243609613 and https://github.com/flutter/flutter/issues/111295 |
| 1036 | + @SuppressWarnings("Override") |
| 1037 | + @Override |
| 1038 | + public void onBackInvoked() { |
| 1039 | + onBackPressed(); |
| 1040 | + } |
| 1041 | + } |
| 1042 | + : null; |
| 1043 | + |
1026 | 1044 | public FlutterFragment() {
|
1027 | 1045 | // Ensure that we at least have an empty Bundle of arguments so that we don't
|
1028 | 1046 | // need to continually check for null arguments before grabbing one.
|
@@ -1060,9 +1078,11 @@ public void onAttach(@NonNull Context context) {
|
1060 | 1078 | super.onAttach(context);
|
1061 | 1079 | delegate = delegateFactory.createDelegate(this);
|
1062 | 1080 | delegate.onAttach(context);
|
| 1081 | + /* |
1063 | 1082 | if (getArguments().getBoolean(ARG_SHOULD_AUTOMATICALLY_HANDLE_ON_BACK_PRESSED, false)) {
|
1064 | 1083 | requireActivity().getOnBackPressedDispatcher().addCallback(this, onBackPressedCallback);
|
1065 | 1084 | }
|
| 1085 | + */ |
1066 | 1086 | context.registerComponentCallbacks(this);
|
1067 | 1087 | }
|
1068 | 1088 |
|
@@ -1684,6 +1704,55 @@ public boolean popSystemNavigator() {
|
1684 | 1704 | return false;
|
1685 | 1705 | }
|
1686 | 1706 |
|
| 1707 | + @Override |
| 1708 | + public void setFrameworkHandlesBack(boolean frameworkHandlesBack) { |
| 1709 | + Log.e( |
| 1710 | + "justin", |
| 1711 | + "setFrameworkHandlesBack in FlutterFragment! setEnabled: " + frameworkHandlesBack); |
| 1712 | + if (frameworkHandlesBack && !hasRegisteredBackCallback) { |
| 1713 | + registerOnBackInvokedCallback(); |
| 1714 | + } else if (!frameworkHandlesBack && hasRegisteredBackCallback) { |
| 1715 | + unregisterOnBackInvokedCallback(); |
| 1716 | + } |
| 1717 | + } |
| 1718 | + |
| 1719 | + /** |
| 1720 | + * Registers the callback with OnBackPressedDispatcher to capture back navigation gestures and |
| 1721 | + * pass them to the framework. |
| 1722 | + * |
| 1723 | + * <p>This replaces the deprecated onBackPressed method override in order to support API 33's |
| 1724 | + * predictive back navigation feature. |
| 1725 | + * |
| 1726 | + * <p>The callback must be unregistered in order to prevent unpredictable behavior once outside |
| 1727 | + * the Flutter app. |
| 1728 | + */ |
| 1729 | + @VisibleForTesting |
| 1730 | + public void registerOnBackInvokedCallback() { |
| 1731 | + if (Build.VERSION.SDK_INT >= 33) { |
| 1732 | + getActivity() |
| 1733 | + .getOnBackInvokedDispatcher() |
| 1734 | + .registerOnBackInvokedCallback( |
| 1735 | + OnBackInvokedDispatcher.PRIORITY_DEFAULT, onBackInvokedCallback); |
| 1736 | + hasRegisteredBackCallback = true; |
| 1737 | + } |
| 1738 | + } |
| 1739 | + |
| 1740 | + /** |
| 1741 | + * Unregisters the callback from OnBackPressedDispatcher. |
| 1742 | + * |
| 1743 | + * <p>This should be called when the activity is no longer in use to prevent unpredictable |
| 1744 | + * behavior such as being stuck and unable to press back. |
| 1745 | + */ |
| 1746 | + @VisibleForTesting |
| 1747 | + public void unregisterOnBackInvokedCallback() { |
| 1748 | + if (Build.VERSION.SDK_INT >= 33) { |
| 1749 | + getActivity() |
| 1750 | + .getOnBackInvokedDispatcher() |
| 1751 | + .unregisterOnBackInvokedCallback(onBackInvokedCallback); |
| 1752 | + hasRegisteredBackCallback = false; |
| 1753 | + } |
| 1754 | + } |
| 1755 | + |
1687 | 1756 | @VisibleForTesting
|
1688 | 1757 | @NonNull
|
1689 | 1758 | boolean shouldDelayFirstAndroidViewDraw() {
|
|
0 commit comments