Пузырь чата в React Native

В настоящее время я создаю пузырь чата в react-native. Поскольку я новичок в react-native, я сначала попытался создать пузырь чата в браузере, а затем попытался воспроизвести то же самое в react-native. Я изо всех сил пытаюсь воспроизвести стрелку в react-native. Есть идеи / предложения?

Обычный HTML / CSS:

<div>
  <p class = "to-me">Hey!</p>
</div>

div {
  padding:20px;
  justify-self: center;
  align-self: center;
  text-align: left;
  display: flex;
  flex-direction: column;
  width: 450px;
}
div p {
  font-size: 16px;
  line-height: 1.4;
  margin: 1px 0;
  padding: 8px 17px 6px 13px;
  max-width: 380px;
  position: relative;
  border-radius: 18px;
}
div p:after {
  position: absolute;
  content: "";
  top: 0;
  bottom: 0;
  right: 0;
  left: 0;
  z-index: -1;
}
div p.to-me {
  color: black;
  align-self: flex-start;
  background-color: #E5E5EA;
}
div p.to-me:after {
  background: url("data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' x='0px' y='0px' width='15.515px' height='17.5px' viewBox='32.484 17.5 15.515 17.5' enable-background='new 32.484 17.5 15.515 17.5'><path fill='#E5E5EA' d='M38.484,17.5c0,8.75,1,13.5-6,17.5C51.484,35,52.484,17.5,38.484,17.5z'/></svg>") left bottom no-repeat;
  left: -6px;
}

Результат:

Пузырь чата в React Native

Версия React-Native:

<View style = {[styles.balloon, {backgroundColor: '#1084ff'}]}>
      <Text style = {{paddingTop: 5, color: 'white'}}>Hey!</Text>
      <View
      style = {[
        styles.arrowContainer,
        styles.arrowLeftContainer,
      ]}
    >
      <View style = {styles.arrowLeft} />
    </View>
    </View>
  </View>


item: {
   marginVertical: 14,
   flexDirection: 'row'
},
itemIn: {
    marginLeft: 10
},
itemOut: {
   alignSelf: 'flex-end',
   marginRight: 10
},
balloon: {
   maxWidth: scale(250),
   paddingHorizontal: 15,
   paddingTop: 10,
   paddingBottom: 15,
   borderRadius: 20,
},
arrowContainer: {
    position: 'absolute',
    top: 0,
    left: 0,
    right: 0,
    bottom: 0,
    zIndex: -1
    // backgroundColor: 'red'
},
arrowLeftContainer: {
    justifyContent: 'center',
    alignItems: 'flex-start',
    // backgroundColor: 'green'
},

arrowLeft: {
    left: -20,
}

Результат: Пузырь чата в React Native

Я почти воспроизвел пузырь. Просто борюсь со стрелкой. Есть идеи / предложения?

Я почти уверен, что это неосуществимо, иначе это будет большой проблемой ... Причина в том, что android и ios по-разному ведут себя при переполнении и т. д. Возможно, этот компонент поможет вам github.com/Jpoliachik/react-native-triangle, но опять же, даже если вы это сделаете, не может быть на 100% таким же. Я бы посоветовал обойтись без стрелки

Panagiotis Vrs 22.05.2018 14:16

Да, ты прав. Это не то же самое. Проверьте мой ответ :)

Kamil Kamili 22.05.2018 16:47
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Введение в CSS
Введение в CSS
CSS является неотъемлемой частью трех основных составляющих front-end веб-разработки.
Как выровнять Div по центру?
Как выровнять Div по центру?
Чтобы выровнять элемент <div>по горизонтали и вертикали с помощью CSS, можно использовать комбинацию свойств и значений CSS. Вот несколько методов,...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
Toor - Ангулярный шаблон для бронирования путешествий
Toor - Ангулярный шаблон для бронирования путешествий
Toor - Travel Booking Angular Template один из лучших Travel & Tour booking template in the world. 30+ валидированных HTML5 страниц, которые помогут...
9
2
13 178
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Ответ принят как подходящий

Заставить стрелки появиться сложнее, чем я думал, особенно если учесть разные размеры экрана, разные платформы (iOS и Android). Да, @Panagiotis Vrs прав, когда упомянул, что он не будет выглядеть на 100% одинаковым на обеих платформах. Тем не менее, я попытался добиться того же, используя реагировать-родной-svg и реагировать-родной-размер-имеет значение.

