【水滴石穿】imooc_gp

这个项目应该是一个标杆项目,看到之前很有几个项目都是按照这个项目的页面摆放顺序来的
不过可以作为自己做项目的一种方式
源码地址为:https://github.com/pgg-pgg/imooc_gp
项目的数据流是mobx
启动页不是定时器自动跳转那种,而是滑动那种
我们分析代码如下



上面是启动页的

//index.js
/** @format */

import {AppRegistry} from 'react-native';
import setup from "./js/pages/setup"
import {name as appName} from './app.json';

AppRegistry.registerComponent(appName, () => setup);
//js/pages/setup.js
/**
 * Sample React Native App
 * https://github.com/facebook/react-native
 *
 * @format
 * @flow
 */

import React, {Component} from 'react';
import {Navigator} from 'react-native-deprecated-custom-components'
import MobxTest from "../MobxTest";
import MyPageTest from "./My/MyPageTest";
import WelcomePage from "./WelcomePage";

function setup() {
    //进行一些初始化的配置
    class Root extends Component {
        renderScene(route, navigator) {
            let Component = route.component;
            return <Component {...route.params} navigator={navigator}/>
        }

        render() {
            return <Navigator
                initialRoute={{component: WelcomePage}}
                renderScene={(route, navigator)=>this.renderScene(route, navigator)}
            />
        }
    }
    return <Root/>;
}

module.exports = setup;

首先进入的是welcomePage页面

//js/pages/WelcomePage.js
import React, {Component} from 'react';
import {
    Platform,
    StyleSheet,
    Image,
    Text,
    View, AsyncStorage,
} from 'react-native';
import NavigationBar from "../common/NavigationBar"
import HomePage from "./HomePage"
import GuidePage from "./GuidePage";
import ThemeDao from "../expand/dao/ThemeDao";
import SplashScreen from 'react-native-splash-screen'
export default class WelcomePage extends Component{

    openApp(){
        //进行了判断是不是第一次打开
        AsyncStorage.getItem('isFirst',(error,result)=>{

            if (result === 'false') {
                console.log('不是第一次打开');

                this.props.navigator.resetTo({
                        //不是第一次打开就是进入home页面
                    component:HomePage,
                    params:{
                        theme:this.theme,
                        ...this.props
                    }
                })

            } else  {
                console.log('第一次打开');
                //是第一次打开就进入导航页
                this.props.navigator.replace({
                    component:GuidePage,
                    params:{
                        theme:this.theme,
                        ...this.props
                    }
                })
            }
        });
    }
    componentDidMount(): void {
        new ThemeDao().getTheme().then(data=>{
            this.theme = data;
        })
        this.timer = setTimeout(()=>{
            SplashScreen.hide();
            this.openApp()
        },1000)
    }

    componentWillUnmount(): void {
        this.timer&&clearTimeout(this.timer);
    }

    constructor(props){
        super(props)
    }

    render(){
        return null;
    }
}

第一次打开进入的导航页面

//GuidePage
import {StyleSheet, View, Button, Text, Image, TouchableOpacity,AsyncStorage} from 'react-native';
import React, {Component} from 'react';
import {PagerTabIndicator, IndicatorViewPager, PagerTitleIndicator, PagerDotIndicator} from 'rn-viewpager';
import HomePage from "./HomePage";

export default class GuidePage extends Component {
    render() {
        let text1 = '消费者第一\n合作伙伴第二\nQunar第三';
        let text2 = '大声说话\n无\'总\'称谓\n遇到批评三不问';
        let text3 = '高层不诿过\n中层不放羊\n基层不跳步';

        return (
            <View style={{flex: 1}}>
                <IndicatorViewPager
                    style={{flex: 1}}
                    indicator={GuidePage._renderDotIndicator()}>
                    <View style={{backgroundColor: '#ff8800', justifyContent: 'center'}}>
                        <Image resizeMode={'contain'} style={styles.image}
                               source={require('../../res/images/s_0_1.png')}/>
                        <Text style={styles.text_desc}>{text1}</Text>
                    </View>
                    <View style={{backgroundColor: '#669900', justifyContent: 'center'}}>
                        <Image resizeMode={'contain'} style={styles.image}
                               source={require('../../res/images/s_1_1.png')}/>
                        <Text style={styles.text_desc}>{text2}</Text>
                    </View>
                    <View style={{backgroundColor: '#aa66cc', justifyContent: 'center'}}>
                        <Image resizeMode={'contain'} style={styles.image}
                               source={require('../../res/images/s_2_1.png')}/>
                        <Text style={styles.text_desc}>{text3}</Text>
                        <TouchableOpacity onPress={()=>{
                            // 存储
                            AsyncStorage.setItem('isFirst','false',(error)=>{
                                if (error) {
                                    alert(error);
                                }
                            });
                            this.props.navigator.resetTo({
                                component:HomePage,
                                params:{
                                    // theme:this.props.theme,
                                    ...this.props
                                }
                            })
                        }}>
                            <Text style={styles.text}>开始使用</Text>
                        </TouchableOpacity>
                    </View>
                </IndicatorViewPager>
            </View>
        );
    }


    static _renderDotIndicator() {
        return <PagerDotIndicator pageCount={3}/>;
    }

}

const styles = StyleSheet.create({
    text: {
        alignSelf: 'center',
        padding: 5,
        backgroundColor: '#2196f3',
        borderRadius: 5,
        fontSize: 18,
        color: 'white',

    },
    text_desc: {
        height:200,
        textAlign: 'center',
        textAlignVertical:'center',
        fontSize: 20,
        color: 'white',
        alignSelf: 'center',
    },
    image: {
        width: 200,
        height: 200,
        alignSelf: 'center'
    },
    btn: {
        width: 150,
        height: 40,
        backgroundColor: '#1296db',
        borderRadius: 8,
        justifyContent: 'center',
        alignItems: 'center',
        marginBottom: 50

    },
    btnText: {
        fontSize: 18,
        color: '#fff'
    },

});

//js/pages/HomePage.js
//里面的tab切换,根据选中的跳转进去不同的页面
/**
 * Sample React Native App
 * https://github.com/facebook/react-native
 *
 * @format
 * @flow
 */

import React, {Component} from 'react';
import {
    Platform,
    StyleSheet,
    Image,
    Text,
    View,
    DeviceEventEmitter,


} from 'react-native';
import TabNavigator from 'react-native-tab-navigator'
import PopularPage from "./popular/PopularPage";
import Toast ,{DURATION}from "react-native-easy-toast";
import TrendingPage from "./trending/TrendingPage";
import FavoritePage from "./favorite/FavoritePage";
import MyPage from "./My/MyPage";
import BaseComponent from "./BaseComponent";
import codePush from "react-native-code-push";


