技术控

    今日:0| 主题:63445
收藏本版 (1)
最新软件应用技术尽在掌握

[其他] Common React Native App Layouts: Calendar Page

[复制链接]
远昼 发表于 2016-11-30 19:42:11
311 6
In this series, you'll learn how to use React Native to create page layouts commonly used in mobile apps. The layouts you'll be creating won't be functional—instead, the main focus of this series is to get your hands dirty in laying out content in your React Native apps.
  If you're new to laying out React Native apps or styling in general, check out my previous tutorial:
  
       
  •   

    Common React Native App Layouts: Calendar Page

    Common React Native App Layouts: Calendar Page
    React Native
    Get Started With React Native Layouts
    Wernher-Bel Ancheta
      
  To follow along with this series, I challenge you to try recreating each screen by yourself first, before you read my step-by-step instructions in the tutorial. You won't really benefit much from this tutorial just by reading it! Try first before looking up the answers here. If you succeed in making it look like the original screen, compare your implementation to mine. Then decide for yourself which one is better!
  In this second part of the series, you'll create the following calendar page:
     

Common React Native App Layouts: Calendar Page

Common React Native App Layouts: Calendar Page
    Calendar apps are used to track events and appointments added by the user. You'll find different variations in the wild, but most of them will have the same elements as a physical calendar would: the current month and year, the days in the month, and the events or appointments added by the user.
  Here are a couple of examples of this type of layout:
     

Common React Native App Layouts: Calendar Page

Common React Native App Layouts: Calendar Page
      

Common React Native App Layouts: Calendar Page

Common React Native App Layouts: Calendar Page
    Project Setup

  The first step, of course, is to set up a new React Native project:
  1. react-native init react-native-common-screens
复制代码
  Once the project is set up, open the index.android.js file and replace the default code with the following:
  1. import React, { Component } from 'react';
  2. import {
  3.   AppRegistry
  4. } from 'react-native';

  5. import Calendar from './src/pages/Calendar';

  6. export default class ReactNativeCommonScreens extends Component {

  7.   render() {
  8.     return (
  9.       <Calendar />
  10.     );
  11.   }

  12. }

  13. AppRegistry.registerComponent('ReactNativeCommonScreens', () => ReactNativeCommonScreens);
复制代码
  Create a src/pages folder and create a Calendar.js file inside it.
   You'll also need the react-native-vector-icons package. This is specifically used for the navigation icons as well as other icons that will be needed in the page.
  1. npm install --save react-native-vector-icons
复制代码
  Open the android/app/build.gradle file and add a reference to the package:
  1. dependencies {
  2.     //rest of the dependencies are here at the top
  3.     compile project(':react-native-vector-icons') //add this
  4. }
复制代码
  Do the same with the android/settings.gradle file by adding the following at the bottom:
  1. include ':react-native-vector-icons'
  2. project(':react-native-vector-icons').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-vector-icons/android')
复制代码
  Open android/app/src/main/java/com/react-native-common-screens/MainApplication.java and import the package:
  1. import java.util.Arrays;
  2. import java.util.List;

  3. import com.oblador.vectoricons.VectorIconsPackage; //add this
复制代码
Lastly, initialize the package:
  1. @Override
  2. protected List<ReactPackage> getPackages() {
  3.   return Arrays.<ReactPackage>asList(
  4.       new MainReactPackage(),
  5.       new VectorIconsPackage() //add this
  6.   );
  7. }
复制代码
Creating the Calendar Page

  Okay, now that you've tried to code the layout yourself (no cheating, right?), I'll show you how I built my implementation.
  At first, I thought this would be the most difficult one to implement, but trust me, it's really not that complicated as long as you already know the basics. There are a couple of opportunities here to use JavaScript code to help with rendering.
  Start by including all the components and packages that you'll need:
  1. import React, { Component } from 'react';

  2. import {
  3.   StyleSheet,
  4.   Text,
  5.   View,
  6.   ScrollView
  7. } from 'react-native';

  8. import Icon from 'react-native-vector-icons/FontAwesome';
  9. import { range } from 'lodash';
  10. import Button from '../components/Button';
复制代码
  This time there's a new package which you haven't installed yet, and that is lodash . You won't really need the whole lodash library, just the range function. This is used for generating an array of numbers based on a specific range. You can install just this function by executing  npm install --save lodash.range on your terminal.
  Add the boilerplate code for creating pages:
  1. export default class Calendar extends Component {
  2.     render() {
  3.             return (
  4.                         <ScrollView style={styles.container}>
  5.                             ...
  6.                         </ScrollView>
  7.                 );
  8.         }
  9. }

  10. const styles = StyleSheet.create({
  11.         container: {
  12.                 flex: 1
  13.         }
  14. });
