How can I do two overlapped rounded buttons on react native?

enter image description here

How can I create this kind of buttons on react native? I know that I can create buttons with rounded corners but using the border radius, but what about the overlap?

Upvotes: 0

Views: 2517

Answers (3)

anonym
anonym

Reputation: 279

Based on the other answers, you can also get the selection login here: https://snack.expo.io/@xavier96/rounded-ovelaying-buttons

export default class App extends React.Component {

  state = {
    btn1Selected: true,
    btn2Selected: false,
  }

  render() {
    const { btn1Selected, btn2Selected } = this.state;
    return (
      <View style={styles.container}>
          <TouchableOpacity
            style={[styles.round, styles.first, styles.inferiorIndex, btn1Selected && styles.superiorIndex, btn2Selected && styles.borderRightRadius]}
            onPress={() => this.setState({btn1Selected: true, btn2Selected: false})}
           >
             <Text>BTN1</Text>
           </TouchableOpacity>
           <TouchableOpacity 
             style={[styles.round, styles.second, styles.inferiorIndex, btn2Selected && styles.superiorIndex]}
             onPress={() => this.setState({btn1Selected: false, btn2Selected: true})}
           >
             <Text>BTN2</Text>
           </TouchableOpacity>
      </View>
   );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    flexDirection: 'row',
    alignItems: 'center',
    justifyContent: 'center',
    paddingTop: Constants.statusBarHeight,
    backgroundColor: '#ecf0f1',
  },
  first: {
    backgroundColor: 'grey',
    zIndex: 1
  },

  second: {
    backgroundColor: 'grey',
    position: 'relative',
    borderTopLeftRadius: 0,
    borderBottomLeftRadius: 0,
    left: -22,
    zIndex: 0
  },

  round: {
    justifyContent: 'center',
    alignItems: 'center',
    width: 100,
    height: 50,
    borderRadius: 50
  },

  superiorIndex: {
    zIndex: 2,
    borderTopLeftRadius: 50,
    borderBottomLeftRadius: 50,
    backgroundColor: 'red'
  },

  inferiorIndex: {
    zIndex: 1,
  },

  borderRightRadius: {
    borderTopRightRadius: 0,
    borderBottomRightRadius: 0,
  }
});

Upvotes: 0

bennygenel
bennygenel

Reputation: 24660

Another approach to @Lukasz's answer would be using relative positioning. Since absolute positioning is hard to set for all different screen sizes I prefer using relative positioning with negative left/right value. This let me set my container with flex like the rest of the app.

Sample (Modfied from the @Lukasz's snack) https://snack.expo.io/@bennygenel/cm91bm

export default class App extends React.Component {
  render() {
    return (
      <View style={styles.container}>
        <TouchableOpacity style={[styles.round, styles.red]}>
          <Text>BTN1</Text>
        </TouchableOpacity>
        <TouchableOpacity style={[styles.round, styles.green]}>
          <Text>BTN1</Text>
        </TouchableOpacity>
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    flexDirection: 'row',
    alignItems: 'center',
    justifyContent: 'center',
    paddingTop: Constants.statusBarHeight,
    backgroundColor: '#ecf0f1',
  },
  red: {
    backgroundColor: 'red',
    zIndex: 2
  },

  green: {
    backgroundColor: 'green',
    position: 'relative',
    borderTopLeftRadius: 0,
    borderBottomLeftRadius: 0,
    left: -22
  },

  round: {
    justifyContent: 'center',
    alignItems: 'center',
    width: 100,
    height: 50,
    borderRadius: 50
  }
});

Upvotes: 0

Lukasz
Lukasz

Reputation: 1842

You should use absolute positioning. Have a look at the snap I prepared for you:

https://snack.expo.io/r1tw8M6iQ

Be careful, the absolute positioning in RNT isn't the same it is in CSS. Have a look at the documentation here: https://facebook.github.io/react-native/docs/layout-props#position

Upvotes: 2

Related Questions