export const ACTION_HOME = {A_SHOW_TOAST:'showToast',A_RESTART:'restart',A_THEME:'THEME'};
export const FLAG_TAB={
    flag_popularTab:'tb_popular',
    flag_trendingTab:'tb_trending',
    flag_favoriteTab:'tb_favorite',
    flag_myTab:'tb_my',
}
export default class HomePage extends BaseComponent {
    constructor(props) {
        super(props);
        let selectedTab=this.props.selectedTab?this.props.selectedTab:'tb_popular';
        this.state = {
            selectedTab: selectedTab,
            theme:this.props.theme,
        }
    }

    componentDidMount(): void {
        super.componentDidMount();
        this.listener = DeviceEventEmitter.
        addListener('ACTION_HOME',
            (action,params)=>this.onAction(action,params));
        this.update();
    }

    /**
     * 想codepush检查更新
     */
    update(){
        codePush.sync({
            updateDialog:{
                appendReleaseDescription:true,
                descriptionPrefix:'更新内容',
                title:'更新',
                mandatoryUpdateMessage:'',
                mandatoryContinueButtonLabel:'更新',
            },
            mandatoryInstallMode:codePush.InstallMode.ON_NEXT_RESTART,
        });
    }

    /**
     * 通知回调事件处理
     * @param action
     * @param params
     */
    onAction(action,params){
        if(ACTION_HOME.A_RESTART===action){
            this.onRestart(params)
        }else if(ACTION_HOME.A_SHOW_TOAST===action){
            this.toast.show(params.text,DURATION.LENGTH_SHORT);
        }
    }

    /**
     * 重启首页
     * @param jumpToTab
     */
    onRestart(jumpToTab){
        this.props.navigator.resetTo({
            component:HomePage,
            params:{
                ...this.props,
                selectedTab:jumpToTab
            }
        })
    }
    componentWillUnmount(): void {
        super.componentWillUnmount();
        if (this.listener) {
            this.listener.remove();
        }
    }
    _renderType(Component,selectTab,title,renderIcon){
        return  <TabNavigator.Item
            selected={this.state.selectedTab === selectTab}
            selectedTitleStyle={this.state.theme.styles.selectedTitleStyle}
            title={title}
            renderIcon={() => <Image style={styles.image} source={renderIcon}/>}
            renderSelectedIcon={() => <Image style={[styles.image,this.state.theme.styles.tabBarSelectedIcon]} source={renderIcon}/>}
            // badgeText="1"
            onPress={() => this.setState({selectedTab: selectTab})}>
            <View style={styles.page1}>
                <Component {...this.props} theme={this.state.theme}/>
            </View>
        </TabNavigator.Item>
    }

    render() {
        return (
            // tab切换
            <View style={styles.container}>
                <TabNavigator>
                    {this._renderType(PopularPage,'tb_popular','最热',require('../../res/images/ic_polular.png'))}
                    {this._renderType(TrendingPage,'tb_trending','趋势',require('../../res/images/ic_trending.png'))}
                    {this._renderType(FavoritePage,'tb_favorite','收藏',require('../../res/images/ic_favorite.png'))}
                    {this._renderType(MyPage,'tb_my','我的',require('../../res/images/ic_my.png'))}
                </TabNavigator>
                <Toast ref={toast=>this.toast=toast}/>
            </View>
        );
    }
}

const styles = StyleSheet.create({
    container: {
        flex: 1,
        backgroundColor: '#F5FCFF',
    },
    page1:{
        flex: 1,
    },
    page2:{
        flex: 2,
        backgroundColor: 'green'
    },
    image:{
        width:22,
        height:22
    }
});
//其实挺有意思的

tab首先的页面

应该只是布局,然后从后端请求数据渲染即可
代码如下:

//js/pages/popular/PopularPage.js
import React, {Component} from 'react';
import {
    Image,
    StyleSheet, TouchableOpacity,
    View,
} from 'react-native';
import NavigationBar from "../../common/NavigationBar";
import ScrollableTabView, {ScrollableTabBar} from 'react-native-scrollable-tab-view'
import LanguageDao, {FLAG_LANGUAGE} from '../../expand/dao/LanguageDao'
import PopularTab from "./PopularTab";
import ViewUtils from "../../util/ViewUtils";
import SearchPage from "../SearchPage";
import {MORE_MENU} from "../../common/MoreMenu";
import {FLAG_TAB} from "../HomePage";
import MoreMenu from "../../common/MoreMenu";
import BaseComponent from "../BaseComponent";
import CustomTheme from "../My/CustomTheme";

export default class PopularPage extends BaseComponent {

    constructor(props) {
        super(props);
        this.languageDao = new LanguageDao(FLAG_LANGUAGE.flag_key);
        this.state = {
            languages: [],
            customThemeViewVisible: false,
            theme:this.props.theme,
        }
    }

    componentDidMount() {
        super.componentDidMount()
        //渲染数据
        this.loadData();
    }

    loadData() {
        //取出数据
        this.languageDao.fetch()
            .then(result => {
                this.setState({
                    languages: result
                })
            }).catch(error => {
            console.log(error)
        })
    }
//点击不同的语言界面,最后是进入不同的语言列表新闻中

    renderRightButton() {
        return <View style={{flexDirection:'row'}}>
            <TouchableOpacity
                onPress={()=> {
                    this.props.navigator.push({
                        component:SearchPage,
                        params:{
                            ...this.props
                        }
                    })
                }}>
                <View style={{padding:5,marginRight:8}}>
                    <Image
                        style={{width:24,height:24}}
                        source={require('../../../res/images/ic_search_white_48pt.png')}
                    />
                </View>

            </TouchableOpacity>
            {ViewUtils.getMoreButton(()=>this.refs.moreMenu.open())}
        </View>
    }

    renderMoreView(){
        let params={...this.props,fromPage:FLAG_TAB.flag_popularTab};
        return <MoreMenu
            ref="moreMenu"
            {...params}
            menus={[MORE_MENU.Custom_Key,MORE_MENU.Sort_Key,MORE_MENU.Remove_Key,MORE_MENU.Share,MORE_MENU.Custom_Theme,
                MORE_MENU.About_Author,MORE_MENU.About]}
            anchorView={()=>this.refs.moreMenuButton}
            onMoreMenuSelect={(e)=> {
                if (e === MORE_MENU.Custom_Theme) {
                    this.setState({
                        customThemeViewVisible:true
                    })
                }
            }}
        />
    }