复制代码
The header has three elements in it: the button for going back to the previous page, the title of the current page, and the text showing a human-friendly representation of the currently selected date.
  1. <View style={styles.header}>
  2.     <Button
  3.                 noDefaultStyles={true}
  4.                 onPress={this.press.bind(this)}
  5.                 styles={{button: styles.header_item}}
  6.         >
  7.         <View style={styles.header_button}>
  8.                 <Icon name="chevron-left" size={30} color="#FFF" />
  9.                 <Text style={[styles.header_text]}> Menu</Text>
  10.         </View>
  11.     </Button>
  12.     <View style={styles.header_item}>
  13.             <Text style={[styles.header_text, styles.text_center, styles.bold_text]}>Calendar</Text>
  14.     </View>
  15.         <View style={styles.header_item}>
  16.             <Text style={[styles.header_text, styles.text_right]}>Today</Text>
  17.     </View>
  18. </View>
复制代码
   

Common React Native App Layouts: Calendar Page

Common React Native App Layouts: Calendar Page
     header has a  flexDirection of  row so that each  header_item is stacked horizontally. The same  flex value is assigned to each of them so they consume equal amounts of space.  text_center and  text_right are used to align the text inside of those  header_item s to the center and right. This is done because by default they're aligned on the left-most side of their container.
  1. import React, { Component } from 'react';
  2. import {
  3.   AppRegistry
  4. } from 'react-native';

  5. import Calendar from './src/pages/Calendar';

  6. export default class ReactNativeCommonScreens extends Component {

  7.   render() {
  8.     return (
  9.       <Calendar />
  10.     );
  11.   }

  12. }

  13. AppRegistry.registerComponent('ReactNativeCommonScreens', () => ReactNativeCommonScreens);0
复制代码
Once the styles have been added, it should now look like this:
     

Common React Native App Layouts: Calendar Page

Common React Native App Layouts: Calendar Page
    Next is the actual calendar, which is divided into three parts: the header, the days of the week, and the calendar days:
  1. import React, { Component } from 'react';
  2. import {
  3.   AppRegistry
  4. } from 'react-native';

  5. import Calendar from './src/pages/Calendar';

  6. export default class ReactNativeCommonScreens extends Component {

  7.   render() {
  8.     return (
  9.       <Calendar />
  10.     );
  11.   }

  12. }

  13. AppRegistry.registerComponent('ReactNativeCommonScreens', () => ReactNativeCommonScreens);1
复制代码
The calendar header allows the user to change the year and month.
   There are at least two ways this can be implemented. The first method is to treat each element as a single item and apply justifyContent: 'space-between' to its container. The second method is to group all the elements that have to do with the year and group those that have to do with the month.  
  The second method is the one that's applied below. Semantically speaking, this makes much more sense because the button for navigating back a year, the year itself, and the button for navigating forward are all related, so you can treat them as a single thing by putting them in the same container. The same is true with the month controls.
  1. import React, { Component } from 'react';
  2. import {
  3.   AppRegistry
  4. } from 'react-native';

  5. import Calendar from './src/pages/Calendar';

  6. export default class ReactNativeCommonScreens extends Component {

  7.   render() {
  8.     return (
  9.       <Calendar />
  10.     );
  11.   }

  12. }

  13. AppRegistry.registerComponent('ReactNativeCommonScreens', () => ReactNativeCommonScreens);2
复制代码
   

Common React Native App Layouts: Calendar Page

Common React Native App Layouts: Calendar Page
     From there, you can apply the same technique to those two groups of components in the same line. To add spaces between the two buttons (back and forward) and the label, we use justifyContent: 'space-between' . We use  alignItems: 'center' to nudge all the elements inside it towards the center. Finally, we add left and right padding to add more space between the two groups.
  1. import React, { Component } from 'react';
  2. import {
  3.   AppRegistry
  4. } from 'react-native';

  5. import Calendar from './src/pages/Calendar';

  6. export default class ReactNativeCommonScreens extends Component {

  7.   render() {
  8.     return (
  9.       <Calendar />
  10.     );
  11.   }

  12. }

  13. AppRegistry.registerComponent('ReactNativeCommonScreens', () => ReactNativeCommonScreens);3
复制代码
   

Common React Native App Layouts: Calendar Page

Common React Native App Layouts: Calendar Page
    Next are the weekdays. We use a function to render these because it's best to use some JavaScript code to render all the elements.
  1. import React, { Component } from 'react';
  2. import {
  3.   AppRegistry
  4. } from 'react-native';

  5. import Calendar from './src/pages/Calendar';

  6. export default class ReactNativeCommonScreens extends Component {

  7.   render() {
  8.     return (
  9.       <Calendar />
  10.     );
  11.   }

  12. }

  13. AppRegistry.registerComponent('ReactNativeCommonScreens', () => ReactNativeCommonScreens);4
