В настоящее время я создаю пузырь чата в 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:
<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,
}
Я почти воспроизвел пузырь. Просто борюсь со стрелкой. Есть идеи / предложения?
Да, ты прав. Это не то же самое. Проверьте мой ответ :)






Заставить стрелки появиться сложнее, чем я думал, особенно если учесть разные размеры экрана, разные платформы (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:
К сожалению, теперь на Android мне не удалось отобразить кривую стрелки. Может я что-то не так делаю. Вот как это выглядит в итоге.
Возможно, мы сможем использовать 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 в элементе рендеринга плоского списка, чтобы сделать пузырь выровнять пузырь в соответствии с идентификатором отправителя или идентификатора получателя
Я почти уверен, что это неосуществимо, иначе это будет большой проблемой ... Причина в том, что android и ios по-разному ведут себя при переполнении и т. д. Возможно, этот компонент поможет вам github.com/Jpoliachik/react-native-triangle, но опять же, даже если вы это сделаете, не может быть на 100% таким же. Я бы посоветовал обойтись без стрелки