react-native-screens 5.0.0-alpha.2 → 5.0.0-alpha.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Package.swift +87 -0
- package/README.md +0 -7
- package/android/src/main/cpp/NativeProxy.cpp +30 -6
- package/android/src/main/cpp/NativeProxy.h +7 -1
- package/android/src/main/java/com/swmansion/rnscreens/common/container/Container.kt +8 -0
- package/android/src/main/java/com/swmansion/rnscreens/common/container/ContainerItem.kt +13 -1
- package/android/src/main/java/com/swmansion/rnscreens/common/text/ReactTextAppearance.kt +62 -0
- package/android/src/main/java/com/swmansion/rnscreens/common/text/TextAppearance.kt +20 -0
- package/android/src/main/java/com/swmansion/rnscreens/common/text/TextAppearanceDefaults.kt +65 -0
- package/android/src/main/java/com/swmansion/rnscreens/helpers/PropIconResolver.kt +17 -23
- package/android/src/main/java/com/swmansion/rnscreens/legacy/Screen.kt +3 -1
- package/android/src/main/java/com/swmansion/rnscreens/legacy/ScreenStack.kt +2 -0
- package/android/src/main/java/com/swmansion/rnscreens/modals/formsheet/native/coordinator/FormSheetBehaviorController.kt +49 -18
- package/android/src/main/java/com/swmansion/rnscreens/modals/formsheet/native/coordinator/FormSheetDimensionsCoordinator.kt +65 -40
- package/android/src/main/java/com/swmansion/rnscreens/modals/formsheet/native/coordinator/FormSheetKeyboardCoordinator.kt +101 -0
- package/android/src/main/java/com/swmansion/rnscreens/modals/formsheet/native/coordinator/FormSheetNativeDismissCoordinator.kt +0 -6
- package/android/src/main/java/com/swmansion/rnscreens/modals/formsheet/native/core/FormSheetAvailableHeightProvider.kt +44 -0
- package/android/src/main/java/com/swmansion/rnscreens/modals/formsheet/native/core/FormSheetDialog.kt +35 -3
- package/android/src/main/java/com/swmansion/rnscreens/modals/formsheet/native/core/FormSheetDialogManager.kt +33 -106
- package/android/src/main/java/com/swmansion/rnscreens/modals/formsheet/native/interfaces/FormSheetDialogEventEmitter.kt +2 -0
- package/android/src/main/java/com/swmansion/rnscreens/modals/formsheet/native/model/FormSheetDetents.kt +61 -15
- package/android/src/main/java/com/swmansion/rnscreens/modals/formsheet/native/presentation/FormSheetAnimatorFactory.kt +8 -9
- package/android/src/main/java/com/swmansion/rnscreens/modals/formsheet/native/presentation/FormSheetDimmingManager.kt +115 -0
- package/android/src/main/java/com/swmansion/rnscreens/modals/formsheet/native/presentation/FormSheetDismissalOrigin.kt +22 -0
- package/android/src/main/java/com/swmansion/rnscreens/modals/formsheet/native/presentation/FormSheetPresentation.kt +173 -0
- package/android/src/main/java/com/swmansion/rnscreens/modals/formsheet/native/presentation/FormSheetPresentationManager.kt +141 -49
- package/android/src/main/java/com/swmansion/rnscreens/modals/formsheet/native/presentation/FormSheetPresentationState.kt +1 -1
- package/android/src/main/java/com/swmansion/rnscreens/modals/formsheet/native/presentation/FormSheetStackRegistry.kt +28 -0
- package/android/src/main/java/com/swmansion/rnscreens/modals/formsheet/react/event/FormSheetDismissEvent.kt +29 -0
- package/android/src/main/java/com/swmansion/rnscreens/modals/formsheet/react/host/FormSheetHostEventEmitter.kt +7 -0
- package/android/src/main/java/com/swmansion/rnscreens/modals/formsheet/react/host/FormSheetHostViewManager.kt +2 -0
- package/android/src/main/java/com/swmansion/rnscreens/stack/header/StackHeaderApplicator.kt +369 -58
- package/android/src/main/java/com/swmansion/rnscreens/stack/header/StackHeaderBackPressHandler.kt +11 -0
- package/android/src/main/java/com/swmansion/rnscreens/stack/header/StackHeaderCoordinatorLayout.kt +143 -98
- package/android/src/main/java/com/swmansion/rnscreens/stack/header/appbar/StackHeaderAppBarLayout.kt +155 -23
- package/android/src/main/java/com/swmansion/rnscreens/stack/header/appbar/StackHeaderContentScrimDrawable.kt +36 -0
- package/android/src/main/java/com/swmansion/rnscreens/stack/header/config/StackHeaderCollapsedTitleGravityMode.kt +6 -0
- package/android/src/main/java/com/swmansion/rnscreens/stack/header/config/StackHeaderConfig.kt +170 -167
- package/android/src/main/java/com/swmansion/rnscreens/stack/header/config/StackHeaderConfigViewManager.kt +385 -12
- package/android/src/main/java/com/swmansion/rnscreens/stack/header/config/StackHeaderConfigurationObserver.kt +0 -4
- package/android/src/main/java/com/swmansion/rnscreens/stack/header/config/StackHeaderConfigurationProviding.kt +32 -3
- package/android/src/main/java/com/swmansion/rnscreens/stack/header/config/StackHeaderDelegate.kt +0 -7
- package/android/src/main/java/com/swmansion/rnscreens/stack/header/config/StackHeaderInvalidationFlags.kt +7 -2
- package/android/src/main/java/com/swmansion/rnscreens/stack/header/toolbar/StackHeaderToolbarMenuApplicator.kt +27 -280
- package/android/src/main/java/com/swmansion/rnscreens/stack/header/toolbar/StackHeaderToolbarMenuController.kt +448 -0
- package/android/src/main/java/com/swmansion/rnscreens/stack/header/toolbar/StackHeaderToolbarMenuDelegate.kt +10 -0
- package/android/src/main/java/com/swmansion/rnscreens/stack/header/toolbar/StackHeaderToolbarMenuMapper.kt +28 -20
- package/android/src/main/java/com/swmansion/rnscreens/stack/header/toolbar/model/StackHeaderToolbarMenuConfig.kt +3 -55
- package/android/src/main/java/com/swmansion/rnscreens/stack/header/toolbar/model/StackHeaderToolbarMenuGroupMetadata.kt +1 -10
- package/android/src/main/java/com/swmansion/rnscreens/stack/header/toolbar/model/StackHeaderToolbarMenuItemConfig.kt +1 -3
- package/android/src/main/java/com/swmansion/rnscreens/stack/header/toolbar/model/StackHeaderToolbarMenuModel.kt +180 -0
- package/android/src/main/java/com/swmansion/rnscreens/stack/header/toolbar/update/StackHeaderToolbarMenuElementOptions.kt +57 -6
- package/android/src/main/java/com/swmansion/rnscreens/stack/header/toolbar/update/StackHeaderToolbarMenuElementRawUpdate.kt +3 -1
- package/android/src/main/java/com/swmansion/rnscreens/stack/header/toolbar/update/StackHeaderToolbarMenuElementUpdate.kt +1 -0
- package/android/src/main/java/com/swmansion/rnscreens/stack/header/toolbar/update/StackHeaderToolbarMenuIconResolver.kt +4 -3
- package/android/src/main/java/com/swmansion/rnscreens/stack/header/toolbar/update/StackHeaderToolbarMenuUpdateQueue.kt +23 -9
- package/android/src/main/java/com/swmansion/rnscreens/stack/host/StackContainer.kt +103 -3
- package/android/src/main/java/com/swmansion/rnscreens/stack/host/StackHost.kt +13 -0
- package/android/src/main/java/com/swmansion/rnscreens/stack/host/StackHostViewManager.kt +14 -0
- package/android/src/main/java/com/swmansion/rnscreens/stack/screen/StackScreen.kt +4 -0
- package/android/src/main/java/com/swmansion/rnscreens/stack/screen/StackScreenFragment.kt +20 -1
- package/android/src/main/java/com/swmansion/rnscreens/stack/screen/StackScreenFragmentDelegate.kt +12 -0
- package/android/src/main/java/com/swmansion/rnscreens/tabs/appearance/TabsAppearanceCoordinator.kt +2 -4
- package/android/src/main/java/com/swmansion/rnscreens/tabs/container/MenuHelpers.kt +5 -23
- package/android/src/main/java/com/swmansion/rnscreens/tabs/container/TabsContainer.kt +46 -25
- package/android/src/main/java/com/swmansion/rnscreens/tabs/host/TabsHost.kt +10 -0
- package/android/src/main/java/com/swmansion/rnscreens/tabs/host/TabsHostA11yCoordinator.kt +23 -2
- package/android/src/main/java/com/swmansion/rnscreens/tabs/screen/TabsScreen.kt +17 -0
- package/android/src/main/java/com/swmansion/rnscreens/tabs/screen/TabsScreenFragment.kt +3 -0
- package/android/src/main/java/com/swmansion/rnscreens/utils/DimensionUtils.kt +7 -0
- package/android/src/main/java/com/swmansion/rnscreens/utils/StyleUtils.kt +22 -0
- package/android/src/main/res/base/layout/rns_collapsing_toolbar_large_available_space.xml +8 -0
- package/android/src/main/res/base/layout/rns_collapsing_toolbar_large_entire_space.xml +8 -0
- package/android/src/main/res/base/layout/rns_collapsing_toolbar_medium_available_space.xml +8 -0
- package/android/src/main/res/base/layout/rns_collapsing_toolbar_medium_entire_space.xml +8 -0
- package/cpp/legacy/RNSScreenRemovalListener.cpp +31 -1
- package/cpp/legacy/RNSScreenRemovalListener.h +18 -3
- package/ios/RNSEnums.h +2 -0
- package/ios/conversion/RNSConversions.h +7 -108
- package/ios/legacy/RNSFullWindowOverlay.mm +1 -1
- package/ios/legacy/RNSModalScreen.mm +1 -1
- package/ios/legacy/RNSScreen.mm +8 -19
- package/ios/legacy/RNSScreenStackHeaderConfig.mm +3 -1
- package/ios/legacy/RNSScreenStackHeaderSubview.mm +1 -1
- package/ios/legacy/RNSScreenWindowTraits.mm +5 -13
- package/ios/modals/form-sheet/RNSFormSheetConfigurationApplicator.h +1 -3
- package/ios/modals/form-sheet/RNSFormSheetConfigurationApplicator.mm +11 -22
- package/ios/modals/form-sheet/RNSFormSheetContentController.h +1 -1
- package/ios/modals/form-sheet/RNSFormSheetContentController.mm +7 -18
- package/ios/modals/form-sheet/RNSFormSheetHostComponentView.mm +4 -4
- package/ios/modals/form-sheet/RNSFormSheetHostShadowStateProxy.mm +2 -2
- package/ios/modals/form-sheet/RNSFormSheetUpdateFlags.h +3 -0
- package/ios/safe-area/RNSSafeAreaViewComponentView.mm +2 -2
- package/ios/{conversion → scroll-view-marker/conversion}/RNSConversions-ScrollViewMarker.mm +2 -3
- package/ios/split/RNSSplitAppearanceApplicator.h +4 -4
- package/ios/split/RNSSplitAppearanceApplicator.mm +53 -56
- package/ios/split/RNSSplitHostComponentEventEmitter.h +1 -0
- package/ios/split/RNSSplitHostComponentEventEmitter.mm +1 -1
- package/ios/split/RNSSplitHostComponentView.h +5 -15
- package/ios/split/RNSSplitHostComponentView.mm +55 -6
- package/ios/split/RNSSplitHostController.h +25 -6
- package/ios/split/RNSSplitHostController.mm +24 -92
- package/ios/split/RNSSplitHostProviders.h +67 -0
- package/ios/split/RNSSplitScreenComponentView.h +0 -39
- package/ios/split/RNSSplitScreenComponentView.mm +27 -10
- package/ios/split/RNSSplitScreenController.h +26 -3
- package/ios/split/RNSSplitScreenController.mm +13 -30
- package/ios/split/RNSSplitScreenShadowStateProxy.h +1 -40
- package/ios/split/RNSSplitScreenShadowStateProxy.mm +1 -26
- package/ios/split/conversion/RNSConversions-SplitView.h +56 -0
- package/ios/{conversion → split/conversion}/RNSConversions-SplitView.mm +4 -1
- package/ios/stack/conversion/RNSConversions-Stack.h +32 -0
- package/ios/stack/conversion/RNSConversions-Stack.mm +55 -0
- package/ios/stack/header/RNSStackHeaderAppearanceMapper.h +26 -0
- package/ios/stack/header/RNSStackHeaderAppearanceMapper.mm +88 -0
- package/ios/stack/header/RNSStackHeaderConfigComponentView.h +10 -1
- package/ios/stack/header/RNSStackHeaderConfigComponentView.mm +67 -35
- package/ios/stack/header/RNSStackHeaderConfigDataProviding.h +6 -0
- package/ios/stack/header/RNSStackHeaderConfigShadowStateProxy.mm +1 -1
- package/ios/stack/header/RNSStackHeaderIconResolver.mm +7 -0
- package/ios/stack/header/RNSStackHeaderItemComponentView.h +3 -1
- package/ios/stack/header/RNSStackHeaderItemComponentView.mm +15 -2
- package/ios/stack/header/RNSStackHeaderItemDataProviding.h +2 -0
- package/ios/stack/header/RNSStackHeaderItemShadowStateProxy.mm +1 -1
- package/ios/stack/header/RNSStackHeaderItemSpacerComponentView.mm +2 -1
- package/ios/stack/header/RNSStackHeaderMenuMapper.mm +4 -0
- package/ios/stack/host/RNSStackNavigationBar.h +25 -0
- package/ios/stack/host/RNSStackNavigationBar.mm +80 -0
- package/ios/stack/host/RNSStackNavigationBarCoordinator.h +8 -0
- package/ios/stack/host/RNSStackNavigationBarCoordinator.mm +11 -0
- package/ios/stack/host/RNSStackNavigationController.mm +13 -5
- package/ios/stack/host/RNSStackOperation.h +0 -2
- package/ios/stack/screen/RNSStackScreenComponentView.mm +9 -2
- package/ios/stack/screen/RNSStackScreenController.mm +12 -0
- package/ios/stack/screen/RNSStackScreenHeaderCoordinator.h +8 -0
- package/ios/stack/screen/RNSStackScreenHeaderCoordinator.mm +98 -16
- package/ios/tabs/RNSTabBarAppearanceCoordinator.mm +40 -9
- package/ios/tabs/bottom-accessory/RNSTabsBottomAccessoryComponentView.h +1 -1
- package/ios/tabs/bottom-accessory/RNSTabsBottomAccessoryComponentView.mm +1 -1
- package/ios/tabs/bottom-accessory/RNSTabsBottomAccessoryContentComponentView.mm +1 -1
- package/ios/tabs/bottom-accessory/RNSTabsBottomAccessoryEventEmitter.mm +1 -1
- package/ios/tabs/bottom-accessory/RNSTabsBottomAccessoryShadowStateProxy.mm +1 -1
- package/ios/tabs/conversion/RNSConversions-Tabs.h +78 -0
- package/ios/{conversion → tabs/conversion}/RNSConversions-Tabs.mm +8 -71
- package/ios/tabs/extensions/RNSTabsHostComponentView+RNSImageLoader.h +1 -1
- package/ios/tabs/host/RNSTabsHostComponentView.h +2 -0
- package/ios/tabs/host/RNSTabsHostComponentView.mm +10 -3
- package/ios/tabs/host/RNSTabsHostEventEmitter.mm +1 -1
- package/ios/tabs/screen/RNSTabsScreenComponentView.mm +20 -5
- package/ios/utils/RNSDefines.h +3 -0
- package/lib/commonjs/components/stack/header/StackHeaderConfig.android.js +34 -19
- package/lib/commonjs/components/stack/header/StackHeaderConfig.android.js.map +1 -1
- package/lib/commonjs/components/stack/header/StackHeaderConfig.ios.js +33 -1
- package/lib/commonjs/components/stack/header/StackHeaderConfig.ios.js.map +1 -1
- package/lib/commonjs/components/stack/host/StackHost.js +9 -6
- package/lib/commonjs/components/stack/host/StackHost.js.map +1 -1
- package/lib/commonjs/components/stack/index.js.map +1 -1
- package/lib/commonjs/components/tabs/host/TabsHost.ios.js +1 -0
- package/lib/commonjs/components/tabs/host/TabsHost.ios.js.map +1 -1
- package/lib/commonjs/fabric/stack/StackHeaderConfigAndroidNativeComponent.js.map +1 -1
- package/lib/commonjs/fabric/stack/StackHeaderConfigIOSNativeComponent.js.map +1 -1
- package/lib/commonjs/fabric/stack/StackHeaderItemIOSNativeComponent.js.map +1 -1
- package/lib/commonjs/fabric/stack/StackHostNativeComponent.js.map +1 -1
- package/lib/commonjs/fabric/tabs/TabsHostIOSNativeComponent.js.map +1 -1
- package/lib/module/components/stack/header/StackHeaderConfig.android.js +35 -20
- package/lib/module/components/stack/header/StackHeaderConfig.android.js.map +1 -1
- package/lib/module/components/stack/header/StackHeaderConfig.ios.js +34 -2
- package/lib/module/components/stack/header/StackHeaderConfig.ios.js.map +1 -1
- package/lib/module/components/stack/host/StackHost.js +9 -6
- package/lib/module/components/stack/host/StackHost.js.map +1 -1
- package/lib/module/components/stack/index.js.map +1 -1
- package/lib/module/components/tabs/host/TabsHost.ios.js +1 -0
- package/lib/module/components/tabs/host/TabsHost.ios.js.map +1 -1
- package/lib/module/fabric/stack/StackHeaderConfigAndroidNativeComponent.js.map +1 -1
- package/lib/module/fabric/stack/StackHeaderConfigIOSNativeComponent.js.map +1 -1
- package/lib/module/fabric/stack/StackHeaderItemIOSNativeComponent.js.map +1 -1
- package/lib/module/fabric/stack/StackHostNativeComponent.js.map +1 -1
- package/lib/module/fabric/tabs/TabsHostIOSNativeComponent.js.map +1 -1
- package/lib/typescript/components/modals/form-sheet/FormSheet.types.d.ts +1 -1
- package/lib/typescript/components/stack/header/StackHeaderConfig.android.d.ts.map +1 -1
- package/lib/typescript/components/stack/header/StackHeaderConfig.android.types.d.ts +616 -21
- package/lib/typescript/components/stack/header/StackHeaderConfig.android.types.d.ts.map +1 -1
- package/lib/typescript/components/stack/header/StackHeaderConfig.ios.d.ts.map +1 -1
- package/lib/typescript/components/stack/header/StackHeaderConfig.ios.types.d.ts +226 -2
- package/lib/typescript/components/stack/header/StackHeaderConfig.ios.types.d.ts.map +1 -1
- package/lib/typescript/components/stack/header/StackHeaderConfig.types.d.ts +2 -2
- package/lib/typescript/components/stack/header/ios/StackHeaderItem.ios.types.d.ts +2 -0
- package/lib/typescript/components/stack/header/ios/StackHeaderItem.ios.types.d.ts.map +1 -1
- package/lib/typescript/components/stack/host/StackHost.d.ts +1 -1
- package/lib/typescript/components/stack/host/StackHost.d.ts.map +1 -1
- package/lib/typescript/components/stack/host/StackHost.types.d.ts +24 -0
- package/lib/typescript/components/stack/host/StackHost.types.d.ts.map +1 -1
- package/lib/typescript/components/stack/index.d.ts +2 -2
- package/lib/typescript/components/stack/index.d.ts.map +1 -1
- package/lib/typescript/components/tabs/host/TabsHost.ios.d.ts.map +1 -1
- package/lib/typescript/components/tabs/host/TabsHost.ios.types.d.ts +16 -0
- package/lib/typescript/components/tabs/host/TabsHost.ios.types.d.ts.map +1 -1
- package/lib/typescript/components/tabs/host/TabsHost.types.d.ts +3 -0
- package/lib/typescript/components/tabs/host/TabsHost.types.d.ts.map +1 -1
- package/lib/typescript/fabric/stack/StackHeaderConfigAndroidNativeComponent.d.ts +52 -0
- package/lib/typescript/fabric/stack/StackHeaderConfigAndroidNativeComponent.d.ts.map +1 -1
- package/lib/typescript/fabric/stack/StackHeaderConfigIOSNativeComponent.d.ts +25 -1
- package/lib/typescript/fabric/stack/StackHeaderConfigIOSNativeComponent.d.ts.map +1 -1
- package/lib/typescript/fabric/stack/StackHeaderItemIOSNativeComponent.d.ts +2 -0
- package/lib/typescript/fabric/stack/StackHeaderItemIOSNativeComponent.d.ts.map +1 -1
- package/lib/typescript/fabric/stack/StackHostNativeComponent.d.ts +3 -1
- package/lib/typescript/fabric/stack/StackHostNativeComponent.d.ts.map +1 -1
- package/lib/typescript/fabric/tabs/TabsHostIOSNativeComponent.d.ts +1 -0
- package/lib/typescript/fabric/tabs/TabsHostIOSNativeComponent.d.ts.map +1 -1
- package/package.json +8 -7
- package/react-native.config.js +3 -0
- package/src/components/modals/form-sheet/FormSheet.types.ts +1 -1
- package/src/components/stack/header/StackHeaderConfig.android.tsx +48 -23
- package/src/components/stack/header/StackHeaderConfig.android.types.ts +637 -21
- package/src/components/stack/header/StackHeaderConfig.ios.tsx +45 -1
- package/src/components/stack/header/StackHeaderConfig.ios.types.ts +238 -2
- package/src/components/stack/header/StackHeaderConfig.types.ts +2 -2
- package/src/components/stack/header/ios/StackHeaderItem.ios.types.ts +2 -0
- package/src/components/stack/host/StackHost.tsx +4 -2
- package/src/components/stack/host/StackHost.types.ts +26 -0
- package/src/components/stack/index.ts +6 -1
- package/src/components/tabs/host/TabsHost.ios.tsx +1 -0
- package/src/components/tabs/host/TabsHost.ios.types.ts +16 -0
- package/src/components/tabs/host/TabsHost.types.ts +3 -0
- package/src/fabric/stack/StackHeaderConfigAndroidNativeComponent.ts +78 -0
- package/src/fabric/stack/StackHeaderConfigIOSNativeComponent.ts +32 -0
- package/src/fabric/stack/StackHeaderItemIOSNativeComponent.ts +2 -0
- package/src/fabric/stack/StackHostNativeComponent.ts +11 -2
- package/src/fabric/tabs/TabsHostIOSNativeComponent.ts +1 -0
- package/android/src/main/java/com/swmansion/rnscreens/modals/dimmingview/DimmingView.kt +0 -83
- package/android/src/main/java/com/swmansion/rnscreens/modals/dimmingview/DimmingViewManager.kt +0 -89
- package/android/src/main/java/com/swmansion/rnscreens/modals/dimmingview/DimmingViewPointerEvents.kt +0 -18
- package/android/src/main/java/com/swmansion/rnscreens/stack/header/toolbar/StackHeaderToolbarMenuSelectionController.kt +0 -83
- package/ios/conversion/RNSConversions-Stack.h +0 -32
- package/ios/conversion/RNSConversions-Stack.mm +0 -41
- package/ios/conversion/always_false.h +0 -31
- /package/ios/{conversion → scroll-view-marker/conversion}/RNSConversions-ScrollViewMarker.h +0 -0
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
package com.swmansion.rnscreens.stack.header
|
|
2
2
|
|
|
3
|
+
import android.annotation.SuppressLint
|
|
3
4
|
import android.content.res.ColorStateList
|
|
5
|
+
import android.graphics.Color
|
|
6
|
+
import android.graphics.Typeface
|
|
4
7
|
import android.graphics.drawable.Drawable
|
|
5
|
-
import android.text.TextUtils
|
|
6
8
|
import android.util.Log
|
|
9
|
+
import android.util.TypedValue
|
|
7
10
|
import android.view.Gravity
|
|
8
11
|
import android.view.View
|
|
9
12
|
import android.view.ViewGroup
|
|
@@ -11,10 +14,9 @@ import android.view.ViewGroup.LayoutParams.MATCH_PARENT
|
|
|
11
14
|
import android.view.ViewGroup.LayoutParams.WRAP_CONTENT
|
|
12
15
|
import android.widget.FrameLayout
|
|
13
16
|
import androidx.appcompat.view.ContextThemeWrapper
|
|
14
|
-
import androidx.appcompat.widget.
|
|
17
|
+
import androidx.appcompat.widget.AppCompatImageView
|
|
15
18
|
import androidx.appcompat.widget.Toolbar
|
|
16
19
|
import androidx.core.graphics.drawable.DrawableCompat
|
|
17
|
-
import androidx.core.widget.TextViewCompat
|
|
18
20
|
import com.google.android.material.R
|
|
19
21
|
import com.google.android.material.appbar.AppBarLayout
|
|
20
22
|
import com.google.android.material.appbar.AppBarLayout.LayoutParams.SCROLL_FLAG_ENTER_ALWAYS
|
|
@@ -24,11 +26,21 @@ import com.google.android.material.appbar.AppBarLayout.LayoutParams.SCROLL_FLAG_
|
|
|
24
26
|
import com.google.android.material.appbar.AppBarLayout.LayoutParams.SCROLL_FLAG_SNAP
|
|
25
27
|
import com.google.android.material.appbar.CollapsingToolbarLayout
|
|
26
28
|
import com.google.android.material.appbar.MaterialToolbar
|
|
29
|
+
import com.google.android.material.color.MaterialColors
|
|
30
|
+
import com.google.android.material.shape.MaterialShapeDrawable
|
|
31
|
+
import com.swmansion.rnscreens.common.text.TextAppearance
|
|
32
|
+
import com.swmansion.rnscreens.common.text.TextAppearanceDefaults
|
|
27
33
|
import com.swmansion.rnscreens.ext.detachFromCurrentParent
|
|
28
34
|
import com.swmansion.rnscreens.stack.header.appbar.StackHeaderAppBarLayout
|
|
35
|
+
import com.swmansion.rnscreens.stack.header.appbar.StackHeaderContentScrimDrawable
|
|
29
36
|
import com.swmansion.rnscreens.stack.header.config.StackHeaderConfigurationProviding
|
|
37
|
+
import com.swmansion.rnscreens.stack.header.config.StackHeaderType
|
|
30
38
|
import com.swmansion.rnscreens.stack.header.subview.StackHeaderSubview
|
|
39
|
+
import com.swmansion.rnscreens.utils.dpToPx
|
|
40
|
+
import com.swmansion.rnscreens.utils.resolveColorAttr
|
|
31
41
|
import com.swmansion.rnscreens.utils.resolveDrawableAttr
|
|
42
|
+
import com.swmansion.rnscreens.utils.spToPx
|
|
43
|
+
import kotlin.math.roundToInt
|
|
32
44
|
|
|
33
45
|
/**
|
|
34
46
|
* Builds and applies the Material app bar — type, subviews, title, back button,
|
|
@@ -43,7 +55,12 @@ internal class StackHeaderApplicator(
|
|
|
43
55
|
coordinatorLayout: StackHeaderCoordinatorLayout,
|
|
44
56
|
config: StackHeaderConfigurationProviding,
|
|
45
57
|
): StackHeaderAppBarLayout {
|
|
46
|
-
val appBar =
|
|
58
|
+
val appBar =
|
|
59
|
+
StackHeaderAppBarLayout.create(
|
|
60
|
+
wrappedContext,
|
|
61
|
+
config.type,
|
|
62
|
+
config.collapsedTitleGravityMode,
|
|
63
|
+
)
|
|
47
64
|
|
|
48
65
|
if (config.transparent) {
|
|
49
66
|
coordinatorLayout.removeContentBehavior()
|
|
@@ -84,30 +101,21 @@ internal class StackHeaderApplicator(
|
|
|
84
101
|
toolbar.addView(it.view, Toolbar.LayoutParams(WRAP_CONTENT, WRAP_CONTENT, Gravity.END))
|
|
85
102
|
}
|
|
86
103
|
|
|
87
|
-
|
|
104
|
+
populateCenterSubview(appBar, toolbar, config)
|
|
88
105
|
populateBackground(appBar, config)
|
|
89
106
|
}
|
|
90
107
|
|
|
91
|
-
private fun
|
|
108
|
+
private fun populateCenterSubview(
|
|
92
109
|
appBar: StackHeaderAppBarLayout,
|
|
93
110
|
toolbar: Toolbar,
|
|
94
111
|
config: StackHeaderConfigurationProviding,
|
|
95
112
|
) {
|
|
96
|
-
val centerSubview = config.centerSubview
|
|
97
|
-
if (
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
Log.e(TAG, "[RNScreens] Center subview is supported only for small header type.")
|
|
103
|
-
}
|
|
104
|
-
} else if (appBar is StackHeaderAppBarLayout.Small) {
|
|
105
|
-
// Small header needs a managed title view because we can't use Toolbar's native
|
|
106
|
-
// title — it would be laid out to the leading side of leading subview.
|
|
107
|
-
val titleView = createManagedTitleView(toolbar)
|
|
108
|
-
appBar.managedTitleView = titleView
|
|
109
|
-
val index = if (config.isRTL) 0 else -1
|
|
110
|
-
toolbar.addView(titleView, index, Toolbar.LayoutParams(WRAP_CONTENT, WRAP_CONTENT, Gravity.START))
|
|
113
|
+
val centerSubview = config.centerSubview ?: return
|
|
114
|
+
if (appBar is StackHeaderAppBarLayout.Small) {
|
|
115
|
+
centerSubview.view.detachFromCurrentParent()
|
|
116
|
+
toolbar.addView(centerSubview.view, Toolbar.LayoutParams(WRAP_CONTENT, WRAP_CONTENT, Gravity.CENTER_HORIZONTAL))
|
|
117
|
+
} else {
|
|
118
|
+
Log.e(TAG, "[RNScreens] Center subview is supported only for small header type.")
|
|
111
119
|
}
|
|
112
120
|
}
|
|
113
121
|
|
|
@@ -144,51 +152,205 @@ internal class StackHeaderApplicator(
|
|
|
144
152
|
)
|
|
145
153
|
}
|
|
146
154
|
|
|
147
|
-
private fun createManagedTitleView(toolbar: Toolbar): AppCompatTextView =
|
|
148
|
-
AppCompatTextView(toolbar.context).apply {
|
|
149
|
-
setSingleLine()
|
|
150
|
-
ellipsize = TextUtils.TruncateAt.END
|
|
151
|
-
TextViewCompat.setTextAppearance(
|
|
152
|
-
this,
|
|
153
|
-
R.style.TextAppearance_Material3_TitleLarge,
|
|
154
|
-
)
|
|
155
|
-
layoutParams =
|
|
156
|
-
Toolbar
|
|
157
|
-
.LayoutParams(
|
|
158
|
-
WRAP_CONTENT,
|
|
159
|
-
WRAP_CONTENT,
|
|
160
|
-
Gravity.START,
|
|
161
|
-
).apply {
|
|
162
|
-
// TODO: there seems to be a problem with collapsing margins.
|
|
163
|
-
// We will expose customization either way but we should
|
|
164
|
-
// have consistent behavior and defaults.
|
|
165
|
-
marginStart = toolbar.titleMarginStart + toolbar.contentInsetStart
|
|
166
|
-
marginEnd = toolbar.titleMarginEnd
|
|
167
|
-
topMargin = toolbar.titleMarginTop
|
|
168
|
-
bottomMargin = toolbar.titleMarginBottom
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
|
|
172
155
|
// endregion
|
|
173
156
|
|
|
174
157
|
// region In-place updates
|
|
175
158
|
|
|
176
|
-
|
|
159
|
+
// ctl.setMaxLines() is listed in Material docs in the same way as other props but for some
|
|
160
|
+
// reason it's restricted.
|
|
161
|
+
@SuppressLint("RestrictedApi")
|
|
162
|
+
internal fun applyTitleAndSubtitle(
|
|
163
|
+
appBar: StackHeaderAppBarLayout,
|
|
164
|
+
config: StackHeaderConfigurationProviding,
|
|
165
|
+
isAppBarFullyCollapsed: Boolean,
|
|
166
|
+
) {
|
|
167
|
+
when (appBar) {
|
|
168
|
+
is StackHeaderAppBarLayout.Small -> {
|
|
169
|
+
appBar.toolbar.title = config.title
|
|
170
|
+
appBar.toolbar.subtitle = config.subtitle
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
is StackHeaderAppBarLayout.Collapsing -> {
|
|
174
|
+
val ctl = appBar.collapsingToolbarLayout
|
|
175
|
+
|
|
176
|
+
ctl.maxLines = config.maxLines
|
|
177
|
+
|
|
178
|
+
ctl.title = config.title
|
|
179
|
+
ctl.subtitle = config.subtitle
|
|
180
|
+
|
|
181
|
+
// setText only recomputes draw offsets within the existing bounds; the
|
|
182
|
+
// title/subtitle vertical split is recomputed only in onLayout. Force a layout
|
|
183
|
+
// so toggling the subtitle at runtime reclaims the title space.
|
|
184
|
+
ctl.requestLayout()
|
|
185
|
+
|
|
186
|
+
// Material re-asserts the collapsed offset after a height change itself, but only
|
|
187
|
+
// when maxLines > 1 (CollapsingToolbarLayout.onMeasure). With maxLines == 1 it never
|
|
188
|
+
// does, so toggling the subtitle at runtime while collapsed leaves a stale offset —
|
|
189
|
+
// setExpanded(false, false) is the closest public equivalent of Material's private
|
|
190
|
+
// maybeSetPendingActionCollapsed().
|
|
191
|
+
if (config.maxLines == 1 && isAppBarFullyCollapsed) {
|
|
192
|
+
appBar.setExpanded(false, false)
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
internal fun applyTitlePositioning(
|
|
177
199
|
appBar: StackHeaderAppBarLayout,
|
|
178
200
|
config: StackHeaderConfigurationProviding,
|
|
179
201
|
) {
|
|
180
202
|
when (appBar) {
|
|
181
203
|
is StackHeaderAppBarLayout.Small -> {
|
|
182
|
-
appBar.
|
|
183
|
-
appBar.
|
|
204
|
+
appBar.toolbar.isTitleCentered = config.titleCentered
|
|
205
|
+
appBar.toolbar.isSubtitleCentered = config.subtitleCentered
|
|
184
206
|
}
|
|
185
207
|
|
|
186
208
|
is StackHeaderAppBarLayout.Collapsing -> {
|
|
187
|
-
appBar.collapsingToolbarLayout.
|
|
209
|
+
appBar.collapsingToolbarLayout.expandedTitleGravity =
|
|
210
|
+
config.expandedTitleHorizontalGravity or config.expandedTitleVerticalGravity
|
|
211
|
+
appBar.collapsingToolbarLayout.collapsedTitleGravity =
|
|
212
|
+
config.collapsedTitleHorizontalGravity or config.collapsedTitleVerticalGravity
|
|
188
213
|
}
|
|
189
214
|
}
|
|
190
215
|
}
|
|
191
216
|
|
|
217
|
+
internal fun applyTitleAndSubtitleAppearance(
|
|
218
|
+
appBar: StackHeaderAppBarLayout,
|
|
219
|
+
config: StackHeaderConfigurationProviding,
|
|
220
|
+
) {
|
|
221
|
+
// Defaults are resolved from wrappedContext, not the widget's own context: MaterialToolbar
|
|
222
|
+
// wraps its context (materialThemeOverlay) in a ContextThemeWrapper whose theme is a
|
|
223
|
+
// one-time copy, so it never sees later setTheme calls on wrappedContext (color scheme
|
|
224
|
+
// changes).
|
|
225
|
+
when (appBar) {
|
|
226
|
+
is StackHeaderAppBarLayout.Small -> {
|
|
227
|
+
val toolbar = appBar.toolbar
|
|
228
|
+
|
|
229
|
+
// Widget.Material3Expressive.Toolbar#{title,subtitle}TextAppearance
|
|
230
|
+
// = @macro/m3_comp_app_bar_small_{title,subtitle}_font. That style sets no text
|
|
231
|
+
// colors, so both come from @macro/m3_comp_app_bar_{title,subtitle}_color.
|
|
232
|
+
applySlot(
|
|
233
|
+
view = toolbar,
|
|
234
|
+
defaults =
|
|
235
|
+
TextAppearanceDefaults.resolve(
|
|
236
|
+
wrappedContext,
|
|
237
|
+
R.attr.textAppearanceTitleLarge,
|
|
238
|
+
R.attr.colorOnSurface,
|
|
239
|
+
),
|
|
240
|
+
appearance = config.titleAppearance,
|
|
241
|
+
setColor = { toolbar.setTitleTextColor(it) },
|
|
242
|
+
setTypeface = { appBar.titleTextView.typeface = it },
|
|
243
|
+
setTextSizePx = { appBar.titleTextView.setTextSize(TypedValue.COMPLEX_UNIT_PX, it) },
|
|
244
|
+
)
|
|
245
|
+
applySlot(
|
|
246
|
+
view = toolbar,
|
|
247
|
+
defaults =
|
|
248
|
+
TextAppearanceDefaults.resolve(
|
|
249
|
+
wrappedContext,
|
|
250
|
+
R.attr.textAppearanceLabelMedium,
|
|
251
|
+
R.attr.colorOnSurfaceVariant,
|
|
252
|
+
),
|
|
253
|
+
appearance = config.subtitleAppearance,
|
|
254
|
+
setColor = { toolbar.setSubtitleTextColor(it) },
|
|
255
|
+
setTypeface = { appBar.subtitleTextView.typeface = it },
|
|
256
|
+
setTextSizePx = { appBar.subtitleTextView.setTextSize(TypedValue.COMPLEX_UNIT_PX, it) },
|
|
257
|
+
)
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
is StackHeaderAppBarLayout.Collapsing -> {
|
|
261
|
+
val ctl = appBar.collapsingToolbarLayout
|
|
262
|
+
val isLarge = appBar.type == StackHeaderType.LARGE
|
|
263
|
+
|
|
264
|
+
// Widget.Material3Expressive.CollapsingToolbar.{Large,Medium}#expandedTitleTextAppearance
|
|
265
|
+
// = @macro/m3_comp_app_bar_{large,medium}_flexible_title_font
|
|
266
|
+
val expandedTitleAttr =
|
|
267
|
+
if (isLarge) R.attr.textAppearanceDisplaySmall else R.attr.textAppearanceHeadlineMedium
|
|
268
|
+
|
|
269
|
+
// …#expandedSubtitleTextAppearance
|
|
270
|
+
// = @macro/m3_comp_app_bar_{large,medium}_flexible_subtitle_font
|
|
271
|
+
val expandedSubtitleAttr =
|
|
272
|
+
if (isLarge) R.attr.textAppearanceTitleMedium else R.attr.textAppearanceLabelLarge
|
|
273
|
+
|
|
274
|
+
// In the calls below, the collapsed appearances and all four colors come from the base
|
|
275
|
+
// Widget.Material3Expressive.CollapsingToolbar: collapsed{Title,Subtitle}TextAppearance
|
|
276
|
+
// = @macro/m3_comp_app_bar_small_{title,subtitle}_font,
|
|
277
|
+
// {collapsed,expanded}{Title,Subtitle}TextColor
|
|
278
|
+
// = @macro/m3_comp_app_bar_{title,subtitle}_color.
|
|
279
|
+
|
|
280
|
+
applySlot(
|
|
281
|
+
view = ctl,
|
|
282
|
+
defaults =
|
|
283
|
+
TextAppearanceDefaults.resolve(wrappedContext, expandedTitleAttr, R.attr.colorOnSurface),
|
|
284
|
+
appearance = config.expandedTitleAppearance,
|
|
285
|
+
setColor = { ctl.setExpandedTitleTextColor(ColorStateList.valueOf(it)) },
|
|
286
|
+
setTypeface = { ctl.setExpandedTitleTypeface(it) },
|
|
287
|
+
setTextSizePx = { ctl.expandedTitleTextSize = it },
|
|
288
|
+
)
|
|
289
|
+
applySlot(
|
|
290
|
+
view = ctl,
|
|
291
|
+
defaults =
|
|
292
|
+
TextAppearanceDefaults.resolve(wrappedContext, R.attr.textAppearanceTitleLarge, R.attr.colorOnSurface),
|
|
293
|
+
appearance = config.collapsedTitleAppearance,
|
|
294
|
+
setColor = { ctl.setCollapsedTitleTextColor(it) },
|
|
295
|
+
setTypeface = { ctl.setCollapsedTitleTypeface(it) },
|
|
296
|
+
setTextSizePx = { ctl.collapsedTitleTextSize = it },
|
|
297
|
+
)
|
|
298
|
+
applySlot(
|
|
299
|
+
view = ctl,
|
|
300
|
+
defaults =
|
|
301
|
+
TextAppearanceDefaults.resolve(wrappedContext, expandedSubtitleAttr, R.attr.colorOnSurfaceVariant),
|
|
302
|
+
appearance = config.expandedSubtitleAppearance,
|
|
303
|
+
setColor = { ctl.setExpandedSubtitleTextColor(ColorStateList.valueOf(it)) },
|
|
304
|
+
setTypeface = { ctl.setExpandedSubtitleTypeface(it) },
|
|
305
|
+
setTextSizePx = { ctl.expandedSubtitleTextSize = it },
|
|
306
|
+
)
|
|
307
|
+
applySlot(
|
|
308
|
+
view = ctl,
|
|
309
|
+
defaults =
|
|
310
|
+
TextAppearanceDefaults.resolve(wrappedContext, R.attr.textAppearanceLabelMedium, R.attr.colorOnSurfaceVariant),
|
|
311
|
+
appearance = config.collapsedSubtitleAppearance,
|
|
312
|
+
setColor = { ctl.setCollapsedSubtitleTextColor(it) },
|
|
313
|
+
setTypeface = { ctl.setCollapsedSubtitleTypeface(it) },
|
|
314
|
+
setTextSizePx = { ctl.collapsedSubtitleTextSize = it },
|
|
315
|
+
)
|
|
316
|
+
|
|
317
|
+
// Layout is necessary e.g. after changing subtitle text size.
|
|
318
|
+
ctl.requestLayout()
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
/**
|
|
324
|
+
* Applies one title/subtitle slot as absolute values: each property is the prop value when
|
|
325
|
+
* set, the Material default otherwise.
|
|
326
|
+
*/
|
|
327
|
+
private fun applySlot(
|
|
328
|
+
view: View,
|
|
329
|
+
defaults: TextAppearanceDefaults,
|
|
330
|
+
appearance: TextAppearance,
|
|
331
|
+
setColor: (Int) -> Unit,
|
|
332
|
+
setTypeface: (Typeface) -> Unit,
|
|
333
|
+
setTextSizePx: (Float) -> Unit,
|
|
334
|
+
) {
|
|
335
|
+
setColor(appearance.color ?: defaults.color)
|
|
336
|
+
setTypeface(appearance.resolveTypeface(defaults.typeface))
|
|
337
|
+
setTextSizePx(appearance.fontSize?.let { view.spToPx(it) } ?: defaults.textSizePx)
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
internal fun applyContentInsets(
|
|
341
|
+
appBar: StackHeaderAppBarLayout,
|
|
342
|
+
config: StackHeaderConfigurationProviding,
|
|
343
|
+
) {
|
|
344
|
+
val toolbar = appBar.toolbar
|
|
345
|
+
|
|
346
|
+
toolbar.setContentInsetsRelative(
|
|
347
|
+
config.contentInsetStart?.let { toolbar.dpToPx(it).roundToInt() } ?: appBar.defaultContentInsetStart,
|
|
348
|
+
config.contentInsetEnd?.let { toolbar.dpToPx(it).roundToInt() } ?: appBar.defaultContentInsetEnd,
|
|
349
|
+
)
|
|
350
|
+
|
|
351
|
+
toolbar.requestLayout()
|
|
352
|
+
}
|
|
353
|
+
|
|
192
354
|
internal fun applyBackButton(
|
|
193
355
|
toolbar: MaterialToolbar,
|
|
194
356
|
config: StackHeaderConfigurationProviding,
|
|
@@ -208,9 +370,15 @@ internal class StackHeaderApplicator(
|
|
|
208
370
|
val baseDrawable =
|
|
209
371
|
config.backButtonIcon
|
|
210
372
|
?.let { getResizedDrawable(toolbar, it) }
|
|
211
|
-
?: resolveDefaultBackButtonIcon()
|
|
373
|
+
?: resolveDefaultBackButtonIcon(toolbar)
|
|
374
|
+
|
|
375
|
+
val tintList =
|
|
376
|
+
buildTintList(
|
|
377
|
+
config.backButtonTintColorNormal,
|
|
378
|
+
config.backButtonTintColorPressed,
|
|
379
|
+
config.backButtonTintColorFocused,
|
|
380
|
+
)
|
|
212
381
|
|
|
213
|
-
val tintList = resolveBackButtonTintList(config)
|
|
214
382
|
toolbar.navigationIcon =
|
|
215
383
|
if (tintList != null && baseDrawable != null) {
|
|
216
384
|
DrawableCompat.wrap(baseDrawable.mutate()).also {
|
|
@@ -223,6 +391,32 @@ internal class StackHeaderApplicator(
|
|
|
223
391
|
toolbar.setNavigationOnClickListener { onNavigationIconClick() }
|
|
224
392
|
}
|
|
225
393
|
|
|
394
|
+
internal fun applyOverflowIcon(
|
|
395
|
+
toolbar: MaterialToolbar,
|
|
396
|
+
config: StackHeaderConfigurationProviding,
|
|
397
|
+
) {
|
|
398
|
+
val baseDrawable =
|
|
399
|
+
config.overflowIcon
|
|
400
|
+
?.let { getResizedDrawable(toolbar, it) }
|
|
401
|
+
?: resolveDefaultOverflowIcon(toolbar)
|
|
402
|
+
|
|
403
|
+
val tintList =
|
|
404
|
+
buildTintList(
|
|
405
|
+
config.overflowIconTintColorNormal,
|
|
406
|
+
config.overflowIconTintColorPressed,
|
|
407
|
+
config.overflowIconTintColorFocused,
|
|
408
|
+
)
|
|
409
|
+
|
|
410
|
+
toolbar.overflowIcon =
|
|
411
|
+
if (tintList != null && baseDrawable != null) {
|
|
412
|
+
DrawableCompat.wrap(baseDrawable.mutate()).also {
|
|
413
|
+
DrawableCompat.setTintList(it, tintList)
|
|
414
|
+
}
|
|
415
|
+
} else {
|
|
416
|
+
baseDrawable
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
|
|
226
420
|
internal fun applyScrollFlags(
|
|
227
421
|
appBar: StackHeaderAppBarLayout,
|
|
228
422
|
config: StackHeaderConfigurationProviding,
|
|
@@ -270,6 +464,109 @@ internal class StackHeaderApplicator(
|
|
|
270
464
|
appBar.requestLayout()
|
|
271
465
|
}
|
|
272
466
|
|
|
467
|
+
internal fun applyBackgroundColors(
|
|
468
|
+
appBar: StackHeaderAppBarLayout,
|
|
469
|
+
config: StackHeaderConfigurationProviding,
|
|
470
|
+
) {
|
|
471
|
+
// Widget.Material3Expressive.AppBarLayout (an empty alias of Widget.Material3.AppBarLayout)
|
|
472
|
+
// #android:background = @macro/m3_comp_app_bar_container_color.
|
|
473
|
+
val backgroundColor =
|
|
474
|
+
config.backgroundColor ?: resolveColorAttr(appBar.context, R.attr.colorSurface)
|
|
475
|
+
|
|
476
|
+
// Both header kinds default to the same token, from different places:
|
|
477
|
+
// small — ...AppBarLayout#liftOnScrollColor
|
|
478
|
+
// = @macro/m3_comp_app_bar_on_scroll_container_color;
|
|
479
|
+
// collapsing — the M3 CollapsingToolbar styles set no contentScrim, so CTL installs its
|
|
480
|
+
// own default for titleCollapseMode=fade (getDefaultContentScrimColorForTitleCollapseFadeMode).
|
|
481
|
+
val scrolledBackgroundColor =
|
|
482
|
+
config.scrolledBackgroundColor
|
|
483
|
+
?: resolveColorAttr(appBar.context, R.attr.colorSurfaceContainer)
|
|
484
|
+
|
|
485
|
+
val background =
|
|
486
|
+
MaterialShapeDrawable().apply {
|
|
487
|
+
fillColor = ColorStateList.valueOf(backgroundColor)
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
when (appBar) {
|
|
491
|
+
is StackHeaderAppBarLayout.Small -> {
|
|
492
|
+
appBar.background = background
|
|
493
|
+
appBar.setLiftOnScrollColor(ColorStateList.valueOf(scrolledBackgroundColor))
|
|
494
|
+
|
|
495
|
+
// The lift animation runs only on lifted-state changes; jump to the end
|
|
496
|
+
// state when colors change while already lifted. The end state is the
|
|
497
|
+
// scrolled color composited over the background (see Material's
|
|
498
|
+
// initializeLiftOnScrollWithColor), not the raw scrolled color — they
|
|
499
|
+
// differ when the scrolled color is not fully opaque.
|
|
500
|
+
if (appBar.isLifted) {
|
|
501
|
+
background.fillColor =
|
|
502
|
+
ColorStateList.valueOf(
|
|
503
|
+
MaterialColors.layer(backgroundColor, scrolledBackgroundColor),
|
|
504
|
+
)
|
|
505
|
+
}
|
|
506
|
+
}
|
|
507
|
+
|
|
508
|
+
is StackHeaderAppBarLayout.Collapsing -> {
|
|
509
|
+
// Fade collapse mode disables liftOnScroll, but the lift animation only checks the
|
|
510
|
+
// lift color. We set it to null so the fill stays at backgroundColor under the
|
|
511
|
+
// transparent/translucent content scrim.
|
|
512
|
+
appBar.setLiftOnScrollColor(null)
|
|
513
|
+
appBar.background = background
|
|
514
|
+
appBar.collapsingToolbarLayout.contentScrim =
|
|
515
|
+
StackHeaderContentScrimDrawable(scrolledBackgroundColor)
|
|
516
|
+
}
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
applyStatusBarScrim(appBar, config, backgroundColor, scrolledBackgroundColor)
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
private fun applyStatusBarScrim(
|
|
523
|
+
appBar: StackHeaderAppBarLayout,
|
|
524
|
+
config: StackHeaderConfigurationProviding,
|
|
525
|
+
backgroundColor: Int,
|
|
526
|
+
scrolledBackgroundColor: Int,
|
|
527
|
+
) {
|
|
528
|
+
when (appBar) {
|
|
529
|
+
is StackHeaderAppBarLayout.Small -> {
|
|
530
|
+
val scrimColor = resolveStatusBarScrimColor(config, drivingColor = backgroundColor)
|
|
531
|
+
val autoFollow = scrimColor != null && config.statusBarScrimColor == null
|
|
532
|
+
appBar.setStatusBarScrimSyncEnabled(autoFollow)
|
|
533
|
+
appBar.statusBarForeground?.setTint(
|
|
534
|
+
when {
|
|
535
|
+
scrimColor == null -> Color.TRANSPARENT
|
|
536
|
+
// Same lifted jump as the background fill in applyBackgroundColors.
|
|
537
|
+
autoFollow && appBar.isLifted ->
|
|
538
|
+
MaterialColors.layer(backgroundColor, scrolledBackgroundColor)
|
|
539
|
+
else -> scrimColor
|
|
540
|
+
},
|
|
541
|
+
)
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
is StackHeaderAppBarLayout.Collapsing -> {
|
|
545
|
+
// Defaulting to the content scrim color masks toolbar content passing
|
|
546
|
+
// through the status-bar area (scroll-only flags) and is a visual
|
|
547
|
+
// no-op in the opaque exitUntilCollapsed case. An invisible scrim is
|
|
548
|
+
// normalized to null so the content scrim exclusion can key on scrim
|
|
549
|
+
// presence alone.
|
|
550
|
+
val scrimColor =
|
|
551
|
+
resolveStatusBarScrimColor(config, drivingColor = scrolledBackgroundColor)
|
|
552
|
+
?.takeIf { Color.alpha(it) > 0 }
|
|
553
|
+
if (scrimColor != null) {
|
|
554
|
+
appBar.collapsingToolbarLayout.setStatusBarScrimColor(scrimColor)
|
|
555
|
+
} else {
|
|
556
|
+
appBar.collapsingToolbarLayout.statusBarScrim = null
|
|
557
|
+
}
|
|
558
|
+
appBar.updateContentScrimExclusion()
|
|
559
|
+
}
|
|
560
|
+
}
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
// The default scrim exists only for an opaque driving color — a translucent
|
|
564
|
+
// scrim would double-composite over the layer it covers.
|
|
565
|
+
private fun resolveStatusBarScrimColor(
|
|
566
|
+
config: StackHeaderConfigurationProviding,
|
|
567
|
+
drivingColor: Int,
|
|
568
|
+
): Int? = config.statusBarScrimColor ?: drivingColor.takeIf { Color.alpha(it) == 0xFF }
|
|
569
|
+
|
|
273
570
|
// endregion
|
|
274
571
|
|
|
275
572
|
// region Helpers
|
|
@@ -298,7 +595,21 @@ internal class StackHeaderApplicator(
|
|
|
298
595
|
}
|
|
299
596
|
}
|
|
300
597
|
|
|
301
|
-
|
|
598
|
+
// Default icon drawables must load through the toolbar's snapshot context, not
|
|
599
|
+
// wrappedContext: on Android 14+ the framework's themed resource cache returns stale
|
|
600
|
+
// entries for a Theme mutated in place by setTheme (ThemeKey dedup + shallow clone),
|
|
601
|
+
// freezing the icon tint after a color scheme change. The toolbar wrapper's theme is
|
|
602
|
+
// created fresh on every rebuild, so its cache entries always match the current palette.
|
|
603
|
+
// Plain attribute resolution (e.g. text appearance defaults) doesn't hit that cache and
|
|
604
|
+
// stays on the live wrappedContext.
|
|
605
|
+
private fun resolveDefaultBackButtonIcon(toolbar: MaterialToolbar): Drawable? =
|
|
606
|
+
resolveDrawableAttr(toolbar.context, androidx.appcompat.R.attr.homeAsUpIndicator)
|
|
607
|
+
|
|
608
|
+
// Mirrors how the toolbar's own overflow button obtains its icon: an AppCompatImageView built
|
|
609
|
+
// with actionOverflowButtonStyle resolves the theme's srcCompat and applies AppCompat's
|
|
610
|
+
// colorControlNormal auto-tint.
|
|
611
|
+
private fun resolveDefaultOverflowIcon(toolbar: MaterialToolbar): Drawable? =
|
|
612
|
+
AppCompatImageView(toolbar.context, null, androidx.appcompat.R.attr.actionOverflowButtonStyle).drawable
|
|
302
613
|
|
|
303
614
|
private fun maybeApplyRTLCollapsingToolbarLayoutWorkaround(
|
|
304
615
|
coordinatorLayout: StackHeaderCoordinatorLayout,
|
|
@@ -340,11 +651,11 @@ internal class StackHeaderApplicator(
|
|
|
340
651
|
}
|
|
341
652
|
}
|
|
342
653
|
|
|
343
|
-
private fun
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
654
|
+
private fun buildTintList(
|
|
655
|
+
normal: Int?,
|
|
656
|
+
pressed: Int?,
|
|
657
|
+
focused: Int?,
|
|
658
|
+
): ColorStateList? {
|
|
348
659
|
if (normal == null && pressed == null && focused == null) return null
|
|
349
660
|
|
|
350
661
|
val states = mutableListOf<IntArray>()
|
package/android/src/main/java/com/swmansion/rnscreens/stack/header/StackHeaderBackPressHandler.kt
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
package com.swmansion.rnscreens.stack.header
|
|
2
|
+
|
|
3
|
+
import com.swmansion.rnscreens.stack.screen.StackScreen
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Receives presses of the native header back button. Implemented by the object
|
|
7
|
+
* managing the navigation state of the stack the pressed header belongs to.
|
|
8
|
+
*/
|
|
9
|
+
internal fun interface StackHeaderBackPressHandler {
|
|
10
|
+
fun handleHeaderBackButtonPress(pressedScreen: StackScreen)
|
|
11
|
+
}
|