    renderCustomThemeView() {
        return (
            <CustomTheme visible={this.state.customThemeViewVisible}
                         {...this.props}
                         onClose={() => {
                             this.setState({
                                 customThemeViewVisible: false,
                             })
                         }}/>
        )
    }

    render() {
        let statusBar = {
            backgroundColor:this.state.theme.themeColor,
            barStyle:'light-content',
        };
        //判断语言切换的,这边用到的是ScrollableTabView组件
        let content = this.state.languages.length > 0 ? <ScrollableTabView
            tabBarBackgroundColor={this.state.theme.themeColor}
            tabBarActiveTextColor='#fff'
            tabBarInactiveTextColor='#333'
            tabBarUnderlineStyle={{backgroundColor: '#e7e7e7', height: 2}}
            renderTabBar={() => <ScrollableTabBar/>}>
            {this.state.languages.map((result, i, arr) => {
                let lan = arr[i];
                return lan.checked ?
                    <PopularTab key={i} tabLabel={lan.name} {...this.props}/>: null;
            })}
        </ScrollableTabView> : null;
        //底部图标切换
        return <View style={styles.container}>
            <NavigationBar
                title={'最热'}
                leftButton={<View/>}
                rightButton={this.renderRightButton()}
                statusBar={statusBar}
                style={this.state.theme.styles.navBar}/>
            {content}
            {this.renderMoreView()}
            {this.renderCustomThemeView()}
        </View>
    }
}

const styles = StyleSheet.create({
    container: {
        flex: 1,
        backgroundColor: '#F5FCFF',
    },

});
//js/pages/popular/PopularTab.js
//下拉刷新和获取数据
import React, {Component} from 'react';
import {DeviceEventEmitter, ListView, RefreshControl, StyleSheet, View} from "react-native";
import ProjectModel from "../../model/ProjectModel";
import Utils from "../../util/Utils";
import DescPage from "./DescPage";
import {FLAG_STORAGE} from "../../expand/dao/DataRepository";
import RepositoryCell from "../../common/RepositoryCell";
import FavoriteDao from "../../expand/dao/FavoriteDao";
import DataRepository from "../../expand/dao/DataRepository";
import ActionUtils from "../../util/ActionUtils";

const URL = "https://api.github.com/search/repositories?q=";
const QUERY_STR = '&sort=stars';
const favoriteDao = new FavoriteDao(FLAG_STORAGE.flag_popular);
const dataRepository = new DataRepository(FLAG_STORAGE.flag_popular);

export default class PopularTab extends Component {
    constructor(props) {
        super(props);
        this.isFavoriteChange=false;
        this.state = {
            result: '',
            isLoading: false,
            dataSource: new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2}),
            favoriteKeys :[],
            theme:this.props.theme,
        }
    }

    componentDidMount(): void {
        this.onLoad();
        this.listener= DeviceEventEmitter.addListener('favoriteChanged_popular',()=>{
            this.isFavoriteChange = true;
        })
    }

    componentWillUnmount(): void {
        if (this.listener){
            this.listener.remove();
        }
    }

    componentWillReceiveProps(nextProps: Readonly<P>, nextContext: any): void {
        if (this.isFavoriteChange) {
            this.isFavoriteChange=false;
            this.getFavoriteKeys()
        }else if (nextProps.theme !== this.state.theme) {
            this.updateState({
                theme:nextProps.theme,
            })
            this.flushFavoriteState()
        }
    }


    /**
     * 更新project item收藏状态
     */
    flushFavoriteState(){
        let projectModels = [];
        let items = this.items;
        for(let i =0 ,len = items.length;i<len;i++){
            projectModels.push(new ProjectModel(items[i],Utils.checkFavorite(items[i],this.state.favoriteKeys)))
        }
        this.updateState({
            isLoading:false,
            dataSource:this.getDataSource(projectModels),
        })
    }


    getDataSource(data){
        return this.state.dataSource.cloneWithRows(data);
    }

    getFavoriteKeys(){
        favoriteDao.getFavoriteKeys()
            .then(keys=>{
                if (keys) {
                    this.updateState({
                        favoriteKeys: keys
                    })
                }
                this.flushFavoriteState();
            })
            .catch(e=>{
                this.flushFavoriteState()
            })
    }

    updateState(dic){
        if (!this) return;
        this.setState(dic);
    }

    onLoad() {
        this.updateState({
            isLoading: true
        });
        let url = URL + this.props.tabLabel + QUERY_STR;
        dataRepository.fetchRepository(url)
            .then(result => {
                this.items = result && result.items ? result.items : result ? result : [];
                this.getFavoriteKeys();
                if (!this.items||result && result.update_date && !dataRepository.checkData(result.update_date)) {
                    return dataRepository.fetchNetRepository(url)
                }
            })
            .then(items => {
                if (!items || items.length === 0) {
                    return;
                } else {
                    this.items=items;
                    this.getFavoriteKeys()
                }
            })
            .catch(error => {
                console.log(error);
                this.updateState({
                    isLoading:false,
                })
            });
    }

    choose(projectModel) {
        return <RepositoryCell
            onSelect={()=>ActionUtils.onSelectRepository({
                flag: FLAG_STORAGE.flag_popular,
                ...this.props,
                projectModel: projectModel,
            })}
            theme={this.state.theme}
            key={projectModel.item.id}
            onFavorite={(item,isFavorite)=>ActionUtils.onFavorite(favoriteDao,item, isFavorite)}
            projectModel={projectModel}/>
    }

    render() {
        return <View style={styles.container}>
            <ListView
                dataSource={this.state.dataSource}
                renderRow={(data) => this.choose(data)}
                refreshControl={
                    <RefreshControl
                        refreshing={this.state.isLoading}
                        onRefresh={() => this.onLoad()}
                        color={this.state.theme.themeColor}
                        tintColor={this.state.theme.themeColor}
                        title={'Loading...'}
                        titleColor={this.state.theme.themeColor}
                    />
                }

            />
        </View>
    }

}

const styles = StyleSheet.create({
    container: {
        flex: 1,
        backgroundColor: '#F5FCFF',
    },
    page1: {
        flex: 1,
        backgroundColor: 'red'
    },
    page2: {
        flex: 2,
        backgroundColor: 'green'
    },
    image: {
        width: 22,
        height: 22
    },
    item: {
        backgroundColor: '#169',
        height: 100,
        margin: 15,
        alignItems: 'center',
        justifyContent: 'center',
    },
    text_my: {
        color: 'black',
        fontSize: 20,
    },
    text: {
        color: 'white',
        fontSize: 20,
    },
    indicatorContainer: {
        alignItems: 'center'
    },
    indicator: {
        color: 'red',
        margin: 10
    }
});
//js/pages/popular/store/Store.js
import {observable} from "mobx";
import DataRepository from "../../../expand/dao/DataRepository";

