React Native에서 라이브러리를 사용하지 않고 테두리 만 연설 거품 만들기

11030 단어 reactnativeReact
Fringe81 어드벤트 캘린더 1일째의 기사입니다.

당사가 제공하는 Unipos이라는 서비스는 웹 버전 외에 Android/iOS용 React Native를 사용하여 앱을 개발하고 있습니다.
이번은 그 앱의 신기능 개발에 있어서, 「테두리만의 풍선」을 만들 필요가 나왔기 때문에 해 보았다, 라고 하는 가벼운 기사입니다.

「테두리만의 풍선」이라고 하는 것은 이런 녀석입니다.



react-native-svg등을 사용해 만드는 방법도 있을 것 같습니다만, 이번은 의존 라이브러리 없이 React Native의 표준 컴퍼넌트만을 사용해 만들어 보았습니다.

환경


  • React Native 0.59.9
  • TypeScript 3.7.2

  • 이번에 사용한 환경은 상기입니다만, 아마 다른 환경에서도 문제 없게 사용할 수 있을 것입니다.

    결론



    구조는 어쨌든, 먼저 완성된 코드를 붙입니다.
    import * as React from 'react';
    import {View, Text, StyleSheet} from 'react-native';
    
    const BALLOON_TRIANGLE_HEIGHT = 14;
    
    export const CommentBalloon = ({text}: {text: string}) => {
      return (
        <View style={{justifyContent: 'flex-end', paddingTop: BALLOON_TRIANGLE_HEIGHT}}>
          <View style={styles.balloonContainer}>
            <View style={[styles.balloonTriangleBase, styles.balloonTriangleOuter]} />
            <View style={[styles.balloonTriangleBase, styles.balloonTriangleInner]} />
            <View style={styles.textContainer}>
              <Text style={styles.text}>{text}</Text>
            </View>
          </View>
        </View>
      );
    };
    
    const styles = StyleSheet.create({
      balloonContainer: {
        width: '100%',
        backgroundColor: '#FFFFFF',
        borderWidth: 1,
        borderColor: '#E1E6E6',
        borderRadius: 2
      },
      balloonTriangleBase: {
        width: 0,
        height: 0,
        position: 'absolute',
        bottom: '100%',
        borderTopColor: 'transparent',
        borderLeftColor: 'transparent',
        borderRightColor: 'transparent'
      },
      balloonTriangleOuter: {
        left: 32,
        borderWidth: BALLOON_TRIANGLE_HEIGHT,
        borderBottomColor: '#E1E6E6'
      },
      balloonTriangleInner: {
        left: 33,
        borderWidth: BALLOON_TRIANGLE_HEIGHT - 1, // border分だけ引く
        borderBottomColor: '#FFFFFF'
      },
      textContainer: {
        padding: 15
      },
      text: {
        fontWeight: '300',
        fontSize: 14,
        lineHeight: 20,
        color: '#4A4A4A',
        maxWidth: '100%',
        letterSpacing: 0
      }
    });
    

    메커니즘



    만져본 적이 있는 분은 이미 아시다시피, React Native에서는 CSS와 비슷한 형식의 속성을 가진 객체를 사용하여 화면 스타일을 정의합니다.
    따라서 CSS로 할 수있는 일은 대부분 가능하지만 일부는 할 수 없습니다. 그 중 하나는 :before 또는 :after와 같은 의사 요소입니다.

    CSS를 사용하여 연설 거품을 만드는 방법으로 유명한 것은 :before 또는 :after 의사 요소를 사용하여 크기가없는 요소에 border를 적용하여 연설 거품의 삼각형 부분 (여담이지만 부리라고 부르는 것 같네요)를 만드는 방법이 있습니다.

    【코피페 변경 OK】 CSS로 만들 수 있는 풍선 디자인 8선 | creive【클리브】

    웹에서의 방법은 이쪽의 기사가 매우 알기 쉬웠습니다.

    React Native에서는 의사 요소를 사용할 수 없기 때문에, 대신 내용이 없는 View 컴퍼넌트를 배치해, 그 컴퍼넌트에 대해서 스타일을 맞추고 있습니다.

    또, 테두리만의 풍선으로 하기 위해, 크기가 다른 부리를 2개 준비해, 외측의 선 부분과, 안쪽의 칠의 부분을 어긋나 겹쳐 있습니다. ( balloonTriangleOuterballoonTriangleInner 그것)

    또, 부리의 부분은 절대 위치 지정( position: 'absolute' )로 배치하고 있기 때문에, 이대로라도 위에 배치된 컴퍼넌트가 부리 위에 겹치는 것을 방지하기 위해, <View style={{justifyContent: 'flex-end', paddingTop: BALLOON_TRIANGLE_HEIGHT}}> 라고 하는 컴퍼넌트로 랩하는 것으로 CommentBalloon 컴퍼넌트 전체에서 보았을 때 부리를 포함한 높이가 되도록 조정하고 있습니다.



    소감



    React Native의 style이 Web의 CSS와 같은 거동이 되도록(듯이) 구현되고 있는 덕분도 있어 이렇게 웹에서 자주(잘) 사용되는 테크닉을 전용해, 그다지 고민하지 않고 화면을 만들 수 있는 것은 행복한 일이다 라고 다시 생각했습니다.

    좋은 웹페이지 즐겨찾기