Я делюсь своим кодом, может, кто-нибудь сможет это импровизировать и сделать еще лучше.

Часть HTML

<View style = {[styles.item, styles.itemIn]}>
        <View style = {[styles.balloon, {backgroundColor: 'grey'}]}>
          <Text style = {{paddingTop: 5, color: 'white'}}>Hey! How are you?</Text>
          <View
          style = {[
            styles.arrowContainer,
            styles.arrowLeftContainer,
          ]}
        >

           <Svg style = {styles.arrowLeft} width = {moderateScale(15.5, 0.6)} height = {moderateScale(17.5, 0.6)} viewBox = "32.484 17.5 15.515 17.5"  enable-background = "new 32.485 17.5 15.515 17.5">
                <Path
                    d = "M38.484,17.5c0,8.75,1,13.5-6,17.5C51.484,35,52.484,17.5,38.484,17.5z"
                    fill = "grey"
                    x = "0"
                    y = "0"
                />
            </Svg>
        </View>
        </View>
      </View>


      <View style = {[styles.item, styles.itemOut]}>
        <View style = {[styles.balloon, {backgroundColor: '#1084ff'}]}>
          <Text style = {{paddingTop: 5, color: 'white'}}>Hey! I am good. How are you?</Text>
          <View
          style = {[
            styles.arrowContainer,
            styles.arrowRightContainer,
          ]}
        >
           <Svg style = {styles.arrowRight} width = {moderateScale(15.5, 0.6)} height = {moderateScale(17.5, 0.6)} viewBox = "32.485 17.5 15.515 17.5"  enable-background = "new 32.485 17.5 15.515 17.5">
                <Path
                    d = "M48,35c-7-4-6-8.75-6-17.5C28,17.5,29,35,48,35z"
                    fill = "#1084ff"
                    x = "0"
                    y = "0"
                />
            </Svg>
        </View>
        </View>
      </View>





       <View style = {[styles.item, styles.itemOut]}>
        <View style = {[styles.balloon, {backgroundColor: '#1084ff'}]}>
          <Text style = {{paddingTop: 5, color: 'white'}}>Check this Image out !!!</Text>
          <View
          style = {[
            styles.arrowContainer,
            styles.arrowRightContainer,
          ]}
        >
           <Svg style = {styles.arrowRight} width = {moderateScale(15.5, 0.6)} height = {moderateScale(17.5, 0.6)} viewBox = "32.485 17.5 15.515 17.5"  enable-background = "new 32.485 17.5 15.515 17.5">
                <Path
                    d = "M48,35c-7-4-6-8.75-6-17.5C28,17.5,29,35,48,35z"
                    fill = "#1084ff"
                    x = "0"
                    y = "0"
                />
            </Svg>
        </View>
        </View>
      </View>


       <View style = {[styles.item, styles.itemOut]}>
        <View style = {[styles.balloon, {backgroundColor: '#1084ff'}]}>

        <Image
            styleName = "small"
            borderRadius = {5}
            source = {{ uri: 'https://shoutem.github.io/img/ui-toolkit/examples/image-3.png'}}
            />
          <View
          style = {[
            styles.arrowContainer,
            styles.arrowRightContainer,
          ]}
        >
           <Svg style = {styles.arrowRight} width = {moderateScale(15.5, 0.6)} height = {moderateScale(17.5, 0.6)} viewBox = "32.485 17.5 15.515 17.5"  enable-background = "new 32.485 17.5 15.515 17.5">
                <Path
                    d = "M48,35c-7-4-6-8.75-6-17.5C28,17.5,29,35,48,35z"
                    fill = "#1084ff"
                    x = "0"
                    y = "0"
                />
            </Svg>
        </View>
        </View>
      </View>


     <View style = {[styles.item, styles.itemIn]}>
        <View style = {[styles.balloon, {backgroundColor: 'grey'}]}>
          <Text style = {{paddingTop: 5, color: 'white'}}>Nice Picture</Text>
          <View
          style = {[
            styles.arrowContainer,
            styles.arrowLeftContainer,
          ]}
        >

           <Svg style = {styles.arrowLeft} width = {moderateScale(15.5, 0.6)} height = {moderateScale(17.5, 0.6)} viewBox = "32.484 17.5 15.515 17.5"  enable-background = "new 32.485 17.5 15.515 17.5">
                <Path
                    d = "M38.484,17.5c0,8.75,1,13.5-6,17.5C51.484,35,52.484,17.5,38.484,17.5z"
                    fill = "grey"
                    x = "0"
                    y = "0"
                />
            </Svg>
        </View>
        </View>
      </View>