export default class PopularStore {
    api;

    @observable popularItems=[];

    constructor(){
        this.api=new DataRepository();
    }

    getPopularItem(id){
        return this.popularItems.find(item=>item.id.toString()===id);
    }


    @action.bound()
    fetchPopularList(tabLabel){
        return this.api.getPopularInfo(tabLabel)
            .then(action(result => {
                this.items = result && result.items ? result.items : result ? result : [];
                this.getFavoriteKeys();
                if (!this.items||result && result.update_date && !dataRepository.checkData(result.update_date)) {
                    return dataRepository.fetchNetRepository(url)
                }
            })
            .then(items => {
                if (!items || items.length === 0) {
                    return;
                } else {
                    this.items=items;
                    this.getFavoriteKeys()
                }
            })
            .catch(error => {
                console.log(error);
                this.updateState({
                    isLoading:false,
                })
            }));
    }

}
//js/pages/popular/model/ProjectModel.js
import {observable} from "mobx";

export default class ProjectModel{
    @observable item;
    @observable isFavorite;
}
//js/pages/popular/DescPage.js
import React, {Component} from 'react'
import {
    View,
    StyleSheet,
    WebView,
    TouchableOpacity,
    Image,

} from 'react-native'
import NavigationBar from "../../common/NavigationBar";
import ViewUtils from "../../util/ViewUtils";
import FavoriteDao from "../../expand/dao/FavoriteDao";
import share from "../../../res/data/share";
import UShare from "../../common/UShare";
import BackPressComponent from "../../common/BackPressComponent";

const TRENDING_URL = 'https://github.com/';
export default class DescPage extends Component {
    constructor(props) {
        super(props);
        // alert(this.props.title);
        this.backPress = new BackPressComponent({backPress:(e)=>this.onBackPress(e)});
        this.url = this.props.projectModel.item.html_url ? this.props.projectModel.item.html_url : TRENDING_URL + this.props.projectModel.item.fullName;
        let title = this.props.projectModel.item.full_name ? this.props.projectModel.item.full_name : this.props.projectModel.item.fullName;
        this.favoriteDao = new FavoriteDao(this.props.flag);
        this.state = {
            url: this.url,
            title: title,
            canGoBack: false,
            isFavorite: this.props.projectModel.isFavorite,
            favoriteIcon: this.props.projectModel.isFavorite ? require('../../../res/images/ic_star.png')
                : require('../../../res/images/ic_star_navbar.png'),
            theme: this.props.theme,
        }
    }
    componentDidMount(): void {
        this.backPress.componentDidMount();
    }

    componentWillUnmount(): void {
        this.backPress.componentWillUnmount();
        if (this.props.onUpdateFavorite)this.props.onUpdateFavorite();
    }

    onBack() {
        if (this.state.canGoBack) {
            this.webView.goBack()
        } else {
            this.props.navigator.pop();
        }

    }

    onBackPress(e){
        this.onBack();
        return true;
    }

    go() {
        this.setState({
            url: this.text
        })
    }

    onNavigationStateChange(e) {
        this.setState({
            canGoBack: e.canGoBack,
            url: e.url,
        })
    }

    onRightButtonClick() {
        let projectModel = this.props.projectModel;
        this.setFavoriteState(projectModel.isFavorite = !projectModel.isFavorite);
        const key = projectModel.item.fullName ? projectModel.item.fullName : projectModel.item.id.toString();
        if (projectModel.isFavorite) {
            this.favoriteDao.saveFavoriteItem(key, JSON.stringify(projectModel.item))
        } else {
            this.favoriteDao.removeFavoriteItem(key)
        }
    }

    setFavoriteState(isFavorite) {
        this.setState({
            isFavorite: isFavorite,
            favoriteIcon: isFavorite ? require('../../../res/images/ic_star.png')
                : require('../../../res/images/ic_star_navbar.png')
        })
    }

    renderRightButton() {
        return <View style={{flexDirection: 'row'}}>
            {ViewUtils.getShareButton(()=>this.shareInfo())}
            <TouchableOpacity onPress={() => this.onRightButtonClick()}>
                <Image style={{width: 20, height: 20, marginRight: 10}} source={this.state.favoriteIcon}/>
            </TouchableOpacity>
        </View>
    }

    shareInfo(){
        const shareApp = share.share_app;
        UShare.share(shareApp.title, shareApp.content,
            shareApp.imgUrl,shareApp.url,()=>{},()=>{});
    }

    render() {
        let statusBar = {
            backgroundColor: this.state.theme.themeColor
        };
        let titleLayoutStyle = this.state.title.length>20?{paddingRight: 30}:null;
        return <View style={styles.container}>
            <NavigationBar
                title={this.state.title}
                statusBar={statusBar}
                titleLayoutStyle={titleLayoutStyle}
                style={this.state.theme.styles.navBar}
                rightButton={this.renderRightButton()}
                leftButton={ViewUtils.getLeftButton(() => this.onBack())}
            />
            <WebView ref={webView => this.webView = webView}
                     source={{uri: this.state.url}}
                     startInLoadingState={true}
                     onNavigationStateChange={(e) =>
                         this.onNavigationStateChange(e)}>
            </WebView>
        </View>
    }

}

const styles = StyleSheet.create({
    container: {
        flex: 1
    },
    tips: {
        fontSize: 20
    },
    row: {
        flexDirection: 'row',
        alignItems: 'center',
        margin: 10
    },
    input: {
        height: 40,
        flex: 1,
        borderWidth: 1,
        margin: 2,
    }
});

趋势页面跟最热页面类似

//js/pages/trending/TrendingPage.js
import React, {Component} from 'react';
import {
    Platform,
    StyleSheet,
    Image,
    Text,
    View,
    TextInput,
    ListView,
    RefreshControl,
    DeviceEventEmitter,
    TouchableOpacity,
} from 'react-native';
import NavigationBar from "../../common/NavigationBar"
import DataRepository, {FLAG_STORAGE} from "../../expand/dao/DataRepository"
import ScrollableTabView, {ScrollableTabBar} from 'react-native-scrollable-tab-view'
import RepositoryCell from "../../common/RepositoryCell";
import LanguageDao, {FLAG_LANGUAGE} from '../../expand/dao/LanguageDao'
import DescPage from "../popular/DescPage";
import TrendingCell from "../../common/TrendingCell";
import TimeSpan from "../../model/TimeSpan";
import Popover from "../../common/Popover";
import FavoriteDao from "../../expand/dao/FavoriteDao";
import ProjectModel from "../../model/ProjectModel";
import Utils from "../../util/Utils";
import ActionUtils from "../../util/ActionUtils";
import {FLAG_TAB} from "../HomePage";
import MoreMenu, {MORE_MENU} from "../../common/MoreMenu";
import ViewUtils from "../../util/ViewUtils";
import BaseComponent from "../BaseComponent";
import CustomTheme from "../My/CustomTheme";

