项目作者: tsaohucn

项目描述 :
react-native-comic-book
高级语言: HTML
项目地址: git://github.com/tsaohucn/react-native-comic-book.git
创建时间: 2018-03-24T15:44:48Z
项目社区:https://github.com/tsaohucn/react-native-comic-book

开源协议:

下载


react-native-comic-book

Installation

  1. Runnpm install git+http://192.168.0.200/xc/react-native-comic-book.git --save

  2. react-native-comic-book use some native library so that you have to link those library below before you use react-native-comic-book

    react-native link react-native-vector-icons

    react-native link react-native-screen-brightness

    react-native link react-native-gesture-handler

  3. Open your MainActivity.java to change the code to below

    1. import com.facebook.react.ReactActivityDelegate;
    2. import com.facebook.react.ReactRootView;
    3. import com.swmansion.gesturehandler.react.RNGestureHandlerEnabledRootView;
    4. public class MainActivity extends ReactActivity {
    5. // Add the following method to your main activity class
    6. @Override
    7. protected ReactActivityDelegate createReactActivityDelegate() {
    8. return new ReactActivityDelegate(this, getMainComponentName()) {
    9. @Override
    10. protected ReactRootView createRootView() {
    11. return new RNGestureHandlerEnabledRootView(MainActivity.this);
    12. }
    13. };
    14. }
    15. }
  4. Open your MainApplication.java to change the code to below
    1. new ScreenBrightnessPackage(1)

API

Props Description Type Default
onClickBackArrow Fired after you click back-arrow icon function none
onEndComicBook Fired after end of your comic-book function none
noPreviousChapter Fired when you click PreviousChapter button but there’s no any previous chapter function none
noNextChapter Fired when you click NextChapter button but there’s no any next chapter function none
noPreviousPageNumber Fired when you click TopArea to page up but it’s alerady in the first page with no previous page function none
noNextPageNumber Fired when you click BottomArea to page down but it’s alerady in the last page with no next page function none
initialPageNumber Initial page number of your comic-book Integer 1
chapter Chapter structure of your comic-book Array[object] []
content Content of your comic-book Array[object] []
renderContentrequired How to render your content function none
getContentLayoutrequired Layout of your content function none

Array[object]

  • chapter : [{ pageNumber: (Int)(Reuired)(Unique), title: (String)(Option) }]

    • pageNumber : pageNumber of this chapter
    • title : title of this chapter
  • content : [{ key: (String)(Reuired)(Unique), ...other }]

    • key : unique string key
    • …other : It depends on your renderContent function that how do you render your each item

Remember custom your renderContent and getContentLayout at same time

  • The props as same as renderItem getItemLayout of FlatList
  1. renderContent = ({ item, index }) => {
  2. // return your content render
  3. }
  4. getContentLayout = (data, index) => {
  5. // return your content layout
  6. if (index >= 0) {
  7. return { length: `your item length of this index`, offset: `your item offset of this index`, index }
  8. } else {
  9. return { length: 0, offset: 0, index }
  10. // Add this line because initialPageNumber will cause index < 0 bug now
  11. // https://github.com/facebook/react-native/issues/18743
  12. }
  13. }

