react-native聊天室|RN版聊天App仿微信实例|RN仿微信界面
一、前言
9月,又到开学的季节。为每个一直默默努力的自己点赞!最近都沉浸在reactnative原生app开发中,之前也有使用vue/react/angular等技术开发过聊天室项目,另外还使用RN技术做了个自定义模态弹窗rnPop组件。
一、项目简述
基于react+react-native+react-navigation+react-redux+react-native-swiper+rnPop等技术开发的仿微信原生App界面聊天室——RN_ChatRoom,实现了原生app启动页、AsyncStorage本地存储登录拦截、集成rnPop模态框功能(仿微信popupWindow弹窗菜单)、消息触摸列表、发送消息、表情(动图),图片预览,拍摄图片、发红包、仿微信朋友圈等功能。
二、技术点
- MVVM框架:react/react-native/react-native-cli
- 状态管理:react-redux/redux页面导航:react-navigationrn
- 弹窗组件:rnPop打包工具:webpack2.0轮播组件:react-native-swiper
- 图片/相册:react-native-image-picker
{
"name":"RN_ChatRoom",
"version":"0.0.1",
"aboutMe":"QQ:282310962、wx:xy190310",
"dependencies":{
"react":"16.8.6",
"react-native":"0.60.4"
},
"devDependencies":{
"@babel/core":"^7.5.5",
"@babel/runtime":"^7.5.5",
"@react-native-community/async-storage":"^1.6.1",
"@react-native-community/eslint-config":"^0.0.5",
"babel-jest":"^24.8.0",
"eslint":"^6.1.0",
"jest":"^24.8.0",
"metro-react-native-babel-preset":"^0.55.0",
"react-native-gesture-handler":"^1.3.0",
"react-native-image-picker":"^1.0.2",
"react-native-swiper":"^1.5.14",
"react-navigation":"^3.11.1",
"react-redux":"^7.1.0",
"react-test-renderer":"16.8.6",
"redux":"^4.0.4",
"redux-thunk":"^2.3.0"
},
"jest":{
"preset":"react-native"
}
}
◆App全屏幕启动页splash模板
react-native如何全屏启动?设置StatusBar顶部条背景为透明translucent={true},并配合RN动画Animated
/**
*@desc启动页面
*/
importReact,{Component}from'react'
import{StatusBar,Animated,View,Text,Image}from'react-native'
exportdefaultclassSplashextendsComponent{
constructor(props){
super(props)
this.state={
animFadeIn:newAnimated.Value(0),
animFadeOut:newAnimated.Value(1),
}
}
render(){
return(
RN-ChatRoomv1.0.0
)
}
componentDidMount(){
//判断是否登录
storage.get('hasLogin',(err,object)=>{
setTimeout(()=>{
Animated.timing(
this.state.animFadeOut,{duration:300,toValue:0}
).start(()=>{
//跳转页面
util.navigationReset(this.props.navigation,(!err&&object&&object.hasLogin)?'Index':'Login')
})
},1500);
})
}
}
◆RN本地存储技术async-storage
/**
*@desc本地存储函数
*/
importAsyncStoragefrom'@react-native-community/async-storage'
exportdefaultclassStorage{
staticget(key,callback){
returnAsyncStorage.getItem(key,(err,object)=>{
callback(err,JSON.parse(object))
})
}
staticset(key,data,callback){
returnAsyncStorage.setItem(key,JSON.stringify(data),callback)
}
staticdel(key){
returnAsyncStorage.removeItem(key)
}
staticclear(){
AsyncStorage.clear()
}
}
global.storage=Storage
声明全局global变量,只需在App.js页面一次引入、多个页面均可调用。
storage.set('hasLogin',{hasLogin:true})
storage.get('hasLogin',(err,object)=>{...})
◆App主页面模板及全局引入组件
importReact,{Fragment,Component}from'react'
import{StatusBar}from'react-native'
//引入公共js
import'./src/utils/util'
import'./src/utils/storage'
//导入样式
import'./src/assets/css/common'
//导入rnPop弹窗
import'./src/assets/js/rnPop/rnPop.js'
//引入页面路由
importPageRouterfrom'./src/router'
classAppextendsComponent{
render(){
return(
{/* */}
{/*页面*/}
{/*弹窗模板*/}
)
}
}
exportdefaultApp
◆react-navigation页面导航器/地址路由、底部tabbar
由于react-navigation官方顶部导航器不能满足需求,如是自己封装了一个,功能效果有些类似微信导航。
exportdefaultclassHeaderBarextendsComponent{
constructor(props){
super(props)
this.state={
searchInput:''
}
}
render(){
/**
*更新
*@param{navigation|页面导航}
*@param{title|标题}
*@param{center|标题是否居中}
*@param{search|是否显示搜索}
*@param{headerRight|右侧Icon按钮}
*/
let{navigation,title,bg,center,search,headerRight}=this.props
return(
{/*返回*/}
{/*标题*/}
{!search&¢er? :null}
{
search?
(
{this.setState({searchInput:text})}}style={styles.barSearchText}placeholder='搜索'placeholderTextColor='rgba(255,255,255,.6)'/>
)
:
(
{title?{title}:null}
)
}
{/*右侧*/}
{
!headerRight?null:headerRight.map((item,index)=>{
return(
item.press?item.press(this.state.searchInput):null}>
{
item.type==='iconfont'?item.title:(
typeofitem.title==='string'?
{`${item.title}`}
:
)
}
{/*圆点*/}
{item.badge?{item.badge}:null}
{item.badgeDot?:null}
)
})
}
)
}
goBack=()=>{
this.props.navigation.goBack()
}
}
//创建底部TabBar
consttabNavigator=createBottomTabNavigator(
//tabbar路由(消息、通讯录、我)
{
Index:{
screen:Index,
navigationOptions:({navigation})=>({
tabBarLabel:'消息',
tabBarIcon:({focused,tintColor})=>(
12
)
})
},
Contact:{
screen:Contact,
navigationOptions:{
tabBarLabel:'通讯录',
tabBarIcon:({focused,tintColor})=>(
)
}
},
Ucenter:{
screen:Ucenter,
navigationOptions:{
tabBarLabel:'我',
tabBarIcon:({focused,tintColor})=>(
)
}
}
},
//tabbar配置
{
...
}
)
◆RN聊天页面功能模块
1、表情处理:原本是想着使用图片表情gif,可是在RN里面textInput文本框不能插入图片,只能通过定义一些特殊字符:66:(:12[奋斗]解析表情,处理起来有些麻烦,而且图片多了影响性能,如是就改用emoj表情符。
faceList:[
{
nodes:[
'