项目地址为:https://github.com/StarkCoder/RNTest
首先我们来分析代码
跟平时不同的是,这个代码运行直接到的是HomePage页面
//index.js代码如下
/**
* @format
*/
import {AppRegistry} from 'react-native';
import App from './App';
import HomePage from './app/views/home/HomePage'
import {name as appName} from './app.json';
AppRegistry.registerComponent(appName, () => HomePage);
//app/views/home/HomePage.js
/**
* HomePage页面
*
*
* */
import React, {PureComponent} from 'react';
import {
Platform,
StyleSheet,
Text,
View,
FlatList,
TouchableOpacity,
} from 'react-native';
//多选框
import CheckBox from 'react-native-check-box';
import Toolbar from '../../component/header/Toolbar';
import SwipeableItem from '../../component/swipeable/SwipeableItem';
const ListData = [
{key: 'a'},
{key: 'b'}
]
export default class HomePage extends PureComponent {
constructor(props) {
super(props);
this.state = {
isEditMode: false,
isChecked: false,
}
}
componentDidMount(): void {
}
_keyExtractor = (item, index) => item.id;
//渲染列表项
_renderItem = (item, index) => {
return (
<SwipeableItem
key={index}
title={'系统消息'}
note={'2019.5.4'}
content={'AAA'}
isEditMode={this.state.isEditMode}
/>
);
}
render() {
return (
<View style={styles.container}>
<Toolbar
title='消息测试'
hideLeftButtons={true}
rightButtons={{
text: '编辑',
onPress: () => {
const mode = this.state.isEditMode;
this.setState({isEditMode: !mode})
}
}}/>
<View style={{paddingVertical: 10}}>
<CheckBox
style={{flex: 1, padding: 10}}
onClick={() => {
this.setState({
isChecked: !this.state.isChecked
})
}}
isChecked={this.state.isChecked}
leftText={"CheckBox"}
/>
<CheckBox
style={{flex: 1, padding: 10}}
onClick={() => {
this.setState({
isChecked: !this.state.isChecked
})
}}
isChecked={this.state.isChecked}
leftText={"CheckBox"}
/>
</View>
<FlatList
data={ListData}
extraData={this.state.isEditMode}
keyExtractor={this._keyExtractor}
renderItem={this._renderItem}
/>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#e4e4e4',
}
})
//app/component/header/Toolbar.js
import React, {PureComponent} from 'react';
import {Image, StyleSheet, Text, TouchableOpacity, View} from 'react-native';
// import {withNavigation} from 'react-navigation';
import PropTypes from 'prop-types';
import styles from './Toolbar.style';
import TextButton from '../button/TextButton';
const ICON_BACK = require('../../constant/image/circle_drashed_32px.png');
const fallbackView = <View/>;
class Toolbar extends PureComponent {
static propTypes = {
title: PropTypes.string.isRequired,
hideLeftButtons: PropTypes.bool,
leftButtons: PropTypes.oneOfType([
PropTypes.arrayOf(PropTypes.shape({
text: PropTypes.string,
onPress: PropTypes.func,
})),
PropTypes.shape({
text: PropTypes.string,
onPress: PropTypes.func,
}),
]),
rightButtons: PropTypes.oneOfType([
PropTypes.arrayOf(PropTypes.shape({
text: PropTypes.string,
onPress: PropTypes.func,
})),
PropTypes.shape({
text: PropTypes.string,
onPress: PropTypes.func,
}),
]),
onBackPress: PropTypes.func,
};
static defaultProps = {
hideLeftButtons: false,
};
renderButton = (button, i) => {
if (button.icon) {
return (
<TouchableOpacity
key={i}
onPress={button.onPress}
disabled={button.disabled}
style={styles.iconButton}>
<Image
source={button.icon}
style={styles.buttonIcon}
resizeMode="contain"/>
</TouchableOpacity>
);
} else {
return (
<TextButton
key={i}
text={button.text}
disabled={button.disabled}
onPress={button.onPress}/>
)
}
};
render() {
const {title, hideLeftButtons, leftButtons, rightButtons, backgroundColor, style} = this.props;
let leftButtonsView = fallbackView;
if (leftButtons) {
const finalLeftButtons = Array.isArray(leftButtons) ? leftButtons : [leftButtons];
leftButtonsView = (
<View style={styles.buttons}>
{finalLeftButtons.map(this.renderButton)}
</View>
);
} else if (!hideLeftButtons) {
leftButtonsView = (
<TouchableOpacity
onPress={this.goBack}
style={styles.backButton}>
<Image
source={ICON_BACK}
style={styles.backIcon}
resizeMode="contain"/>
</TouchableOpacity>
);
}
let rightButtonsView = fallbackView;
if (rightButtons) {
const finalRightButtons = Array.isArray(rightButtons) ? rightButtons : [rightButtons];
rightButtonsView = (
<View style={styles.buttons}>
{finalRightButtons.map(this.renderButton)}
</View>
);
}
const containerStyle = StyleSheet.compose(styles.container, style);
const finalContainerStyle = backgroundColor ? [containerStyle, {backgroundColor}] : containerStyle;
return (
<View style={finalContainerStyle}>
<View style={styles.titleContainer}>
<Text style={styles.title} numberOfLines={1}>{title}</Text>
</View>
<View style={styles.actionBar}>
{leftButtonsView}
{rightButtonsView}
</View>
</View>
);
}
goBack = () => {
if (typeof this.props.onBackPress === 'function') {
this.props.onBackPress();
} else {
this.props.navigation.goBack(null);
}
};
}
// export default withNavigation(Toolbar);
export default Toolbar;
// app/component/swipeable/SwipeableItem.js
import React, {PureComponent} from 'react';
import {
Platform,
StyleSheet,
Text,
View,
FlatList,
TouchableOpacity,
Image,
} from 'react-native';
import PropTypes from 'prop-types';
import Swipeable from 'react-native-swipeable';
const Dimensions = require('Dimensions');
const screenWidth = Dimensions.get('window').width;
const ICON_CIRCLE_CHECK = require('../../constant/image/circle_check_32px.png');
const ICON_CIRCLE_DASH = require('../../constant/image/circle_drashed_32px.png');
const ITEM_HEIGHT = 60;
const leftContent = <Text>Pull to activate</Text>;
export default class SwipeableItem extends PureComponent {
/**
* isEditMode 是否是编辑模式
*
* isChecked 是否被选中 内部状态
* source 头部图片资源
* title 左边文本
* note 右边文本
* content 下面文本
*
*
* */
static propTypes = {
// isChecked: PropTypes.bool.isRequired,
isEditMode: PropTypes.bool.isRequired,
}
constructor(props) {
super(props);
this.state = {
isChecked: false
}
}
componentWillMount(): void {
}
//条目点击事件
//在编辑模式下就是被选中,非编辑模式下就是跳转
onItemPress = () => {
if (this.props.isEditMode) {
const isCheck = this.state.isChecked;
this.setState({isChecked: !isCheck})
} else {
// this.navigation
}
}
//渲染头部图片
renderHeaderImage() {
if (this.state.isChecked) {
return (<Image source={ICON_CIRCLE_CHECK}/>);
} else {
return (<Image source={ICON_CIRCLE_DASH}/>);
}
}
render() {
const rightButtons = [
<TouchableOpacity
style={styles.buttonStyle1}
><Text>{'已读'}</Text></TouchableOpacity>,
<TouchableOpacity
style={styles.buttonStyle2}
><Text style={{color:'#FFF'}}>{'删除'}</Text></TouchableOpacity>
];
return (
<Swipeable
leftContent={leftContent}
rightButtons={rightButtons}
rightButtonWidth={75}
rightActionActivationDistance={0}
>
<TouchableOpacity
style={styles.swipeContainer}
onPress={this.onItemPress}>
{this.props.isEditMode ? this.renderHeaderImage() : null}
<Image
style={styles.headImage}
source={this.props.source}/>
<View style={{flex: 1, paddingRight: 10}}>
<View style={styles.rightTexts}>
<Text>{this.props.title}</Text>
<Text>{this.props.note}</Text>
</View>
<Text>{this.props.content}</Text>
</View>
</TouchableOpacity>
</Swipeable>
);
}
}
const styles = StyleSheet.create({
swipeContainer: {
flex: 1,
paddingLeft: 5,
flexDirection: 'row',
alignItems: 'center',
marginBottom: 5,
height: ITEM_HEIGHT,
backgroundColor: '#FFF'
},
buttonStyle1: {
// flex:1,
width: 75,
backgroundColor: '#ff7687',
height: ITEM_HEIGHT,
justifyContent: 'center',
alignItems: 'center',
},
buttonStyle2: {
// flex:1,
width: 75,
backgroundColor: '#b9ffb4',
height: ITEM_HEIGHT,
justifyContent: 'center',
alignItems: 'center',
},
headImage: {
marginRight: 5,
},
rightTexts: {
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'center'
}
}
后面这部分看不太懂
// app/navigation/index.js
import { createSwitchNavigator, createAppContainer } from 'react-navigation';
import AppStackNavigator from './AppStackNavigator';
import SplashScreen from '../views/SplashScreen';
import Login from '../views/login/Login';
const routeConfigMap = {
SplashScreen,
App: AppStackNavigator,
Login,
};
const switchConfig = {
headerMode: 'none',
initialRouteName: 'SplashScreen',
};
const AppNavigator = createSwitchNavigator(routeConfigMap, switchConfig);
export default createAppContainer(AppNavigator);
//app/navigation/AppStackNavigator.js
import {createStackNavigator} from 'react-navigation';
// 首页
import HomePage from '../views/home/HomePage';
const routeConfigMap = {
HomePage: HomePage,
};
const stackConfig = {
headerMode: 'none',
initialRouteName: 'HomePage',
};
const AppStackNavigator = createStackNavigator(routeConfigMap, stackConfig);
export default AppStackNavigator;
//app/navigation/NavigationService.js
import { NavigationActions } from 'react-navigation';
let _navigator;
function setNavigator(navigator) {
_navigator = navigator;
}
function navigate(routeName, params) {
_navigator.dispatch(
NavigationActions.navigate({
routeName,
params,
})
);
}
export default {
navigate,
setNavigator,
};
未完,待续。。。我还差很远~