复制代码
  So instead of having seven View or  Text components rendering each day of the week, you can just have an array containing the days of the week. You can then iterate through those days using the  Array.map() function. For each iteration, render a  Text component that shows the day.  
  1. import React, { Component } from 'react';
  2. import {
  3.   AppRegistry
  4. } from 'react-native';

  5. import Calendar from './src/pages/Calendar';

  6. export default class ReactNativeCommonScreens extends Component {

  7.   render() {
  8.     return (
  9.       <Calendar />
  10.     );
  11.   }

  12. }

  13. AppRegistry.registerComponent('ReactNativeCommonScreens', () => ReactNativeCommonScreens);5
复制代码
  Note that in the code above, the toUpperCase() function is used to convert all the letters of each day to uppercase. React Native doesn't come with the  text-transform CSS property, so this is the only way to achieve uppercase letters aside from manually using uppercase strings.
     

Common React Native App Layouts: Calendar Page

Common React Native App Layouts: Calendar Page
    Here's the styling for the calendar header:
  1. import React, { Component } from 'react';
  2. import {
  3.   AppRegistry
  4. } from 'react-native';

  5. import Calendar from './src/pages/Calendar';

  6. export default class ReactNativeCommonScreens extends Component {

  7.   render() {
  8.     return (
  9.       <Calendar />
  10.     );
  11.   }

  12. }

  13. AppRegistry.registerComponent('ReactNativeCommonScreens', () => ReactNativeCommonScreens);6
复制代码
   

Common React Native App Layouts: Calendar Page

Common React Native App Layouts: Calendar Page
    The calendar days also uses a function for rendering the days:
  1. import React, { Component } from 'react';
  2. import {
  3.   AppRegistry
  4. } from 'react-native';

  5. import Calendar from './src/pages/Calendar';

  6. export default class ReactNativeCommonScreens extends Component {

  7.   render() {
  8.     return (
  9.       <Calendar />
  10.     );
  11.   }

  12. }

  13. AppRegistry.registerComponent('ReactNativeCommonScreens', () => ReactNativeCommonScreens);7
复制代码
  The renderWeeks() function uses the  range() function in lodash to generate an array containing the days from the last month and the days of the current month. Those two arrays are then merged together.  
   However, you can't directly use the resulting array as the data source for the calendar days. That's because if you simply loop through the items and output a Text component for each day, there won't be any distinction between each week. You already know that to make each calendar day inline, you need to apply  flexDirection: 'row' to its container. So applying it to a single container would result in having all the calendar days placed in a single line.  
  This means you need to have a separate container for each week. The question is how. Again, there are at least two ways to accomplish this.
   The first method is to have a variable store how many days are currently outputted and then add a conditional statement that will render an opening <View> every time the variable contains  0 and a closing  </View> every time it's  7 . Once it's  7 , reset it back to  0 . This is the most straightforward method.
   But I'll use a different method here. Below, the getWeeksArray() function is used to implement it. This function accepts the array of days and groups them into arrays containing seven days each. From there, you can loop through each of those arrays to render the week container. Then for each iteration, you again loop through the days inside the week to render the days. This is what the  renderDays() function does.
  1. import React, { Component } from 'react';
  2. import {
  3.   AppRegistry
  4. } from 'react-native';

  5. import Calendar from './src/pages/Calendar';

  6. export default class ReactNativeCommonScreens extends Component {

  7.   render() {
  8.     return (
  9.       <Calendar />
  10.     );
  11.   }

  12. }

  13. AppRegistry.registerComponent('ReactNativeCommonScreens', () => ReactNativeCommonScreens);8
复制代码
  Here's the getWeeksArray() function:
  1. import React, { Component } from 'react';
  2. import {
  3.   AppRegistry
  4. } from 'react-native';

  5. import Calendar from './src/pages/Calendar';

  6. export default class ReactNativeCommonScreens extends Component {

  7.   render() {
  8.     return (
  9.       <Calendar />
  10.     );
  11.   }

  12. }

  13. AppRegistry.registerComponent('ReactNativeCommonScreens', () => ReactNativeCommonScreens);9
复制代码
  And here's the renderDays() function:
  1. npm install --save react-native-vector-icons0
复制代码
   

Common React Native App Layouts: Calendar Page

Common React Native App Layouts: Calendar Page
     Add the styling for each week ( week_days ) and day ( day and  day_text ):
  1. npm install --save react-native-vector-icons1
复制代码
   

Common React Native App Layouts: Calendar Page

