From ed07ac3407601ff8bed1e535b82f20e7d2dbb8a4 Mon Sep 17 00:00:00 2001 From: Marek Piechut Date: Thu, 7 May 2020 09:22:42 +0200 Subject: [PATCH 1/3] feat: Animate segment selection on Android (#77) --- js/SegmentedControl.js | 50 +++++++++++++++++++++++++++++++++++++-- js/SegmentedControlTab.js | 12 +--------- 2 files changed, 49 insertions(+), 13 deletions(-) diff --git a/js/SegmentedControl.js b/js/SegmentedControl.js index bcfa5d3d..f48b84b3 100644 --- a/js/SegmentedControl.js +++ b/js/SegmentedControl.js @@ -5,7 +5,7 @@ 'use strict'; import * as React from 'react'; -import {StyleSheet, View} from 'react-native'; +import {Animated, Easing, StyleSheet, View} from 'react-native'; import {SegmentedControlTab} from './SegmentedControlTab'; import type {SegmentedControlProps} from './types'; @@ -27,6 +27,9 @@ const SegmentedControl = ({ backgroundColor, fontSize, }: SegmentedControlProps) => { + const [segmentWidth, setSegmentWidth] = React.useState(0); + const animation = React.useRef(new Animated.Value(0)).current; + const handleChange = (index: number) => { // mocks iOS's nativeEvent const event: any = { @@ -38,6 +41,18 @@ const SegmentedControl = ({ onChange && onChange(event); onValueChange && onValueChange(values[index]); }; + + React.useEffect(() => { + if (animation && segmentWidth) { + Animated.timing(animation, { + toValue: segmentWidth * (selectedIndex || 0), + duration: 300, + easing: Easing.out(Easing.quad), + useNativeDriver: true, + }).start(); + } + }, [animation, segmentWidth, selectedIndex]); + return ( + ]} + onLayout={({ + nativeEvent: { + layout: {width}, + }, + }) => { + const newSegmentWidth = values.length ? width / values.length : 0; + if (newSegmentWidth !== segmentWidth) { + animation.setValue(newSegmentWidth * (selectedIndex || 0)); + setSegmentWidth(newSegmentWidth); + } + }}> + {selectedIndex != null && segmentWidth ? ( + + ) : null} {values && values.map((value, index) => { return ( @@ -70,6 +108,8 @@ const SegmentedControl = ({ const styles = StyleSheet.create({ default: { + overflow: 'hidden', + position: 'relative', flexDirection: 'row', justifyContent: 'space-evenly', alignContent: 'center', @@ -80,6 +120,12 @@ const styles = StyleSheet.create({ disabled: { opacity: 0.4, }, + slider: { + position: 'absolute', + left: 0, + height: '100%', + borderRadius: 5, + }, }); export default SegmentedControl; diff --git a/js/SegmentedControlTab.js b/js/SegmentedControlTab.js index 3c878d0f..aa770bf8 100644 --- a/js/SegmentedControlTab.js +++ b/js/SegmentedControlTab.js @@ -42,22 +42,12 @@ export const SegmentedControlTab = ({ }; const color = getColor(); - const getBackgroundColor = () => { - if (selected && tintColor) { - return tintColor; - } - return 'white'; - }; return ( - + Date: Thu, 7 May 2020 19:28:53 +0900 Subject: [PATCH 2/3] chore: apply style to match iOS 13 Segmented Control (#78) --- js/SegmentedControl.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/js/SegmentedControl.js b/js/SegmentedControl.js index f48b84b3..77fbe61e 100644 --- a/js/SegmentedControl.js +++ b/js/SegmentedControl.js @@ -122,9 +122,11 @@ const styles = StyleSheet.create({ }, slider: { position: 'absolute', - left: 0, - height: '100%', borderRadius: 5, + top: 1, + bottom: 1, + right: 1, + left: 1, }, }); From d9c082282c901673df278639878223c43d4e8926 Mon Sep 17 00:00:00 2001 From: Jesse Katsumata Date: Thu, 7 May 2020 19:30:10 +0900 Subject: [PATCH 3/3] 1.6.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index b0b28513..d3c0ded7 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@react-native-community/segmented-control", - "version": "1.5.0", + "version": "1.6.0", "description": "React Native SegmentedControlIOS library", "main": "js/index.js", "types": "index.d.ts",