Skip to content

Commit

Permalink
Implement bottomTabs.hideOnScroll (#6283)
Browse files Browse the repository at this point in the history
This option is currently available only on Android and can be used to allow the user to hide the BottomTabs on scroll.
  • Loading branch information
guyca authored Jun 11, 2020
1 parent 5c6ccd1 commit 9544f41
Show file tree
Hide file tree
Showing 8 changed files with 58 additions and 37 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ public static BottomTabsOptions parse(JSONObject json) {
options.backgroundColor = ColorParser.parse(json, "backgroundColor");
options.currentTabId = TextParser.parse(json, "currentTabId");
options.currentTabIndex = NumberParser.parse(json,"currentTabIndex");
options.hideOnScroll = BoolParser.parse(json, "hideOnScroll");
options.visible = BoolParser.parse(json,"visible");
options.drawBehind = BoolParser.parse(json, "drawBehind");
options.preferLargeIcons = BoolParser.parse(json, "preferLargeIcons");
Expand All @@ -41,6 +42,7 @@ public static BottomTabsOptions parse(JSONObject json) {
}

public Colour backgroundColor = new NullColor();
public Bool hideOnScroll = new NullBool();
public Bool visible = new NullBool();
public Bool drawBehind = new NullBool();
public Bool animate = new NullBool();
Expand All @@ -55,6 +57,7 @@ public static BottomTabsOptions parse(JSONObject json) {
void mergeWith(final BottomTabsOptions other) {
if (other.currentTabId.hasValue()) currentTabId = other.currentTabId;
if (other.currentTabIndex.hasValue()) currentTabIndex = other.currentTabIndex;
if (other.hideOnScroll.hasValue()) hideOnScroll = other.hideOnScroll;
if (other.visible.hasValue()) visible = other.visible;
if (other.drawBehind.hasValue()) drawBehind = other.drawBehind;
if (other.animate.hasValue()) animate = other.animate;
Expand All @@ -69,6 +72,7 @@ void mergeWith(final BottomTabsOptions other) {
void mergeWithDefault(final BottomTabsOptions defaultOptions) {
if (!currentTabId.hasValue()) currentTabId = defaultOptions.currentTabId;
if (!currentTabIndex.hasValue()) currentTabIndex = defaultOptions.currentTabIndex;
if (!hideOnScroll.hasValue()) hideOnScroll = defaultOptions.hideOnScroll;
if (!visible.hasValue()) visible = defaultOptions.visible;
if (!drawBehind.hasValue()) drawBehind = defaultOptions.drawBehind;
if (!animate.hasValue()) animate = defaultOptions.animate;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,9 @@ private void mergeBottomTabsOptions(Options options, ViewController view) {
int tabIndex = bottomTabFinder.findByControllerId(bottomTabsOptions.currentTabId.get());
if (tabIndex >= 0) tabSelector.selectTab(tabIndex);
}
if (bottomTabsOptions.hideOnScroll.hasValue()) {
bottomTabs.setBehaviorTranslationEnabled(bottomTabsOptions.hideOnScroll.get());
}
if (view.isViewShown()) {
if (bottomTabsOptions.visible.isTrue()) {
if (bottomTabsOptions.animate.isTrueOrUndefined()) {
Expand Down Expand Up @@ -154,6 +157,7 @@ private void applyBottomTabsOptions(Options options) {
if (bottomTabsOptions.elevation.hasValue()) {
bottomTabs.setUseElevation(true, bottomTabsOptions.elevation.get().floatValue());
}
bottomTabs.setBehaviorTranslationEnabled(bottomTabsOptions.hideOnScroll.get(false));
}

@NotNull
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ public class BottomTabs extends AHBottomNavigation {
public BottomTabs(Context context) {
super(context);
setId(R.id.bottomTabs);
setBehaviorTranslationEnabled(false);
}

public void disableItemsCreation() {
Expand Down
1 change: 1 addition & 0 deletions playground/src/screens/Screens.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ module.exports = {
SetRoot: 'SetRoot',
Overlay: 'Overlay',
OverlayAlert: 'OverlayAlert',
ScrollViewScreen: 'ScrollViewScreen',
ScrollViewOverlay: 'ScrollViewOverlay',
Lifecycle: 'Lifecycle',
BackHandler: 'BackHandler',
Expand Down
70 changes: 37 additions & 33 deletions playground/src/screens/ScrollViewScreen.js
Original file line number Diff line number Diff line change
@@ -1,55 +1,50 @@
const React = require('react');
const { Component } = require('react');

const { StyleSheet, ScrollView, View, Button, Platform } = require('react-native');

const { Navigation } = require('react-native-navigation');
const testIDs = require('../testIDs');

const FAB = 'fab';
const { StyleSheet, ScrollView, View } = require('react-native');
const Button = require('../components/Button');
const Navigation = require('../services/Navigation');
const Colors = require('../commons/Colors');

class ScrollViewScreen extends Component {
static options() {
return {
topBar: {
title: {
text: 'Collapse',
color: 'black',
fontSize: 16
text: 'Hide on scroll'
},
drawBehind: true,
visible: true,
testID: testIDs.TOP_BAR_ELEMENT
},
bottomTabs: {
hideOnScroll: true
},
fab: {
id: FAB,
backgroundColor: 'blue',
clickColor: 'blue',
rippleColor: 'aquamarine',
id: 'FAB',
icon: require('../../img/whatshot.png'),
iconColor: 'white',
backgroundColor: Colors.primary,
clickColor: Colors.primary,
rippleColor: Colors.accent,
hideOnScroll: true
}
};
}

constructor(props) {
super(props);
this.state = {
topBarHideOnScroll: false
};
this.onClickToggleTopBarHideOnScroll = this.onClickToggleTopBarHideOnScroll.bind(this);
this.onClickPop = this.onClickPop.bind(this);
}
state = {
topBarHideOnScroll: false,
bottomTabsHideOnScroll: false
};

render() {
return (
<View>
<ScrollView testID={testIDs.SCROLLVIEW_ELEMENT} contentContainerStyle={styles.contentContainer}>
<View>
<Button title='Toggle Top Bar Hide On Scroll' testID={testIDs.TOGGLE_TOP_BAR_HIDE_ON_SCROLL} onPress={this.onClickToggleTopBarHideOnScroll} />
<Button title='Pop screen' testID={testIDs.POP_BUTTON} onPress={this.onClickPop} />
</View>
</ScrollView>
</View>
<ScrollView
contentContainerStyle={styles.contentContainer}
nestedScrollEnabled={this.state.bottomTabsHideOnScroll}>
<View>
<Button label='Toggle Top Bar Hide On Scroll' onPress={this.onClickToggleTopBarHideOnScroll} />
<Button label='Pop screen' onPress={this.onClickPop} />
<Button label='Toggle hide BottomTabs on scroll' onPress={this.hideBottomTabsOnScroll} />
</View>
</ScrollView>
);
}

Expand All @@ -59,6 +54,16 @@ class ScrollViewScreen extends Component {
});
}

hideBottomTabsOnScroll = () => {
const hideOnScroll = !this.state.bottomTabsHideOnScroll;
this.setState({ bottomTabsHideOnScroll: hideOnScroll });
Navigation.mergeOptions(this, {
bottomTabs: {
hideOnScroll: hideOnScroll
}
});
}

onClickPop() {
Navigation.pop(this.props.componentId);
}
Expand All @@ -80,7 +85,6 @@ module.exports = ScrollViewScreen;
const styles = StyleSheet.create({
contentContainer: {
alignItems: 'center',
backgroundColor: 'green',
paddingTop: 200,
height: 1200
}
Expand Down
3 changes: 3 additions & 0 deletions playground/src/screens/SecondBottomTabScreen.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ class SecondBottomTabScreen extends React.Component {
<Root componentId={this.props.componentId}>
<Button label='Push' onPress={this.push} />
<Button label='Push BottomTabs' testID={PUSH_BTN} onPress={this.pushBottomTabs} />
<Button label='Push ScrollView' onPress={this.pushScrollView} />
<Button label='SideMenu inside BottomTabs' testID={SIDE_MENU_INSIDE_BOTTOM_TABS_BTN} onPress={this.sideMenuInsideBottomTabs} />
<Button label='Hide Tabs on Push' testID={HIDE_TABS_PUSH_BTN} onPress={this.hideTabsOnPush} />
</Root>
Expand Down Expand Up @@ -77,6 +78,8 @@ class SecondBottomTabScreen extends React.Component {
}
});

pushScrollView = () => Navigation.push(this, Screens.ScrollViewScreen);

sideMenuInsideBottomTabs = () => {
Navigation.showModal({
bottomTabs: {
Expand Down
4 changes: 1 addition & 3 deletions playground/src/screens/index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
const React = require('react');
const { Navigation } = require('react-native-navigation');
const ScrollViewScreen = require('./ScrollViewScreen');
const CustomDialogWithScroll = require('./complexlayouts/CustomDialogWithScroll');
const TopTabScreen = require('./TopTabScreen');
const TopTabOptionsScreen = require('./TopTabOptionsScreen');
Expand Down Expand Up @@ -34,6 +33,7 @@ function registerScreens() {
Navigation.registerComponent(Screens.LifecycleButton, () => require('./LifecycleButton'));
Navigation.registerComponent(Screens.ReactTitleView, () => require('./CustomTopBar'));
Navigation.registerComponent(Screens.RoundButton, () => require('./RoundedButton'));
Navigation.registerComponent(Screens.ScrollViewScreen, () => require('./ScrollViewScreen'));
Navigation.registerComponent(Screens.ScrollViewOverlay, () => require('./ScrollViewOverlay'));
Navigation.registerComponent(Screens.SecondBottomTabsScreen, () => require('./SecondBottomTabScreen'));
Navigation.registerComponent(Screens.Search, () => require('./SearchScreen'));
Expand All @@ -55,8 +55,6 @@ function registerScreens() {
</ContextProvider>,
() => ContextScreen);

Navigation.registerComponent(`navigation.playground.ScrollViewScreen`, () => ScrollViewScreen);

Navigation.registerComponent('navigation.playground.CustomDialog', () => CustomDialog);
Navigation.registerComponent('navigation.playground.CustomDialogWithScroll', () => CustomDialogWithScroll);
Navigation.registerComponent('navigation.playground.TopTabScreen', () => TopTabScreen);
Expand Down
8 changes: 8 additions & 0 deletions website/api/options-bottomTabs.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,14 @@ Select a tab by the id (componentId) of a child contained in it. See [Selecting
| ------- | -------- | -------- |
| boolean | No | iOS |

## `hideOnScroll`
Hides the BottomTabs on scroll to increase the amount of content visible to the user.
The options requires that the scrollable view will be the root view of the screen and that it specifies `nestedScrollEnabled: true`.

| Type | Required | Platform |
| ------- | -------- | -------- |
| boolean | No | Android |

## `preferLargeIcons`

| Type | Required | Platform |
Expand Down

0 comments on commit 9544f41

Please sign in to comment.