const API_URL = "https://github.com/trending/";
var timeSpanTextArray = [new TimeSpan('今 天', 'since=daily'), new TimeSpan('本 周', 'since=weekly'), new TimeSpan('本 月', 'since=monthly')];
var favoriteDao = new FavoriteDao(FLAG_STORAGE.flag_trending);
var dataRespository = new DataRepository(FLAG_STORAGE.flag_trending);


export default class TrendingPage extends BaseComponent {

    constructor(props) {
        super(props);
        this.languageDao = new LanguageDao(FLAG_LANGUAGE.flag_language);
        this.state = {
            languages: [],
            isVisible: false,
            buttonRect: {},
            timeSpan: timeSpanTextArray[0],
            theme:this.props.theme,
            customThemeViewVisible: false,
        }
    }

    componentDidMount() {
        super.componentDidMount();
        this.loadData();
    }

    componentWillReceiveProps(nextProps: Readonly<P>, nextContext: any): void {
        if (nextProps.timeSpan !== this.props.timeSpan) {
            this.loadData(nextProps.timeSpan)
        }
    }

    loadData() {
        this.languageDao.fetch()
            .then(result => {
                this.setState({
                    languages: result
                })
            }).catch(error => {
            console.log(error)
        })
    }

    showPopover() {
        this.refs.button.measure((ox, oy, width, height, px, py) => {
            this.setState({
                isVisible: true,
                buttonRect: {x: px, y: py, width: width, height: height}
            });
        });
    }

    closePopover() {
        this.setState({
            isVisible: false,
        });
    }

    renderTitleView() {
        return <View>
            <TouchableOpacity ref={'button'} onPress={() => {
                this.showPopover()
            }}>
                <View style={{flexDirection: 'row', alignItems: 'center'}}>
                    <Text style={{
                        fontSize: 18,
                        color: 'white',
                        fontWeight: '400'
                    }}>趋势 {this.state.timeSpan.showText}</Text>
                    <Image style={{width: 12, height: 12, marginLeft: 5}}
                           source={require('../../../res/images/ic_spinner_triangle.png')}/>
                </View>
            </TouchableOpacity>
        </View>
    }

    onSelectTimeSpan(timeSpan) {
        this.setState({
            timeSpan: timeSpan,
            isVisible: false,
        })
    }

    renderMoreView() {
        let params = {...this.props, fromPage: FLAG_TAB.flag_popularTab};
        return <MoreMenu
            ref="moreMenu"
            {...params}
            menus={[MORE_MENU.Custom_Language, MORE_MENU.Sort_Language,MORE_MENU.Share, MORE_MENU.Custom_Theme,
                MORE_MENU.About_Author, MORE_MENU.About]}
            anchorView={() => this.refs.moreMenuButton}
            onMoreMenuSelect={(e) => {
                if (e === MORE_MENU.Custom_Theme) {
                    this.setState({
                        customThemeViewVisible: true
                    })
                }
            }}
        />
    }

    renderCustomThemeView() {
        return (
            <CustomTheme visible={this.state.customThemeViewVisible}
                         {...this.props}
                         onClose={() => {
                             this.setState({
                                 customThemeViewVisible: false,
                             })
                         }}/>
        )
    }

    render() {
        let statusBar = {
            backgroundColor:this.state.theme.themeColor
        };
        let content = this.state.languages.length > 0 ? <ScrollableTabView
            tabBarBackgroundColor={this.state.theme.themeColor}
            tabBarActiveTextColor='#fff'
            tabBarInactiveTextColor='#333'
            tabBarUnderlineStyle={{backgroundColor: '#e7e7e7', height: 2}}
            renderTabBar={() => <ScrollableTabBar/>}>
            {this.state.languages.map((result, i, arr) => {
                let lan = arr[i];
                return lan.checked ?
                    <TrendingTab key={i} tabLabel={lan.name}
                                 timeSpan={this.state.timeSpan} {...this.props}>{lan.name}</TrendingTab> : null;
            })}
        </ScrollableTabView> : null;
        let timeSpanView = <Popover
            isVisible={this.state.isVisible}
            fromRect={this.state.buttonRect}
            placement={'bottom'}
            contentStyle={{backgroundColor: '#343434', opacity: 0.5}}
            onClose={() => this.closePopover()}>
            {timeSpanTextArray.map((result, i, arr) => {
                return <TouchableOpacity key={i} underlayColor={'transparent'}
                                         onPress={() => this.onSelectTimeSpan(arr[i])}>
                    <Text style={{fontSize: 18, color: 'white', padding: 8, fontWeight: '400'}}>{arr[i].showText}</Text>
                </TouchableOpacity>
            })}
        </Popover>;
        return <View style={styles.container}>
            <NavigationBar
                titleView={this.renderTitleView()}
                leftButton={<View/>}
                rightButton={ViewUtils.getMoreButton(() => this.refs.moreMenu.open())}
                statusBar={statusBar}
                style={this.state.theme.styles.navBar}/>
            {content}
            {timeSpanView}
            {this.renderMoreView()}
            {this.renderCustomThemeView()}
        </View>
    }
}