Часть CSS

 item: {
       marginVertical: moderateScale(7, 2),
       flexDirection: 'row'
    },
    itemIn: {
        marginLeft: 20
    },
    itemOut: {
       alignSelf: 'flex-end',
       marginRight: 20
    },
    balloon: {
       maxWidth: moderateScale(250, 2),
       paddingHorizontal: moderateScale(10, 2),
       paddingTop: moderateScale(5, 2),
       paddingBottom: moderateScale(7, 2),
       borderRadius: 20,
    },
    arrowContainer: {
        position: 'absolute',
        top: 0,
        left: 0,
        right: 0,
        bottom: 0,
        zIndex: -1,
        flex: 1
    },
    arrowLeftContainer: {
        justifyContent: 'flex-end',
        alignItems: 'flex-start'
    },

    arrowRightContainer: {
        justifyContent: 'flex-end',
        alignItems: 'flex-end',
    },

    arrowLeft: {
        left: moderateScale(-6, 0.5),
    },

    arrowRight: {
        right:moderateScale(-6, 0.5),
    }

Теперь масштабирование на разных экранах устройств было для меня всего лишь методом проб и ошибок. На данный момент результат для меня достаточно хорош. Возможно, когда у меня будет время, я постараюсь улучшить этот текущий дизайн.

Вот как это выглядит на iOS:

iPhone 7:iPhone7

iPhone X:

К сожалению, теперь на Android мне не удалось отобразить кривую стрелки. Может я что-то не так делаю. Вот как это выглядит в итоге.

Пиксель 2:Pixel2

Nexus 6:Nexus6

Возможно, мы сможем использовать flex, чтобы кривые стрелок хорошо выглядели на Android.

На случай, если кто-то сделал лучшую версию этого. Делитесь. :)

Вы можете включить это без использования SVG. В основном это достигается путем закрепления компонентов <View> в углу текстового контейнера.

<View style = {{
                    backgroundColor: "#0078fe",
                    padding:10,
                    marginLeft: '45%',
                    borderRadius: 5,
                    marginTop: 5,
                    marginRight: "5%",
                    maxWidth: '50%',
                    alignSelf: 'flex-end',
                    
                    
                    borderRadius: 20,
                  }}>
  
                    
                    <Text style = {{ fontSize: 16, color: "#fff", }} key = {index}>{item.text}</Text>
  
                      <View style = {styles.rightArrow}></View>
                      
                      <View style = {styles.rightArrowOverlap}></View>
                    
                    
                    
</View> 


const styles = StyleSheet.create({
rightArrow: {
  position: "absolute",
  backgroundColor: "#0078fe",
  //backgroundColor:"red",
  width: 20,
  height: 25,
  bottom: 0,
  borderBottomLeftRadius: 25,
  right: -10
},

rightArrowOverlap: {
  position: "absolute",
  backgroundColor: "#eeeeee",
  //backgroundColor:"green",
  width: 20,
  height: 35,
  bottom: -6,
  borderBottomLeftRadius: 18,
  right: -20

},

Значения свойств, такие как borderRadius, maxWidth, margin, произвольны и могут быть изменены в соответствии с вашими потребностями. Вы можете обратиться к статье это, в которой я подробно объяснил то же самое.
Предостережение: используйте это с FlatList, так как наблюдались несоответствия рендеринга с другими функциями (например, картой)

Вы можете использовать библиотеку response-native-gifted-chat, чтобы сделать идеальный пузырь или, если вы хотите создать пузырек клиентов, используйте плоский список react-native в элементе рендеринга плоского списка, чтобы сделать пузырь выровнять пузырь в соответствии с идентификатором отправителя или идентификатора получателя

Другие вопросы по теме