最近学习了一个网上的React Native项目,利用React Native制作一个类似于美团的App,项目属于对之前React Native常用组件的基本使用,但是仍有一些关键点值得记录。最后做成的效果如下:
接着就需要把这些数据填充到界面上,界面上的显示模块是固定的,例如主页中的活动模块如下:
可以看到活动广告模块可以分为三类:MediumBlock(左上角粉色框)、SmallBlock(绿色框)、LargeBlock(蓝色框),可以将这三类框分别抽象为组件,然后排布到页面上。例如SmallBlock.js:
export default class SmallBlock extends Component {render() {return (<TouchableOpacity style&#61;{styles.container}>
<View>
<Text style&#61;{[{color:this.props.data.typeface_color},styles.title]}>
{this.props.data.title}Text>
<Text>{this.props.data.deputytitle}Text>
View>
<Image source&#61;{{uri:this.handleUrl(this.props.data.imageurl)}} style&#61;{styles.image}/>
TouchableOpacity>
)}handleUrl(url){let imageUrl&#61;&#39;&#39;;
if(url.indexOf(&#39;w.h&#39;)&#61;&#61;&#61;-1){imageUrl&#61;url;
}else {//美团的图片url中有w.h字段&#xff0c;代表图片的长与宽&#xff0c;需要替换后才能得到图片
imageUrl&#61;url.replace(&#39;w.h&#39;,&#39;60.60&#39;);
}return imageUrl;
}
} 在页面中调用组件&#xff0c;并填充数据&#xff1a;
<SmallBlock data&#61;{this.props.shopList[4]}/>
例如将商家页面shopScreen.js中的“购物中心”封装成为一个组件ShopCenter&#xff0c;
当点击它时跳转到详情页shopDetail.js&#xff0c;但是在每个ShopCenter组件中是没办法处理跳转事件的&#xff0c;只有在ShopScreen类中才可以访问到navigation对象&#xff0c;实现跳转。因此需要在ShopScreen中调用ShopCenter组件时&#xff0c;为其绑定一个事件属性onClick&#xff08;这个属性名可自定&#xff09;&#xff0c;然后在ShopCenter组件中点击时调用该属性触发父组件中对应的事件&#xff1a;
例如父组件中调用子组件ShopCenter以及绑定onClick属性为jumpDetail函数&#xff1a;
<ShopCenter key&#61;{index} data&#61;{item} onClick&#61;{this.jumpDetail}/>
...
jumpDetail(url){navigation.navigate(&#39;Detail&#39;,url);
} 其中变量navigation是this.props.navigation&#xff0c;是由StackNavigator传递给它的子组件的&#xff0c;我直接使用时&#xff0c;会报错this.props未定义&#xff0c;于是我把它保存到一个全局变量navigation中&#xff0c;然后再调用其navigate方法。
在子组件ShopCenter中点击触发jumpTo函数来调用父组件属性onClick
export default class ShopCenter extends Component {render() {return (<TouchableOpacity style&#61;{styles.container}onPress&#61;{()&#61;>this.jumpTo(this.props.data.detailurl)}>
<Image source&#61;{{uri:this.props.data.img}} style&#61;{styles.image} />
<Text style&#61;{styles.imageLabel}>{this.props.data.showtext.text}Text>
<Text style&#61;{styles.name}>{this.props.data.name}Text>
TouchableOpacity>
)}jumpTo(detailurl){let url&#61;detailurl;//对url进行处理&#xff0c;去掉url前面没用的部分
url&#61;detailurl.replace(&#39;imeituan://www.meituan.com/web/?url&#61;&#39;,&#39;&#39;);
this.props.onClick({url:url});//触发父组件onOnclick&#xff0c;并传入url参数
}
}
App中并不是所有的页面都是写死的&#xff0c;这样很不易于维护与更新。一些页面是通过网页来实现的&#xff0c;在App中点击时跳转到对应的网页。当我们想要修改时&#xff0c;只需要更新在服务器端网页就可以&#xff0c;而不必更新App、重新发布等。这种思维就是一种Hybrid混合开发的思维。
例如当点击购物中心时跳转到ShopDetail页面&#xff0c;并通过navigation传入对应网页的url&#xff0c;在ShopDetail中只需通过
ShopDetail.js就只有很短几行用于呈现WebView:
export default class ShopDetail extends Component {static navigationOptions&#61;{title:&#39;商场详情&#39;,
headerStyle:{ //导航栏样式设置
backgroundColor:&#39;#8bffce&#39;,
},
};
render() {let url&#61;this.props.navigation.state.params.url&#43; &#39;?uuid&#61;5C7B6342814C7B496D836A69C872&#39;; return (<WebView source&#61;{{uri: url}}JavascriptEnabled&#61;{true}domStorageEnabled&#61;{true}/>
)}
}
之前一直通过debug来将react native安装到手机上&#xff0c;如果需要发行则需要打包生成apk。
Android要求所有应用都有一个数字签名才会被允许安装在用户手机上&#xff0c;所有首先需要生成一个签名密钥。要通过keytool生成密钥&#xff0c;首先进入jdk下的bin目录&#xff0c;打开cmd输入如下命令
keytool -genkey -v -keystore my-release-key.keystore -alias my-key-alias -keyalg RSA -keysize 2048 -validity 10000
其中my-release-key为密钥库的名字&#xff0c;my-key-alias为密钥库别名可以自定义&#xff0c;接着会出现命令行提示&#xff0c;要求输入相关信息&#xff0c;并设置相关密码&#xff0c;之后会在当前目录下生成my-release-key.keystore文件。
把该文件拷贝到react native工程下的android/app目录下
在C:\Users\你的用户名\.gradle目录下新建gradle.properties文件&#xff0c;并在其中输入如下内容&#xff1a;
MYAPP_RELEASE_STORE_FILE&#61;my-release-key.keystore 密钥库的名字
我的密钥密码与库密码一致
MYAPP_RELEASE_KEY_ALIAS&#61;my-key-alias 密钥库别名
MYAPP_RELEASE_STORE_PASSWORD&#61;***** 密钥库密码
MYAPP_RELEASE_KEY_PASSWORD&#61;***** 密钥密
打开react native项目下的android/app/build.gradle文件&#xff0c;添加如下内容
android {...defaultConfig { ... }signingConfigs {release {storeFile file(MYAPP_RELEASE_STORE_FILE)storePassword MYAPP_RELEASE_STORE_PASSWORDkeyAlias MYAPP_RELEASE_KEY_ALIASkeyPassword MYAPP_RELEASE_KEY_PASSWORD}}buildTypes {release {...signingConfig signingConfigs.release}}
}
进入react native项目的android目录下执行cmd命令&#xff1a;
gradlew assembleRelease
生成的apk文件位于项目的android/app/build/outputs/apk/app-release.apk。
在GitHub上的代码仓库为&#xff1a;https://github.com/SuperTory/React-Native-ECommerce