class TrendingTab extends Component {
    constructor(props) {
        super(props);
        this.isFavoriteChange = false;
        this.state = {
            result: '',
            isLoading: false,
            dataSource: new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2}),
            favoriteKeys: [],
            theme:this.props.theme,
        }
    }


    /**
     * 更新project item收藏状态
     */
    flushFavoriteState() {
        let projectModels = [];
        let items = this.items;
        for (let i = 0, len = items.length; i < len; i++) {
            projectModels.push(new ProjectModel(items[i], Utils.checkFavorite(items[i], this.state.favoriteKeys)))
        }
        this.updateState({
            isLoading: false,
            dataSource: this.getDataSource(projectModels),
        })
    }

    getDataSource(data) {
        return this.state.dataSource.cloneWithRows(data);
    }

    getFavoriteKeys() {
        favoriteDao.getFavoriteKeys()
            .then(keys => {
                if (keys) {
                    this.updateState({
                        favoriteKeys: keys
                    })
                }
                this.flushFavoriteState();
            })
            .catch(e => {
                this.flushFavoriteState()
            })
    }

    updateState(dic) {
        if (!this) return;
        this.setState(dic);
    }

    componentDidMount(): void {
        this.onLoad(this.props.timeSpan, true)
        this.listener = DeviceEventEmitter.addListener('favoriteChanged_trending', () => {
            this.isFavoriteChange = true;
        })
    }

    onUpdateFavorite() {
        this.getFavoriteKeys();
    }

    componentWillUnmount(): void {
        if (this.listener) {
            this.listener.remove();
        }
    }

    componentWillReceiveProps(nextProps: Readonly<P>, nextContext: any): void {
        if (this.isFavoriteChange) {
            this.isFavoriteChange = false;
            this.getFavoriteKeys()
        }else if (nextProps.theme !== this.state.theme) {
            this.updateState({
                theme:nextProps.theme,
            });
            this.flushFavoriteState()
        }
    }

    getFetchUrl(timeSpan, category) {
        return API_URL + category + '?' + timeSpan.searchText
    }

    onLoad(timeSpan, isRefresh) {
        this.updateState({
            isLoading: true
        });

        let url = this.getFetchUrl(timeSpan, this.props.tabLabel)
        dataRespository.fetchRepository(url)
            .then(result => {
                this.items = result && result.items ? result.items : result ? result : [];
                this.getFavoriteKeys();
                if (!this.items || isRefresh && result && result.update_date && !dataRespository.checkData(result.update_date)) {
                    return dataRespository.fetchNetRepository(url)
                }
            })
            .then(items => {
                if (!items || items.length === 0) {
                    return;
                } else {
                    this.items = items;
                    this.getFavoriteKeys();
                }
            })
            .catch(error => {
                this.updateState({
                    isLoading: false
                })
            });
    }


    choose(projectModel) {
        return <TrendingCell
            onSelect={() => ActionUtils.onSelectRepository({
                projectModel: projectModel,
                flag: FLAG_STORAGE.flag_trending,
                ...this.props,
                parentComponent: this,
                onUpdateFavorite: ()=>this.onUpdateFavorite(),
            })}
            theme={this.props.theme}
            key={projectModel.item.fullName}
            onFavorite={(item, isFavorite) => ActionUtils.onFavorite(favoriteDao, item, isFavorite, FLAG_STORAGE.flag_trending)}
            projectModel={projectModel}/>
    }

    onRefresh() {
        this.onLoad(this.props.timeSpan, true);
    }


    render() {
        return <View style={styles.container}>
            <ListView
                dataSource={this.state.dataSource}
                renderRow={(data) => this.choose(data)}
                refreshControl={
                    <RefreshControl
                        refreshing={this.state.isLoading}
                        onRefresh={() => this.onRefresh()}
                        color={this.state.theme.themeColor}
                        tintColor={this.state.theme.themeColor}
                        title={'Loading...'}
                        titleColor={this.state.theme.themeColor}
                    />
                }

            />
        </View>
    }

}

const styles = StyleSheet.create({
    container: {
        flex: 1,
        backgroundColor: '#F5FCFF',
    },
    page1: {
        flex: 1,
        backgroundColor: 'red'
    },
    page2: {
        flex: 2,
        backgroundColor: 'green'
    },
    image: {
        width: 22,
        height: 22
    },
    item: {
        backgroundColor: '#169',
        height: 100,
        margin: 15,
        alignItems: 'center',
        justifyContent: 'center',
    },
    text_my: {
        color: 'black',
        fontSize: 20,
    },
    text: {
        color: 'white',
        fontSize: 20,
    },
    indicatorContainer: {
        alignItems: 'center'
    },
    indicator: {
        color: 'red',
        margin: 10
    }
});

//收藏页面
//js/pages/favorite/FavoritePage.js
import React, {Component} from 'react';
import {
    StyleSheet,
    View,
    ListView,
    RefreshControl,
    DeviceEventEmitter,
} from 'react-native';
import NavigationBar from "../../common/NavigationBar"
import {FLAG_STORAGE} from "../../expand/dao/DataRepository"
import ScrollableTabView, {ScrollableTabBar} from 'react-native-scrollable-tab-view'
import RepositoryCell from "../../common/RepositoryCell";
import DescPage from "../popular/DescPage";
import ProjectModel from "../../model/ProjectModel";
import FavoriteDao from "../../expand/dao/FavoriteDao";
import TrendingCell from "../../common/TrendingCell";
import ArrayUtils from "../../util/ArrayUtils";
import ActionUtils from "../../util/ActionUtils";
import MoreMenu, {MORE_MENU} from "../../common/MoreMenu";
import {FLAG_TAB} from "../HomePage";
import ViewUtils from "../../util/ViewUtils";
import BaseComponent from "../BaseComponent";
import CustomTheme from "../My/CustomTheme";

export default class FavoritePage extends BaseComponent {

    constructor(props) {
        super(props);
        this.state = {
            theme: this.props.theme,
            customThemeViewVisible: false,
        }
    }

    renderMoreView() {
        let params = {...this.props, fromPage: FLAG_TAB.flag_popularTab}
        return <MoreMenu
            ref="moreMenu"
            {...params}
            menus={[MORE_MENU.Custom_Theme, MORE_MENU.Share,
                MORE_MENU.About_Author, MORE_MENU.About]}
            anchorView={() => this.refs.moreMenuButton}
            onMoreMenuSelect={(e) => {
                if (e === MORE_MENU.Custom_Theme) {
                    this.setState({
                        customThemeViewVisible: true
                    })
                }
            }}
        />
    }

    renderCustomThemeView() {
        return (
            <CustomTheme visible={this.state.customThemeViewVisible}
                         {...this.props}
                         onClose={() => {
                             this.setState({
                                 customThemeViewVisible: false,
                             })
                         }}/>
        )
    }

    render() {
        let statusBar = {
            backgroundColor: this.state.theme.themeColor
        };
        let content = <ScrollableTabView
            tabBarBackgroundColor={this.state.theme.themeColor}
            tabBarActiveTextColor='#fff'
            tabBarInactiveTextColor='#333'
            tabBarUnderlineStyle={{backgroundColor: '#e7e7e7', height: 2}}
            renderTabBar={() => <ScrollableTabBar/>}
        >
            <FavoriteTab tabLabel='最热' flag={FLAG_STORAGE.flag_popular} {...this.props}/>
            <FavoriteTab tabLabel='趋势' flag={FLAG_STORAGE.flag_trending} {...this.props}/>
        </ScrollableTabView>
        return <View style={styles.container}>
            <NavigationBar
                title={'收藏'}
                leftButton={<View/>}
                rightButton={ViewUtils.getMoreButton(() => this.refs.moreMenu.open())}
                statusBar={statusBar}
                style={this.state.theme.styles.navBar}/>
            {content}
            {this.renderMoreView()}
            {this.renderCustomThemeView()}
        </View>
    }
}

