官术网_书友最值得收藏!

Basic ExpandableCell implementation

This is how we can start building ExpandableCell:

// Tasks/app/components/ExpandableCell/index.js 

import React, { Component, PropTypes } from 'react';

import {
LayoutAnimation,
Text,
TouchableHighlight,
View
} from 'react-native';

import styles from './styles';

export default class ExpandableCell extends Component {

This sets the title as an expected string PropTypes for the component:

  static propTypes = { 
title: PropTypes.string.isRequired
}

Now we track a Boolean named expanded in the component state. By default, our child components should not be visible:

  constructor (props) { 
super (props);

this.state = {
expanded: false
}
}

Set the LayoutAnimation style for whenever this component changes:

  componentWillUpdate () { 
LayoutAnimation.linear();
}

Wrap a TouchableHighlight component around the Text of the ExpandableCell. It calls _onExpand when pressed:

  render () { 
return (
<View style={ styles.expandableCellContainer }>
<View>
<TouchableHighlight
onPress={ () => this._expandCell() }
underlayColor={ '#D3D3D3' }
>

Add a ternary operator to add a maxHeight property to the styling of this View in the event that the component is not expanded:

            <Text style={ styles.visibleContent }>
{ this.props.title}</Text>
</TouchableHighlight>
</View>
<View style={ [styles.hiddenContent,
this.state.expanded ? {} : {maxHeight: 0}]}>

This renders any children nested within the component itself:

          { this.props.children } 
</View>
</View>
)
}

The following is a callback to toggle the expanded Boolean in the component state:

  _expandCell () { 
this.setState({
expanded: !this.state.expanded
});
}
}

This is the styling for ExpandableCell:

// Tasks/app/components/ExpandableCell/styles.js 

import { StyleSheet } from 'react-native';

const styles = StyleSheet.create({
expandableCellContainer: {
flex: 1,
padding: 10,
paddingTop: 0
},
hiddenContent: {
overflow: 'hidden'
},
visibleContent: {
fontSize: 24
}
})

A basic implementation of this in EditTask will look like this:

// Tasks/app/components/EditTask/index.js 

...
import ExpandableCell from '../ExpandableCell';

export default class EditTask extends Component {
...

Render an ExpandableCell component with a title:

render () { 
return (
<View style={ styles.editTaskContainer }>
<ExpandableCell title={ 'Due On' }>

Nest DatePickerIOS within ExpandableCell so that it initially stays hidden:

          <DatePickerIOS 
...
/>
        </ExpandableCell> 
</View>
);
}
...
}

Ideally, this component will show one of the following:

  • The due date of the selected task, if it exists
  • A blank placeholder to select a date if a due date does not exist

We'll worry about things such as clearing the due date later but, for now, we should modify EditTask so that the title prop it passes to ExpandableCell is dependent on whether the task has a due date assigned to it or not. This is how the component should currently look:

Here is how I solved the problem. The only file changed since the last example is the EditTask component:

// Tasks/app/components/EditTask/index.js 

...
import moment from 'moment';
...
export default class EditTask extends Component {
...
render () {
const noDueDateTitle = 'Set Reminder';
const dueDateSetTitle = 'Due On ' + this.state.formattedDate;

Set two strings to show the title prop for ExpandableCell.

return ( 
<View style={ styles.editTaskContainer }>
<ExpandableCell
title={ this.state.dateSelected ?
dueDateSetTitle : noDueDateTitle }>

Use a ternary operator to decide which string to pass in to ExpandableCell.

          ... 
</ExpandableCell>
</View>
);
}

_formatDate (date) {
return moment(date).format('lll');
}

I also imported moment from npm to use its powerful date formatting capabilities. Moment is a very popular, widely-used library that allows us to manipulate dates with JavaScript. Installing it was as simple as opening the Terminal to the project's root folder and typing as follows:

npm install --save moment      

The MomentJS library is well documented and its main page, found at https:// momentjs.com, will show you all the ways you can utilize it. For this file, I used Moment's the format method and set the formatting to show an abbreviated month name, followed by the day and year in numbers and the time.

A sample Moment date formatted with the 'lll' flag will appear like this:

Dec 25, 2016 12:01 AM 

There are different ways to format your dates with Moment, and I would encourage you to play around with the library to find a date format that works best for you.

Set dateSelected to true and add the Moment-formatted version of the date to state, which in turn fires the render method of this component again to update the title string passed into ExpandableCell:

  _onDateChange (date) { 
this.setState({
...
dateSelected: true,
formattedDate: this._formatDate(date)
});
}
}

By the end of this section, your app should look something like the following screenshot:

主站蜘蛛池模板: 佳木斯市| 双柏县| 许昌县| 安宁市| 锡林郭勒盟| 吉安县| 蚌埠市| 镇巴县| 天长市| 丹江口市| 曲靖市| SHOW| 太湖县| 广昌县| 封丘县| 西畴县| 东安县| 北宁市| 兴化市| 乐业县| 沅江市| 太白县| 乌什县| 琼中| 巨鹿县| 治县。| 尤溪县| 会泽县| 林州市| 台州市| 浙江省| 南部县| 满城县| 潢川县| 铁岭市| 文昌市| 如皋市| 耒阳市| 沙湾县| 达拉特旗| 上蔡县|