Common React Native App Layouts: Calendar Page
    Next is the note added by the user for the currently selected day and the selected date and time. Again, it's better to group elements according to their purpose rather than how they're placed in the page. Certainly all these elements are related, so we'll place them inside the same container. But on a closer look, you'll start to see that you can group them further: the actual note and the selected date. With that in mind, here's the markup that you'll end up with:
  1. npm install --save react-native-vector-icons2
复制代码
   

Common React Native App Layouts: Calendar Page

Common React Native App Layouts: Calendar Page
     The selected date occupies less space than the note, so you have to apply a bigger flex value to the notes.  flex: 3 and  flex: 1 are used in this case, which means that the notes consume 3/4 of the available space and the selected date consumes 1/4. You can also use decimals ( 0.75 and  0.25 ) if that makes more sense to you. What's important is to pick a standard and stick to it.  alignItems: 'flex-end' is used on  notes_selected_date so that all its children will be aligned to the right. This is needed because by default they're aligned to the left.   
  1. npm install --save react-native-vector-icons3
复制代码
   

Common React Native App Layouts: Calendar Page

Common React Native App Layouts: Calendar Page
    Lastly, we add the logs, which are very similar to those in the previous tutorial, so I'll leave it to you to figure out how the layout is achieved!
  1. npm install --save react-native-vector-icons4
复制代码
Here are the styles:
  1. npm install --save react-native-vector-icons5
复制代码
Conclusion

  That's it! In this tutorial you've created a calendar page. We've made a nice calendar layout for an app, and I've shown you how JavaScript code can be used to compensate for some of the limitations of Flexbox.
   As you have seen, we needed a way to limit the number of days in a row to just seven days. Flexbox doesn't have a way to specify this, so we used JavaScript to reconstruct the original array of days in such a way that they're divided into groups containing seven days each. From there, all we had to do was to wrap each group inside a View and then apply  flexDirection: 'row' to make each of them render in their own row.
  In an upcoming tutorial, you'll learn how to implement the layout commonly used in gallery pages. In the meantime, check out some of our other tutorials on React Native and Flexbox.
  
       
  •                

    Common React Native App Layouts: Calendar Page

    Common React Native App Layouts: Calendar Page
           Get Started With React Native

               When building mobile applications, you might not always want to go native if it means that you would have to develop your app for multiple platforms. But a...
       
  •                       Get Started With React Native Layouts

               In this tutorial, you'll learn how to lay out React Native apps and how to implement layouts commonly used in apps.
       
  •                

    Common React Native App Layouts: Calendar Page

    Common React Native App Layouts: Calendar Page
           Build a Social App With React Native

               React Native, created by Facebook, lets you write native mobile apps in modern JavaScript. React Native apps will be transformed into native views specific...
       
  •                

    Common React Native App Layouts: Calendar Page

    Common React Native App Layouts: Calendar Page
           How to Build a Striped Navigation With Flexbox

               Are you looking to improve your flexbox knowledge and at the same time learn how to build easily an attractive and unique layout? If so, be sure to read this...
       
  •                

    Common React Native App Layouts: Calendar Page

    Common React Native App Layouts: Calendar Page
           Animate Your React Native App

               Animations can breath life into your app and make your UIs more intuitive. In this tutorial, you'll learn how to implement different kinds of animations in...
       
  •                

    Common React Native App Layouts: Calendar Page

    Common React Native App Layouts: Calendar Page
           An Introduction to the CSS Flexbox Module

               CSS, despite its relatively low perceived skill ceiling, always seems to have a killer feature up its sleeve. Remember how media queries made responsive...
      

Common React Native App Layouts: Calendar Page

Common React Native App Layouts: Calendar Page
ThopEa 发表于 2016-11-30 22:08:54
这么强,支持楼主,佩服
回复 支持 反对

使用道具 举报

Anthonytync 发表于 2016-12-2 02:47:20
路过!!!据说外面下人民币了!!!
回复 支持 反对

使用道具 举报

邓东梅 发表于 2016-12-2 15:10:38
我就路过,不说话。
回复 支持 反对

使用道具 举报

yfeqva93 发表于 2016-12-3 22:37:10
坐沙发喽,楼主给赏钱不?
回复 支持 反对

使用道具 举报

我是和宁 发表于 2016-12-4 11:39:55
楼主,笑一个,萌萌哒!
回复 支持 反对

使用道具 举报

zhaozicang 发表于 2016-12-16 17:29:34
为什么我躺着也中枪
回复 支持 反对

使用道具 举报

我要投稿

推荐阅读


回页顶回复上一篇下一篇回列表
手机版/c.CoLaBug.com ( 粤ICP备05003221号 | 粤公网安备 44010402000842号 )

© 2001-2017 Comsenz Inc.

返回顶部 返回列表