class FavoriteTab extends Component {
    constructor(props) {
        super(props);
        this.unFavoriteItems = [];
        this.favoriteDao = new FavoriteDao(this.props.flag);
        this.state = {
            result: '',
            isLoading: false,
            dataSource: new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2}),
            favoriteKeys: [],
            theme: this.props.theme,
        }
    }

    componentDidMount(): void {
        this.onLoad(true)
    }

    componentWillReceiveProps(nextProps: Readonly<P>, nextContext: any): void {
        this.onLoad(false)
    }

    updateState(dic) {
        if (!this) return;
        this.setState(dic);
    }

    getDataSource(data) {
        return this.state.dataSource.cloneWithRows(data);
    }

    onLoad(isShowLoading) {
        if (isShowLoading) {
            this.updateState({
                isLoading: true
            });
        }
        this.favoriteDao.getAllItems()
            .then(items => {
                let resultData = [];
                for (let i = 0, len = items.length; i < len; i++) {
                    resultData.push(new ProjectModel(items[i], true));
                }
                this.updateState({
                    isLoading: false,
                    dataSource: this.getDataSource(resultData)
                })
            })
            .catch(e => {
                this.updateState({
                    isLoading: false
                })
            })
    }

    choose(projectModel) {
        let CellComponent = this.props.flag === FLAG_STORAGE.flag_popular ? RepositoryCell : TrendingCell;
        return <CellComponent
            onSelect={() => ActionUtils.onSelectRepository({
                flag: FLAG_STORAGE.flag_popular,
                ...this.props,
                projectModel: projectModel,
            })}
            theme={this.props.theme}
            key={this.props.flag === FLAG_STORAGE.flag_popular ? projectModel.item.id : projectModel.item.fullName}
            onFavorite={(item, isFavorite) => ActionUtils.onFavorite(this.favoriteDao, item, isFavorite, this.props.flag)}
            projectModel={projectModel}/>
    }

    render() {
        return <View style={styles.container}>
            <ListView
                dataSource={this.state.dataSource}
                renderRow={(data) => this.choose(data)}
                enableEmptySections={true}
                refreshControl={
                    <RefreshControl
                        refreshing={this.state.isLoading}
                        onRefresh={() => this.onLoad()}
                        color={this.state.theme.themeColor}
                        tintColor={this.state.theme.themeColor}
                        title={'Loading...'}
                        titleColor={this.state.theme.themeColor}
                    />
                }

            />
        </View>
    }

}

const styles = StyleSheet.create({
    container: {
        flex: 1,
        backgroundColor: '#F5FCFF',
    },
    page1: {
        flex: 1,
        backgroundColor: 'red'
    },
    page2: {
        flex: 2,
        backgroundColor: 'green'
    },
    image: {
        width: 22,
        height: 22
    },
    item: {
        backgroundColor: '#169',
        height: 100,
        margin: 15,
        alignItems: 'center',
        justifyContent: 'center',
    },
    text_my: {
        color: 'black',
        fontSize: 20,
    },
    text: {
        color: 'white',
        fontSize: 20,
    },
    indicatorContainer: {
        alignItems: 'center'
    },
    indicator: {
        color: 'red',
        margin: 10
    }
});

//js/pages/My/MyPage.js
import React, {Component} from 'react';
import {
    StyleSheet,
    Text,
    View,
    ScrollView,
    TouchableHighlight,
    Image,
} from 'react-native';
import NavigationBar from "../../common/NavigationBar";
import GlobalStyles from "../../../res/styles/GlobalStyles"
import ViewUtils from "../../util/ViewUtils";
import CustomKeyPage from "./CustomKeyPage";
import {FLAG_LANGUAGE} from "../../expand/dao/LanguageDao";
import SortKeyPage from "./SortKeyPage";
import AboutMePage from "./about/AboutMePage";
import AboutPage from "./about/AboutPage";
import {MORE_MENU} from "../../common/MoreMenu";
import CustomTheme from "./CustomTheme";
import BaseComponent from "../BaseComponent";
import codePush from "react-native-code-push";

export default class MyPage extends BaseComponent {
    constructor(props) {
        super(props);
        this.state = {
            customThemeViewVisible: false,
            theme:this.props.theme,
        }
    }

    onClick(tab) {
        let TargetComponent, params = {...this.props, menuType: tab};
        switch (tab) {
            case MORE_MENU.Custom_Language:
                TargetComponent = CustomKeyPage;
                params.flag = FLAG_LANGUAGE.flag_language;
                break;
            case MORE_MENU.Custom_Key:
                TargetComponent = CustomKeyPage;
                params.flag = FLAG_LANGUAGE.flag_key;
                break;
            case MORE_MENU.Remove_Key:
                TargetComponent = CustomKeyPage;
                params.flag = FLAG_LANGUAGE.flag_key;
                params.isRemoveKey = true;
                break;
            case MORE_MENU.Sort_Language:
                TargetComponent = SortKeyPage;
                params.flag = FLAG_LANGUAGE.flag_language;
                break;
            case MORE_MENU.Sort_Key:
                TargetComponent = SortKeyPage;
                params.flag = FLAG_LANGUAGE.flag_key;
                break;
            case MORE_MENU.Custom_Theme:
                this.setState({customThemeViewVisible: true});
                break;
            case MORE_MENU.About_Author:
                TargetComponent = AboutMePage;
                break;
            case MORE_MENU.About:
                TargetComponent = AboutPage;
                break;
            case '更新':
                // this.update();
                break;

        }

        if (TargetComponent) {
            this.props.navigator.push({
                component: TargetComponent,
                params: params,
            });
        }
    }


    getItem(tag, icon, text) {
        return ViewUtils.getSettingItem(() => this.onClick(tag), icon, text, this.state.theme.styles.tabBarSelectedIcon, null);
    }


    renderCustomThemeView() {
        return (
            <CustomTheme visible={this.state.customThemeViewVisible}
                         {...this.props}
                         onClose={() => {
                             this.setState({
                                 customThemeViewVisible: false,
                             })
                         }}/>
        )
    }

