React Native中的聊天气泡 [英] Chat Bubble in React Native

查看:70
本文介绍了React Native中的聊天气泡的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在用本机创建聊天气泡.由于我是React Native的新手,因此我首先尝试在浏览器上创建聊天气泡,然后尝试在react-native中复制聊天气泡.我正在努力以本机的方式复制箭头.有任何想法/建议吗?

普通HTML/CSS:

 < div>< p class ="to-me">嘿!</p></div>div {内边距:20px;自我辩护:中心;自我定位:居中;文字对齐:左;显示:flex;flex-direction:列;宽度:450像素;}div p {font-size:16px;行高:1.4;边距:1px 0;填充:8px 17px 6px 13px;最大宽度:380px;职位:相对border-radius:18px;}div p:之后{位置:绝对;内容: "";最高:0;底部:0;正确:0;左:0;z索引:-1;}div p.to-me {颜色:黑色;align-self:flex-start;背景颜色:#E5E5EA;}div p.to-me:之后{背景: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)左下无重复;左:-6px;} 

结果:

反应版本:

 <查看样式= {[styles.balloon,{backgroundColor:'#1084ff'}]}}><文本样式= {{paddingTop:5,颜色:'white'}}>嘿!</Text><查看样式= {[styles.arrowContainer,styles.arrowLeftContainer,]}><查看样式= {styles.arrowLeft}/></View></View></View>物品: {marginVertical:14flexDirection:'行'},itemIn:{marginLeft:10},itemOut:{alignSelf:'flex-end',marginRight:10},气球: {maxWidth:scale(250),填充水平:15paddingTop:10,paddingBottom:15,borderRadius:20,},arrow容器:{位置:绝对",上:0,左:0,右:0,底部:0,zIndex:-1//backgroundColor:红色"},arrowLeftContainer:{justifyContent:中心",alignItems:'flex-start',//backgroundColor:绿色"},arrowLeft:{左:-20,} 

结果:

我几乎复制了泡沫.只是在箭头部分上挣扎.有任何想法/建议吗?

解决方案

使箭头出现比我想象的要难,尤其是当您考虑不同的屏幕尺寸,不同的平台(iOS和android)时.是的,@ Panagiotis Vrs提到两个平台看起来都不是100%相同时是正确的.尽管如此,我还是尝试使用

iPhone X:

不幸的是,现在在android上,我无法使箭头的曲线出现.也许我做错了.最终看起来就是这样.

像素2:

Nexus 6:

也许我们可以使用 flex 使箭头曲线在android上看起来不错.

以防有人对它做了更好的版本.分享.:)

I am currently making a chat bubble in react-native. Since I am new to react-native I first tried to make the chat bubble on a browser and then tried to replicate the same in react-native. I am struggling to replicate the arrow in react-native. Any ideas/suggestions?

Normal 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;
}

The result:

React-Native Version:

<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,
}

The result:

I have almost replicated the bubble. Just struggling on the arrow part. Any ideas/suggestions?

解决方案

Making the arrows appear was harder than I thought it would be, especially when you consider different screen sizes, different platforms (iOS and android). Yes, @Panagiotis Vrs is correct when he mentioned that it won't look 100% same on both platforms. Nevertheless, I tried to achieve the same using react-native-svg and react-native-size-matters.

I am sharing my code, maybe someone can improvise this and make this even better.

The HTML Part

<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>

The CSS Part

 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),
    }

Now scaling it on different device screens was just trial and error for me. The output right now is good enough for me. Maybe when I have time I will try to improve on this current design.

This is how it looks on iOS:

iPhone 7:

iPhone X:

Now on android unfortunately I wasn't able to make the curve of the arrow appear. Maybe I am doing something wrong. This is how it looks in the end.

Pixel 2:

Nexus 6:

Maybe we can use flex to make the arrow curves look good on android.

In case someone has made a better version of this. Do share. :)

这篇关于React Native中的聊天气泡的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