项目下载地址:https://github.com/hebiao6446/DemoProject
陆续更新中。。。
这是app store上随机找的一个APP
引导页面大部分APP都有的 。。。 尽管这东西没什么用不说,还占APP控件(总有些2B的设计喜好搞那些鲜艳颜色的高清图)所以大一点的厂或者知名的APP逐渐的废弃了这个功能,我们来分析下 。。。
其实这个就是几张图片和一个分页的控件
react native里面大部分东西都是模块化的,这个其实也不例外,我们可以把每一个page看做成一个模块页面,其实我们的page就是一张图片
我们用代码实现看并观察效果
先看效果
代码如下 这个是单个page的代码
import React, {Component} from 'react';
import {Image, StyleSheet, View} from 'react-native';
const img_guide1 = require('../appimages/guide1.png');
class GuideView extends Component{
render(){
return (
);
}
}
const styles = StyleSheet.create({
imgStyle:{
resizeMode:'cover',
height: '100%',
width: '100%',
},
});
export default GuideView;
上代码
import React, {Component} from 'react';
import {View, StyleSheet, Text} from 'react-native';
import GuideView from './appcode/GuideView';
class App extends Component{
render() {
return (
)
}
}
const styles = StyleSheet.create({
view1:{
flex:1,
justifyContent:'center',
}
});
export default App;
这里有一个问题就是通常页面有很多个, 而这里却只有一个页面
所以我们需要多个GuideView,我们之前说到react native 所有的东西都可以模块化, 我们可以把多个GuideView封装起来 ,也就是我们有5个类似的GuideView 需要左右滑动,并且有页面效果 ,这里react native提供了一个控件叫 ViewPager
https://github.com/react-native-community/react-native-viewpager
import ViewPager from "@react-native-community/viewpager";
React native | iOS | Android |
---|---|---|
ViewPager | UIScrollView | ViewPager |
PageControl | UIPageControl |
单个引导页我们已经完成了 ,但是通常的APP都有多个引导页面,也就是我们需要把 GuideView
重复多次 , 这个时候我们想到react是模块化的东西,一切皆模块
我们需要一个group来管理GuideView ,并且用 viewpager 将其关联,引入 viewpager
一般跟翻页一起的就是 PageControl了 ,这哥们的作用就是page上面的几个点
,这个属于通用功能,多了就不解释了。。。 这个哥们也需要引入
https://github.com/silentcloud/react-native-page-control
yarn add @react-native-community/viewpager
npm install react-native-page-control --save
也别纳闷,为啥有时候用 yarn
有时候 用npm
这个自己百度,我是按照GitHub上作者的操作搬下来的,理论上这两个差不多,细小差别自行百度就行。
安装完以后ios别忘记 ,Android 可以不用处理
pod install
react native 在引用图片的时候跟ios和Android不同,ios和Android都有固定的文件夹存放素材 多的不说,看代码
单个页面Page
import React, {Component} from 'react';
import {Image, StyleSheet, View} from 'react-native';
class GuideView extends Component{
render(){
return (
);
}
}
const styles = StyleSheet.create({
imgStyle:{
resizeMode:'cover',
height: '100%',
width: '100%',
},
});
export default GuideView;
页面Page组的代码如下
import React, {Component} from 'react';
import HbImages from "./utils/HbImages";
import {StyleSheet, TouchableOpacity, View} from "react-native";
import GuideView from "./GuideView";
import PageControl from 'react-native-page-control';
import ViewPager from "@react-native-community/viewpager";
class GuideGroup extends Component{
constructor(pros){
super(pros);
this.state = {
imgArray:[HbImages.img_guide1,HbImages.img_guide2,HbImages.img_guide3,HbImages.img_guide4,HbImages.img_guide5],
showButton:false,
currentPage:0,
}
this.viewPagerSelectCurrent = this.viewPagerSelectCurrent.bind(this);
}
viewPagerSelectCurrent(tag) {
this.setState({
currentPage:tag.nativeEvent.position,
showButton:tag.nativeEvent.position === 4,
})
}
render(){
return
{
this.state.imgArray.map(function (v,i) {
return
})
}
{
if (!this.state.showButton) return;
this.props.onButtonClick();
}
} >
}
}
const styles = StyleSheet.create({
container:{
flex:1,
},
viewPager:{
flex:1,
},
btnView:{
backgroundColor:"#00ff0000",
width:350,
height:70,
position:'absolute',
// left:'50%',
bottom:30,
...Platform.select({
// ios:{ transform:[{translateX:'-150'}],},
// android:{},
})
},
});
export default GuideGroup;
引导页算告一段落了,现在处理下广告页面,不过在处理广告页面之前我们先需要来研究一个新的东西就是本地存贮 storage
我喜欢用这个 AsyncStorage
,其实有很多第三方的框架,找到适合自己的就行,其他的不重要
React native | iOS | Android |
---|---|---|
AsyncStorage | NSUserDefaults | SharedPreferences |
异步 |
同步 | 同步 |
但是重点来了, 在react native 里面本地存储是异步的,这可能就是react native的一个蛋疼的开始了 。。。。 同样第一步导入包
yarn add @react-native-community/async-storage
https://github.com/react-native-community/async-storage
同样别忘记 进入 ios的目录
pod install
import AsyncStorage from '@react-native-community/async-storage';
class HbDataStorage {
/**
* 获取
* @param key
* @returns {Promise|*|Promise.}
*/
static async get(key) {
// const value = ;
return await AsyncStorage.getItem(key);
}
/**
* 保存
* @param key
* @param value
* @returns {*}
*/
static async save(key, value) {
try {
await AsyncStorage.setItem(key, value.toString());
} catch (e) {
}
}
}
export default HbDataStorage;
APP开发广告也是个老生常谈的问题,先看一个广告
那么 我们总结通常的广告页面的几个要素 :
1)是否有广告 , 2)广告的图片地址 , 3)广告的持续时间,4)点击广告的web页面地址, 5)点击广告web的标题,6)是否是第一次启动软件
我们需要搞一个跟开机闪屏广告有关的工具类
import HbDataStorage from "./HbDataStorage";
class ADUtil {
static AD_HAVE_AD = "ad_have_ad";
static AD_IMG_URL = "ad_img_url";
static AD_DURING_TIME = "ad_during_time";
static AD_WEB_TITEL = "ad_web_title";
static AD_WEB_URL = "ad_web_url";
static AD_FT_START = "ad_firsttime_start";
static async ftStart(){
return await HbDataStorage.get(this.AD_FT_START) ;
}
static async setFtStart(b) {
await HbDataStorage.save(this.AD_FT_START, b);
}
static async hasAd(){
return await HbDataStorage.get(this.AD_HAVE_AD) ;
}
static setHasAd(b){
HbDataStorage.save(this.AD_HAVE_AD,b);
}
static async getAdDuringTime(){
return await HbDataStorage.get(this.AD_DURING_TIME);
}
static async getAdWebTitle(){
return await HbDataStorage.get(this.AD_WEB_TITEL);
}
static async getAdWebUrl(){
return await HbDataStorage.get(this.AD_WEB_URL);
}
static async getAdUrlImg(){
return await HbDataStorage.get(this.AD_IMG_URL);
}
static setAdUrlImg(v){
HbDataStorage.save(this.AD_IMG_URL,v);
}
static setAdDuringTime(v){
HbDataStorage.save(this.AD_DURING_TIME,v);
}
static setAdWebTitle(v){
HbDataStorage.save(this.AD_WEB_TITEL,v);
}
static setAdWebUrl(v){
HbDataStorage.save(this.AD_WEB_URL,v);
}
}
export default ADUtil;
广告工具类写完后,我们注意到HbDataStorage
,react native的本地存储保存和获取都是异步的,保存可以先晾着一边,获取重点拿出来看下
ADUtil.hasAd().then((res)=>{
if (res || res == 'true'){
this.setState({
haveAD:true,
})
}
}).catch((e)=>{
});
这玩意是个异步,而且获取出来的值是字符串 (如果获取成功)
基于这些我们把广告也的逻辑代码展示下
import React, {Component} from 'react';
import {Image, Platform, StyleSheet, Text, TouchableOpacity, View} from "react-native";
import HbImages from "./utils/HbImages";
import React from "react";
import ADUtil from "./utils/ADUtil";
class ADView extends Component{
constructor(pros){
super(pros)
this.state = {
haveAD:false,
adImgUrl:'',
remainTime:5,
}
}
render(){
let showAD = this.state.haveAD && this.state.adImgUrl.length > 0 ;
let showText = showAD ? : ;
return (
{showText}
{
this.props.onButtonClick();
}
}
>{this.state.remainTime}s
{
this.props.onButtonClick();
}
} >
)
}
componentDidMount(): void {
ADUtil.getAdUrlImg().then((res)=>{
this.setState({
adImgUrl:res,
})
}).catch((e)=>{
});
ADUtil.hasAd().then((res)=>{
if (res || res == 'true'){
this.setState({
haveAD:true,
})
}
}).catch((e)=>{
});
ADUtil.getAdDuringTime().then((res)=>{
let rmt = Number.parseInt(res);
this.setState({
remainTime:rmt,
})
this.counFun(rmt);
}).catch((e)=>{
});
}
counFun(time):void{
this.timer = setInterval(()=>{
let t = this.state.remainTime - 1;
if (t == 0){
clearInterval(this.timer);
this.props.onButtonClick();
}else {
this.setState({
remainTime:t,
})
}
},1000);
}
componentWillUnmount(){
clearInterval(this.timer);
}
}
const styles = StyleSheet.create({
container:{
flex:1,
},
bgImage:{
width:'100%',
height:'100%',
},
djsView:{
width: 46,
height: 46,
position:'absolute',
backgroundColor:'#e8e8e8',
borderRadius: 23,
top:'5%',
left:'80%',
},
djsText:{
width: 46,
height: 46,
fontSize:16,
fontWeight: '200',
textAlign:'center',
textAlignVertical: 'center',
...Platform.select({
ios:{lineHeight: 46},
android:{},
})
},
btnView:{
backgroundColor:"#00000000",
width:300,
height:150,
position:'absolute',
left:'50%',
bottom:30,
transform:[{translateX:-150}],
},
});
export default ADView;
这里面涉及到 react native的生命周期的话,自行百度
React native | iOS | Android |
---|---|---|
componentDidMount | ViewDidLoad | onCreate |
componentWillUnmount | viewWillUnload | onDestroy(不太准确) |
我们来看效果 。。。
引导页和广告也分别都完成了, 这里面有个逻辑
也就是引导页面是广告页面是互斥的, 为什吗?? 第一次启动的时候广告也说不定还没有请求过来。。。。
项目下载地址:https://github.com/hebiao6446/DemoProject
陆续更新中。。。