    render() {

        let statusBar = {
            backgroundColor:this.state.theme.themeColor
        };
        let navigatorBar = <NavigationBar title={'我的'}
                                          statusBar={statusBar}
                                          style={this.state.theme.styles.navBar}/>;
        return <View style={GlobalStyles.root_container}>
            {navigatorBar}
            <ScrollView>
                {/*最热管理*/}
                <TouchableHighlight onPress={() => this.onClick(MORE_MENU.About)}>
                    <View style={[styles.item, {height: 90}]}>
                        <View style={{flexDirection: 'row', alignItems: 'center'}}>
                            <Image source={require('../../../res/images/ic_trending.png')}
                                   style={[{width: 40, height: 40, marginRight: 10}, this.state.theme.styles.tabBarSelectedIcon]}/>

                            <Text>Github Popular</Text>
                        </View>
                        <Image style={[{marginRight: 10, height: 22, width: 22,}, this.state.theme.styles.tabBarSelectedIcon]}
                               source={require('../../../res/images/ic_tiaozhuan.png')}/>
                    </View>
                </TouchableHighlight>
                <View style={GlobalStyles.line}/>
                {/*趋势管理*/}
                <Text style={styles.groupTitle}>趋势管理</Text>
                <View style={GlobalStyles.line}/>
                {/*自定义语言*/}
                {this.getItem(MORE_MENU.Custom_Language, require('./img/ic_custom_language.png'), '自定义语言')}
                <View style={GlobalStyles.line}/>
                {/*语言排序*/}
                {this.getItem(MORE_MENU.Sort_Language, require('./img/ic_sort.png'), '语言排序')}
                <View style={GlobalStyles.line}/>

                {/*标签管理*/}
                <Text style={styles.groupTitle}>标签管理</Text>
                <View style={GlobalStyles.line}/>
                {/*自定义标签*/}
                {this.getItem(MORE_MENU.Custom_Key, require('./img/ic_custom_language.png'), '自定义标签')}
                <View style={GlobalStyles.line}/>
                {/*标签排序*/}
                {this.getItem(MORE_MENU.Sort_Key, require('./img/ic_swap_vert.png'), '标签排序')}
                <View style={GlobalStyles.line}/>
                {/*标签移除*/}
                {this.getItem(MORE_MENU.Remove_Key, require('./img/ic_remove.png'), '标签移除')}
                <View style={GlobalStyles.line}/>
                {/*设置*/}
                <Text style={styles.groupTitle}>设置</Text>
                <View style={GlobalStyles.line}/>
                {this.getItem(MORE_MENU.Custom_Theme, require('./img/ic_custom_theme.png'), '自定义主题')}
                <View style={GlobalStyles.line}/>
                {this.getItem(MORE_MENU.About_Author, require('./img/ic_insert_emoticon.png'), '关于作者')}
                <View style={GlobalStyles.line}/>

            </ScrollView>

            {this.renderCustomThemeView()}
        </View>
    }
}

const styles = StyleSheet.create({
    container: {
        flex: 1,
        backgroundColor: '#F5FCFF',
    },
    item: {
        flexDirection: 'row',
        justifyContent: 'space-between',
        alignItems: 'center',
        padding: 10,
        height: 60,
        backgroundColor: 'white',
    },
    groupTitle: {
        marginLeft: 10,
        marginTop: 10,
        marginBottom: 5,
        fontSize: 12,
        color: 'gray',

    }
});
//js/pages/My/CustomTheme.js
import React, {Component} from 'react';
import {
    StyleSheet,
    Text,
    View,
    ScrollView,
    TouchableHighlight,
    Image,
    Platform,
    DeviceEventEmitter,
    Modal,
} from 'react-native';

import GlobalStyles from "../../../res/styles/GlobalStyles"
import ThemeFactory,{ThemeFlags} from "../../../res/styles/ThemeFactory"
import ThemeDao from "../../expand/dao/ThemeDao";
import {ACTION_HOME} from "../HomePage";

export default class CustomTheme extends Component {
    constructor(props) {
        super(props);
        this.themeDao = new ThemeDao();
    }


    onSelectTheme(themeKey){
        this.props.onClose();
        this.themeDao.save(ThemeFlags[themeKey]);
        DeviceEventEmitter.emit('ACTION_BASE',ACTION_HOME.A_THEME,ThemeFactory.createTheme(
            ThemeFlags[themeKey]
        ))
    }

    getThemeItem(themeKey){
        return <TouchableHighlight underlayColor={'white'} onPress={()=>this.onSelectTheme(themeKey)} style={{flex: 1}}>
            <View style={[{backgroundColor: ThemeFlags[themeKey]},styles.themeItem]}>
                <Text style={styles.themeText}>{themeKey}</Text>
            </View>
        </TouchableHighlight>
    }

    /**
     * 创建主题列表
     * @returns {Array}
     */
    renderThemeItems(){
        const views = [];
        for (let i=0,keys=Object.keys(ThemeFlags),l=keys.length;i<l;i+=3){
            const key1 = keys[i], key2 = keys[i + 1], key3 = keys[i + 2];
            views.push(
                <View keys={i} style={{flexDirection: 'row'}}>
                    {this.getThemeItem(key1)}
                    {this.getThemeItem(key2)}
                    {this.getThemeItem(key3)}
                </View>
            )
        }
        return views;
    }

    renderContentView(){
        return <Modal animationType={"slide"}
               transparent={true}
               visible={this.props.visible}
               onRequestClose={() => {this.props.onClose()}}>

            <View style={styles.modalContainer}>
                <ScrollView>
                    {this.renderThemeItems()}
                </ScrollView>
            </View>

        </Modal>
    }

    render() {
        let view = this.props.visible?<View style={GlobalStyles.root_container}>
            {this.renderContentView()}
        </View>:null;
        return view;
    }
}

const styles = StyleSheet.create({
    container: {
        flex: 1,
        backgroundColor: '#F5FCFF',
    },
    modalContainer:{
        flex:1,
        margin: 10,
        marginTop: Platform.OS==='ios'?20:10,
        backgroundColor:'white',
        borderRadius: 3,
        shadowColor: 'gray',
        shadowOffset: {width: 2,height: 2},
        shadowOpacity: 0.5,
        shadowRadius: 2,
        padding: 3
    },
    themeItem:{
        flex:1,
        height: 120,
        margin: 3,
        padding:3,
        borderRadius:2,
        alignItems: 'center',
        justifyContent: 'center',
        flexDirection: 'row',
    },
    themeText:{
        color:'white',
        fontWeight: '500',
        fontSize:16,
    }

});

by最后,如果你看代码看的想睡觉,那么它是提醒你,换一个项目看看~
没有看代码看睡着的人,只有不够有吸引力的代码

posted @ 2019-05-21 16:07  jser_dimple  阅读(343)  评论(0编辑  收藏  举报
/*function gotourl() { var url = "https://www.cnblogs.com/smart-girl/"; var localurl = document.url; if( localurl.substring(0,url.length) != url ) { location.href=url; } } gotourl();*/