Usage example

  • Novel
  1. import React, { Component } from 'react'
  2. import {
  3. View,
  4. Text,
  5. Button,
  6. Dimensions
  7. } from 'react-native'
  8. import { StackNavigator } from 'react-navigation'
  9. import getSlideFromRightTransition from 'react-navigation-slide-from-right-transition'
  10. import ComicBook from 'react-native-comic-book'
  11. class HomeScreen extends Component {
  12. render() {
  13. return (
  14. <View style={styles.home}>
  15. <Text>Home</Text>
  16. <Button
  17. title="Go To ComicBook"
  18. onPress={() => this.props.navigation.navigate('ComicBook')}
  19. />
  20. </View>
  21. );
  22. }
  23. }
  24. class ComicBookScreen extends Component {
  25. constructor(props) {
  26. super(props)
  27. }
  28. onEndComicBook = (pageNumber) => {
  29. console.log(pageNumber)
  30. }
  31. onClickBackArrow = () => {
  32. this.props.navigation.goBack()
  33. }
  34. noPreviousChapter = () => {
  35. console.log('沒有上一回')
  36. }
  37. noNextChapter = () => {
  38. console.log('沒有下一回')
  39. }
  40. noPreviousPageNumber = () => {
  41. console.log('沒有上一頁')
  42. }
  43. noNextPageNumber = () => {
  44. console.log('沒有下一頁')
  45. }
  46. renderContent = ({ item, index }) =>
  47. <View style={styles.content}>
  48. <View style={styles.pageNumber}>
  49. <Text>{index + 1}</Text>
  50. </View>
  51. <View style={styles.novel}>
  52. <Text>{item.novel}</Text>
  53. </View>
  54. </View>
  55. getContentLayout = (data, index) => ({ length: 500, offset: 500*index, index })
  56. render() {
  57. return (
  58. <ComicBook
  59. onClickBackArrow={this.onClickBackArrow}
  60. onEndComicBook={this.onEndComicBook}
  61. noPreviousChapter={this.noPreviousChapter}
  62. noNextChapter={this.noNextChapter}
  63. noPreviousPageNumber={this.noPreviousPageNumber}
  64. noNextPageNumber={this.noNextPageNumber}
  65. content={content}
  66. renderContent={this.renderContent}
  67. getContentLayout={this.getContentLayout}
  68. initialPageNumber={30}
  69. chapter={chapter}
  70. ></ComicBook>
  71. );
  72. }
  73. }
  74. export default class App extends React.Component {
  75. render() {
  76. return <RootStack ></RootStack>
  77. }
  78. }
  79. const RootStack = StackNavigator(
  80. {
  81. Home: {
  82. screen: HomeScreen,
  83. },
  84. ComicBook: {
  85. screen: ComicBookScreen,
  86. }
  87. },
  88. {
  89. initialRouteName: 'Home',
  90. headerMode: 'none',
  91. transitionConfig: getSlideFromRightTransition
  92. }
  93. )
  94. const content = Array(100).fill().map((e,index) => ({
  95. key: index.toString(),
  96. novel: '你的小說內容'
  97. }))
  98. const chapter = [
  99. { pageNumber: 76, title: '戰役' },
  100. { pageNumber: 5, title: '精氣' },
  101. { pageNumber: 29, title: '鎮寢之寶' },
  102. { pageNumber: 16, title: '夢中人' },
  103. { pageNumber: 39, title: '飛來豔福' },
  104. { pageNumber: 26, title: '馬克思主義哲學' },
  105. { pageNumber: 69, title: '演員的自我修飾' },
  106. { pageNumber: 48, title: '天降之物' },
  107. { pageNumber: 95, title: '亞拉那一卡?' },
  108. { pageNumber: 89, title: '相遇' }
  109. ]
  110. const styles = {
  111. home: {
  112. flex: 1,
  113. justifyContent: 'center',
  114. alignItems: 'center'
  115. },
  116. content: {
  117. backgroundColor: 'white',
  118. height: 500
  119. },
  120. pageNumber: {
  121. flex: 1
  122. },
  123. novel: {
  124. flex: 1,
  125. justifyContent: 'flex-start',
  126. alignItems: 'center'
  127. }
  128. }
  • ComicBook
  1. import React, { Component } from 'react'
  2. import {
  3. View,
  4. Text,
  5. Image,
  6. Button,
  7. Dimensions,
  8. ActivityIndicator
  9. } from 'react-native'
  10. import { StackNavigator } from 'react-navigation'
  11. import getSlideFromRightTransition from 'react-navigation-slide-from-right-transition'
  12. import ComicBook from 'react-native-comic-book'
  13. import LoadingImage from './LoadingImage'
  14. class HomeScreen extends Component {
  15. render() {
  16. return (
  17. <View style={styles.home}>
  18. <Text>Home</Text>
  19. <Button
  20. title="Go To ComicBook"
  21. onPress={() => this.props.navigation.navigate('ComicBook')}
  22. />
  23. </View>
  24. );
  25. }
  26. }
  27. class ComicBookScreen extends Component {
  28. constructor(props) {
  29. super(props)
  30. this.length = new Array
  31. this.offset = new Array
  32. this.state = {
  33. isLoading: true
  34. }
  35. }
  36. componentDidMount() {
  37. // this part may exist some issue on ios now
  38. // https://github.com/facebook/react-native/pull/18875
  39. const scaleImageHeightPromise = content.map(async (ele,index) => {
  40. let scaleImageHeight = width
  41. await Image.getSize(ele.uri,(imageWidth, imageHeight) => {
  42. if (imageWidth && imageHeight) {
  43. scaleImageHeight = width*imageHeight/imageWidth
  44. console.log(scaleImageHeight)
  45. }
  46. },() => {
  47. scaleImageHeight = width
  48. })
  49. return scaleImageHeight
  50. })
  51. Promise.all(scaleImageHeightPromise).then(value => {
  52. this.length = value
  53. let offset = 0
  54. this.offset = this.length.map(lenght => {
  55. offset += lenght
  56. return offset
  57. })
  58. this.offset.unshift(0)
  59. this.setState({
  60. isLoading: false
  61. })
  62. }).catch(err => {
  63. alert(err)
  64. })
  65. }
  66. onEndComicBook = (pageNumber) => {
  67. console.log(pageNumber)
  68. }
  69. onClickBackArrow = () => {
  70. this.props.navigation.goBack()
  71. }
  72. noPreviousChapter = () => {
  73. console.log('沒有上一回')
  74. }
  75. noNextChapter = () => {
  76. console.log('沒有下一回')
  77. }
  78. noPreviousPageNumber = () => {
  79. console.log('沒有上一頁')
  80. }
  81. noNextPageNumber = () => {
  82. console.log('沒有下一頁')
  83. }
  84. renderContent = ({ item, index }) =>
  85. <LoadingImage
  86. width={width}
  87. height={this.length[index]}
  88. source={{uri: item.uri}}
  89. ></LoadingImage>
  90. getContentLayout = (data, index) => {
  91. if (index >= 0) {
  92. return { length: this.length[index], offset: this.offset[index], index }
  93. } else {
  94. return { length: 0, offset: 0, index }
  95. // Add this line because initialPageNumber will cause index < 0 bug now
  96. // https://github.com/facebook/react-native/issues/18743
  97. }
  98. }
  99. render() {
  100. return (
  101. <View style={styles.comicbook}>
  102. {
  103. this.state.isLoading ?
  104. <ActivityIndicator
  105. style={styles.activityIndicator}
  106. size={'large'}
  107. color={'white'}
  108. ></ActivityIndicator> :
  109. <ComicBook
  110. onClickBackArrow={this.onClickBackArrow}
  111. onEndComicBook={this.onEndComicBook}
  112. noPreviousChapter={this.noPreviousChapter}
  113. noNextChapter={this.noNextChapter}
  114. noPreviousPageNumber={this.noPreviousPageNumber}
  115. noNextPageNumber={this.noNextPageNumber}
  116. content={content}
  117. renderContent={this.renderContent}
  118. getContentLayout={this.getContentLayout}
  119. initialPageNumber={5}
  120. chapter={chapter}
  121. ></ComicBook>
  122. }
  123. </View>
  124. )
  125. }
  126. }
  127. export default class App extends React.Component {
  128. render() {
  129. return <RootStack ></RootStack>
  130. }
  131. }
  132. const RootStack = StackNavigator(
  133. {
  134. Home: {
  135. screen: HomeScreen,
  136. },
  137. ComicBook: {
  138. screen: ComicBookScreen,
  139. }
  140. },
  141. {
  142. initialRouteName: 'Home',
  143. headerMode: 'none',
  144. transitionConfig: getSlideFromRightTransition
  145. }
  146. )
  147. const { width, heigth } = Dimensions.get("window")
  148. const content = Array(500).fill().map((e,index) => {
  149. const randomWidth = getRandomArbitrary(200,500).toFixed(0)
  150. const randomHeight = getRandomArbitrary(200,500).toFixed(0)
  151. return({
  152. key: index.toString(),
  153. uri: 'https://via.placeholder.com/' + randomWidth + 'x' + randomHeight
  154. //uri: 'https://picsum.photos/'+ randomWidth + '/' + randomHeight + '?image=' + index,
  155. })
  156. })
  157. const chapter = [
  158. { pageNumber: 20, title: '戰役' },
  159. { pageNumber: 133, title: '精氣' },
  160. { pageNumber: 100, title: '鎮寢之寶' },
  161. { pageNumber: 93, title: '夢中人' },
  162. { pageNumber: 45, title: '飛來豔福' },
  163. { pageNumber: 198, title: '馬克思主義哲學' },
  164. { pageNumber: 267, title: '演員的自我修飾' },
  165. { pageNumber: 356, title: '天降之物' },
  166. { pageNumber: 462, title: '亞拉那一卡?' },
  167. { pageNumber: 410, title: '相遇' }
  168. ]
  169. const styles = {
  170. home: {
  171. flex: 1,
  172. justifyContent: 'center',
  173. alignItems: 'center'
  174. },
  175. comicbook: {
  176. flex: 1,
  177. backgroundColor: '#000000'
  178. },
  179. activityIndicator: {
  180. flex: 1,
  181. justifyContent: 'center'
  182. }
  183. }
  184. function getRandomArbitrary(min, max) {
  185. return Math.random() * (max - min) + min;
  186. }