Compare commits
91 Commits
bumpVersio
...
develop
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
11699645bc | ||
|
|
7030c13224 | ||
|
|
b240254af9 | ||
|
|
ee680eda68 | ||
|
|
dbe12b0b0c | ||
|
|
1aa1a7aded | ||
|
|
f0b1606fac | ||
|
|
e22a39e8bf | ||
|
|
f9315cc706 | ||
|
|
9d012ef028 | ||
|
|
574435855d | ||
|
|
802edd1ca3 | ||
|
|
67822de9e6 | ||
|
|
3a119c8454 | ||
|
|
1b1c9516de | ||
|
|
4a04adcf9d | ||
|
|
beb6cf995d | ||
|
|
e9e9b075e1 | ||
|
|
cc538a069b | ||
|
|
72c6430393 | ||
|
|
f00abfb859 | ||
|
|
2cda5bda31 | ||
|
|
44cbed20bd | ||
|
|
9b527b22ab | ||
|
|
988e2c010c | ||
|
|
f8d66f30c2 | ||
|
|
655eb204e1 | ||
|
|
05bb025469 | ||
|
|
0676c84401 | ||
|
|
7ebd74d4bd | ||
|
|
7ee508a291 | ||
|
|
9a6200bd20 | ||
|
|
057032940c | ||
|
|
fa52596712 | ||
|
|
0e850fbf6d | ||
|
|
a4c06c5cdc | ||
|
|
c90de7b40f | ||
|
|
c99f80a3d9 | ||
|
|
aa1e9df982 | ||
|
|
e2f8d9e309 | ||
|
|
4a13acfb03 | ||
|
|
5e4c9852a5 | ||
|
|
ee6c352444 | ||
|
|
cff749e7c6 | ||
|
|
5a6a9f59ce | ||
|
|
4d4b26e06a | ||
|
|
6503b1cfb6 | ||
|
|
3fc6449780 | ||
|
|
846e13f58c | ||
|
|
b71ac8dbb6 | ||
|
|
288ce99397 | ||
|
|
7f51a00bba | ||
|
|
bba003f23f | ||
|
|
a808eed809 | ||
|
|
515257506b | ||
|
|
27b51f9de9 | ||
|
|
28294b7dfc | ||
|
|
f6f656b3a0 | ||
|
|
f81e260915 | ||
|
|
facd667a58 | ||
|
|
4e8fbc54b6 | ||
|
|
70d1218b11 | ||
|
|
e4dbde6657 | ||
|
|
cb8c080a8f | ||
|
|
6333668c36 | ||
|
|
658923f707 | ||
|
|
23d62e09e4 | ||
|
|
1ca92e5afe | ||
|
|
d786dffc88 | ||
|
|
e6bcc4e2e4 | ||
|
|
7afcdd7c9d | ||
|
|
008ed8bb8a | ||
|
|
81dd7be33e | ||
|
|
2c52e01067 | ||
|
|
30cc488c46 | ||
|
|
be1b3beb84 | ||
|
|
64fdd5cfbd | ||
|
|
4fc5eab25e | ||
|
|
f3276c9659 | ||
|
|
a1e052e485 | ||
|
|
cf9cc5a83c | ||
|
|
06e0fa5a07 | ||
|
|
57f87ce4ef | ||
|
|
456157f71c | ||
|
|
2e3c812965 | ||
|
|
76ac03cde5 | ||
|
|
00f429d6b2 | ||
|
|
7bf6a49860 | ||
|
|
d6c696d3b2 | ||
|
|
4f6554f440 | ||
|
|
5336a4ac2c |
3
.gitignore
vendored
@ -39,3 +39,6 @@ examples/swiper.xcodeproj/xcuserdata
|
||||
# Vim
|
||||
*.sw*
|
||||
dist/
|
||||
|
||||
# yarn
|
||||
yarn.lock
|
||||
|
||||
10
.prettierrc
Normal file
@ -0,0 +1,10 @@
|
||||
{
|
||||
"printWidth": 80,
|
||||
"tabWidth": 2,
|
||||
"useTabs": false,
|
||||
"semi": false,
|
||||
"singleQuote": true,
|
||||
"trailingComma": "none",
|
||||
"bracketSpacing": true,
|
||||
"jsxBracketSameLine": false
|
||||
}
|
||||
136
CHANGELOG.md
@ -1,103 +1,129 @@
|
||||
- [1.6.0-dev]
|
||||
- ViewPagerAndroid: react-native => @react-native-community/viewpager
|
||||
- add TypeScript typing of containerStyle
|
||||
- [1.5.14]
|
||||
- fixes #582 (Android not setting this onLayout first?) #789 (thanks [@fungilation](https://github.com/fungilation))
|
||||
- Add onScrollBegin and onTouchEnd for Android #684 (thanks [@kostyaVyrodov](https://github.com/kostyaVyrodov))
|
||||
- [1.5.13]
|
||||
+ Workaround for react-native 0.4.8 contentOffset regression #572 (thanks @nixoz)
|
||||
+ Fix wrong calculation of width and height after device rotation #581 (thanks @kostyaVyrodov)
|
||||
+ Calculated width & height on layout, used later on re-rendering. Possibility to change ScrollView styles #548 (thanks @germanst)
|
||||
- Workaround for react-native 0.4.8 contentOffset regression #572 (thanks [@nixoz](https://github.com/nixoz))
|
||||
- Fix wrong calculation of width and height after device rotation #581 (thanks [@kostyaVyrodov](https://github.com/kostyaVyrodov))
|
||||
- Calculated width & height on layout, used later on re-rendering. Possibility to change ScrollView styles #548 (thanks [@germanst](https://github.com/germanst))
|
||||
- [1.5.12]
|
||||
+ Update core packages
|
||||
+ Optionally disable the 'next' control button (thanks [@SSTPIERRE2](https://github.com/SSTPIERRE2))
|
||||
+ Fix `Uncaught TypeError: _this.refs.scrollView.scrollTo is not a function` (thanks [@flyskywhy](https://github.com/flyskywhy))
|
||||
+ Allow dotStyle and activeDotStyle PropTypes to accept Stylesheet (thanks [@knopt](https://github.com/knopt))
|
||||
+ Calculate the offset in the initial state instead of `onLayout` (thanks [@kjkta](https://github.com/kjkta))
|
||||
|
||||
- Update core packages
|
||||
- Optionally disable the 'next' control button (thanks [@SSTPIERRE2](https://github.com/SSTPIERRE2))
|
||||
- Fix `Uncaught TypeError: _this.refs.scrollView.scrollTo is not a function` (thanks [@flyskywhy](https://github.com/flyskywhy))
|
||||
- Allow dotStyle and activeDotStyle PropTypes to accept Stylesheet (thanks [@knopt](https://github.com/knopt))
|
||||
- Calculate the offset in the initial state instead of `onLayout` (thanks [@kjkta](https://github.com/kjkta))
|
||||
|
||||
- [1.5.11]
|
||||
+ Typescript Definition
|
||||
|
||||
- Typescript Definition
|
||||
|
||||
- [1.5.1]
|
||||
+ Allow scroll without animate, ref: [scrollBy(index, animated)](#scrollbyindex-animated)
|
||||
+ Remove [#254](https://github.com/leecade/react-native-swiper/pull/254) which break the scroll direction in loop mode
|
||||
|
||||
- Allow scroll without animate, ref: [scrollBy(index, animated)](#scrollbyindex-animated)
|
||||
- Remove [#254](https://github.com/leecade/react-native-swiper/pull/254) which break the scroll direction in loop mode
|
||||
|
||||
- [1.5.0]
|
||||
+ Improve develop [workflow](#development) for support watch & use real pkg name in examples
|
||||
+ Update examples for support `React-native 0.33` + `Xcode8` + `ios10` + `iphone7`
|
||||
+ Switch to [standard](https://github.com/feross/standard) code style
|
||||
+ Rewrite source code with ES6 syntex
|
||||
+ Cancel transform the source code when publish
|
||||
+ Add a [demo](examples/components/LoadMinimal) for `loadMinimal` + `lazyload`
|
||||
+ Add a [demo](examples/components/PhotoView) for multi-images viewer
|
||||
+ [#254](https://github.com/leecade/react-native-swiper/pull/254) Fix jitter when quickly swiping back and forth between pages (iOS) (@thanks [@nemophrost](https://github.com/nemophrost)).
|
||||
|
||||
- Improve develop [workflow](#development) for support watch & use real pkg name in examples
|
||||
- Update examples for support `React-native 0.33` + `Xcode8` + `ios10` + `iphone7`
|
||||
- Switch to [standard](https://github.com/feross/standard) code style
|
||||
- Rewrite source code with ES6 syntex
|
||||
- Cancel transform the source code when publish
|
||||
- Add a [demo](examples/components/LoadMinimal) for `loadMinimal` + `lazyload`
|
||||
- Add a [demo](examples/components/PhotoView) for multi-images viewer
|
||||
- [#254](https://github.com/leecade/react-native-swiper/pull/254) Fix jitter when quickly swiping back and forth between pages (iOS) (@thanks [@nemophrost](https://github.com/nemophrost)).
|
||||
|
||||
- [1.4.11]
|
||||
+ Adds loadMinimalSize property
|
||||
|
||||
- Adds loadMinimalSize property
|
||||
|
||||
- [1.4.10]
|
||||
+ Adds loadMinimal to api (lazyloading-esque)
|
||||
|
||||
- Adds loadMinimal to api (lazyloading-esque)
|
||||
|
||||
- [1.4.9]
|
||||
+ Adds extra check for title
|
||||
|
||||
- Adds extra check for title
|
||||
|
||||
- [1.4.8]
|
||||
+ Fixes loop and autoplay bugs in android
|
||||
|
||||
- Fixes loop and autoplay bugs in android
|
||||
|
||||
- [1.4.7]
|
||||
+ Don't attempt to mutate this.props
|
||||
+ Fixes examples links
|
||||
+ Adds drag end handling to always reset state.isScrolling
|
||||
+ Fixes float calculation error
|
||||
|
||||
- Don't attempt to mutate this.props
|
||||
- Fixes examples links
|
||||
- Adds drag end handling to always reset state.isScrolling
|
||||
- Fixes float calculation error
|
||||
|
||||
- [1.4.6]
|
||||
+ refactors examples
|
||||
+ prevents mutation of `this.props`
|
||||
+ fixes android index loop issue
|
||||
|
||||
- refactors examples
|
||||
- prevents mutation of `this.props`
|
||||
- fixes android index loop issue
|
||||
|
||||
- [1.4.5]
|
||||
+ renames `scrollTo()` to `scrollBy()`
|
||||
+ image index is now always an integer
|
||||
+ prevents parent state updates from reseting index counter
|
||||
+ fixes issue with scrolling not working sometimes
|
||||
|
||||
- renames `scrollTo()` to `scrollBy()`
|
||||
- image index is now always an integer
|
||||
- prevents parent state updates from reseting index counter
|
||||
- fixes issue with scrolling not working sometimes
|
||||
|
||||
- [1.4.4]
|
||||
+ Support for React Native latest(`^0.26.0`)
|
||||
+ Updates examples to work with react-native-swiper 1.4.4
|
||||
+ Examples now run on Android (some are still buggy, needs more work)
|
||||
+ Removes old examples folder
|
||||
|
||||
- Support for React Native latest(`^0.26.0`)
|
||||
- Updates examples to work with react-native-swiper 1.4.4
|
||||
- Examples now run on Android (some are still buggy, needs more work)
|
||||
- Removes old examples folder
|
||||
|
||||
- [1.4.3]
|
||||
+ Fixed auto play issue when only a child view
|
||||
|
||||
- Fixed auto play issue when only a child view
|
||||
|
||||
- [v1.4.0]
|
||||
+ Support for React Native latest(`^0.17.0`) & Upgrade examples base on Xcode `7.2` / React Native `0.17.0`
|
||||
|
||||
+ Upgrade build tool to babel6
|
||||
- Support for React Native latest(`^0.17.0`) & Upgrade examples base on Xcode `7.2` / React Native `0.17.0`
|
||||
|
||||
+ Add missing deps `react-timer-mixin`
|
||||
- Upgrade build tool to babel6
|
||||
|
||||
+ [1f8643a](https://github.com/leecade/react-native-swiper/commit/1f8643a67e2768d165132a19629a991a86672036) Move Dimensions import to deconstructed React import for react-native (@thanks [@jedrekk](https://github.com/jedrekk)).
|
||||
- Add missing deps `react-timer-mixin`
|
||||
|
||||
+ [e28af9b](https://github.com/leecade/react-native-swiper/commit/e28af9b205f17447cb3149b45fc220beec037bce) Support index property in combination with loop property (@thanks [@almost](https://github.com/almost)).
|
||||
- [1f8643a](https://github.com/leecade/react-native-swiper/commit/1f8643a67e2768d165132a19629a991a86672036) Move Dimensions import to deconstructed React import for react-native (@thanks [@jedrekk](https://github.com/jedrekk)).
|
||||
|
||||
+ [6c832d](https://github.com/leecade/react-native-swiper/commit/6c832d6a23da3737a2e8a2667273dc6093bcc9ee) fix warnings about keys for dots (@thanks [@sunnylqm](https://github.com/sunnylqm)).
|
||||
- [e28af9b](https://github.com/leecade/react-native-swiper/commit/e28af9b205f17447cb3149b45fc220beec037bce) Support index property in combination with loop property (@thanks [@almost](https://github.com/almost)).
|
||||
|
||||
+ [8de1afc](https://github.com/leecade/react-native-swiper/commit/8de1afcb75a003424231bb089802db53bbbf84e4) Changes to make the example work in xcode 7 (@thanks [@allomov](https://github.com/allomov)).
|
||||
- [6c832d](https://github.com/leecade/react-native-swiper/commit/6c832d6a23da3737a2e8a2667273dc6093bcc9ee) fix warnings about keys for dots (@thanks [@sunnylqm](https://github.com/sunnylqm)).
|
||||
|
||||
- [8de1afc](https://github.com/leecade/react-native-swiper/commit/8de1afcb75a003424231bb089802db53bbbf84e4) Changes to make the example work in xcode 7 (@thanks [@allomov](https://github.com/allomov)).
|
||||
|
||||
- [v1.3.0]
|
||||
+ [8d6d75c](https://github.com/leecade/react-native-swiper/commit/8d6d75c00edf87b603c218aad0018932277814b5) inject `state` in ScrollResponders (@thanks [@smothers](https://github.com/smothers)).
|
||||
|
||||
- [8d6d75c](https://github.com/leecade/react-native-swiper/commit/8d6d75c00edf87b603c218aad0018932277814b5) inject `state` in ScrollResponders (@thanks [@smothers](https://github.com/smothers)).
|
||||
|
||||
- [v1.2.2]
|
||||
+ [890c0ce](https://github.com/leecade/react-native-swiper/commit/890c0ce64e2192c2ca7830e6699f67b88171e74b) ensure `onMomentumScrollEnd` synchronous update `index`.
|
||||
|
||||
- [890c0ce](https://github.com/leecade/react-native-swiper/commit/890c0ce64e2192c2ca7830e6699f67b88171e74b) ensure `onMomentumScrollEnd` synchronous update `index`.
|
||||
|
||||
- [v1.2.0]
|
||||
+ [838b24c](https://github.com/leecade/react-native-swiper/commit/838b24cbeaf49b9ca1dabb4eed8305e314503fb1) Re-design a loop model for avoid img flickering.
|
||||
+ [9cb91c5](https://github.com/leecade/react-native-swiper/commit/9cb91c58c84034b0b8b874dbfc2a44da982686a8) fixes [#7](https://github.com/leecade/react-native-swiper/issues/6) `onMomentumScrollEnd` lost `event` param. (thanks [@smothers](https://github.com/smothers))
|
||||
|
||||
- [838b24c](https://github.com/leecade/react-native-swiper/commit/838b24cbeaf49b9ca1dabb4eed8305e314503fb1) Re-design a loop model for avoid img flickering.
|
||||
- [9cb91c5](https://github.com/leecade/react-native-swiper/commit/9cb91c58c84034b0b8b874dbfc2a44da982686a8) fixes [#7](https://github.com/leecade/react-native-swiper/issues/6) `onMomentumScrollEnd` lost `event` param. (thanks [@smothers](https://github.com/smothers))
|
||||
|
||||
- [v1.1.1]
|
||||
+ [21f0b00](https://github.com/leecade/react-native-swiper/commit/21f0b00138b6936cd3dfac2eb107a14c99c7392b) fixes [#6](https://github.com/leecade/react-native-swiper/issues/6) a define-propType error. (thanks [@benjamingeorge](https://github.com/benjamingeorge))
|
||||
|
||||
- [21f0b00](https://github.com/leecade/react-native-swiper/commit/21f0b00138b6936cd3dfac2eb107a14c99c7392b) fixes [#6](https://github.com/leecade/react-native-swiper/issues/6) a define-propType error. (thanks [@benjamingeorge](https://github.com/benjamingeorge))
|
||||
|
||||
- [v1.1.0]
|
||||
+ [44ec630](https://github.com/leecade/react-native-swiper/commit/44ec630b62844dbeaccee73adaa0996e319ebffb) fixes [#4](https://github.com/leecade/react-native-swiper/issues/4) `onMoementumScrollEnd` gets overridden. (thanks [@subpublicanders](https://github.com/subpublicanders))
|
||||
+ [5de06a7](https://github.com/leecade/react-native-swiper/commit/5de06a7aa86318ad38720728022b80e5cf98a2ab) New prop: `renderPagination`. (thanks [@aksonov](https://github.com/aksonov))
|
||||
|
||||
- [44ec630](https://github.com/leecade/react-native-swiper/commit/44ec630b62844dbeaccee73adaa0996e319ebffb) fixes [#4](https://github.com/leecade/react-native-swiper/issues/4) `onMoementumScrollEnd` gets overridden. (thanks [@subpublicanders](https://github.com/subpublicanders))
|
||||
- [5de06a7](https://github.com/leecade/react-native-swiper/commit/5de06a7aa86318ad38720728022b80e5cf98a2ab) New prop: `renderPagination`. (thanks [@aksonov](https://github.com/aksonov))
|
||||
|
||||
- [v1.0.4]
|
||||
+ [21cb373](https://github.com/leecade/react-native-swiper/commit/21cb3732578588f9d47ee7ddda541577ad691970) fixes [#2](https://github.com/leecade/react-native-swiper/issues/2) Solve the problem of installation. (thanks [@jamwaffles](https://github.com/jamwaffles))
|
||||
|
||||
- [21cb373](https://github.com/leecade/react-native-swiper/commit/21cb3732578588f9d47ee7ddda541577ad691970) fixes [#2](https://github.com/leecade/react-native-swiper/issues/2) Solve the problem of installation. (thanks [@jamwaffles](https://github.com/jamwaffles))
|
||||
|
||||
- [v1.0.3]
|
||||
+ [0f796f3](https://github.com/leecade/react-native-swiper/commit/0f796f3557b5aeb1772573cd7ecae2e835bccc0b) fixes [#1](https://github.com/leecade/react-native-swiper/issues/1) Two 'horizontal' in propTypes. (thanks [@MacyzZ](https://github.com/MacyzZ))
|
||||
- [0f796f3](https://github.com/leecade/react-native-swiper/commit/0f796f3557b5aeb1772573cd7ecae2e835bccc0b) fixes [#1](https://github.com/leecade/react-native-swiper/issues/1) Two 'horizontal' in propTypes. (thanks [@MacyzZ](https://github.com/MacyzZ))
|
||||
|
||||
243
README.md
@ -22,27 +22,50 @@
|
||||
> see: [ROADMAP.md](ROADMAP.md)
|
||||
|
||||
## Changelogs
|
||||
- **[1.5.6]**
|
||||
+ Fix [#16](https://github.com/leecade/react-native-swiper/issues/16), [#36](https://github.com/leecade/react-native-swiper/issues/36), [#371](https://github.com/leecade/react-native-swiper/issues/371), [#410](https://github.com/leecade/react-native-swiper/issues/410), [#411](https://github.com/leecade/react-native-swiper/issues/411), [#422](https://github.com/leecade/react-native-swiper/issues/422), [#468](https://github.com/leecade/react-native-swiper/issues/468) Fix landscape orientation auto resize! (thanks [@ahmed3mar](https://github.com/ahmed3mar), [@timmywil](https://github.com/timmywil))
|
||||
+ Add containerStyle prop to customize the view container.
|
||||
|
||||
- [1.5.5]
|
||||
+ Update: using PropTypes from prop-types and Change View.propTypes to ViewPropTypes
|
||||
|
||||
- **[1.6.0-rc]**
|
||||
- Dependency
|
||||
- Remove ViewPagerAndroid, use ScrollView #1009
|
||||
- Test Integration
|
||||
- Setup e2e test
|
||||
- TypeScript
|
||||
- correct the wrong types #1000
|
||||
- Add missing scrollBy TypeScript definition #931
|
||||
- New Feature
|
||||
- add scrollTo #831
|
||||
- Added prop to disable the PrevButton #749
|
||||
- Optionally render page #1004
|
||||
- Bug Fix
|
||||
- ES6 and CommonJS compatibility #717
|
||||
- Solves the issue of state messing up when parent component calls setState #939
|
||||
- replay when autoplay is setted to true #1002
|
||||
- fix broken examples and migrate to react-native 0.60.x
|
||||
- fix bad jumping on ios when loadMinimal set true
|
||||
- fix fliker when loop and loadMinimal are enabled #1062
|
||||
|
||||
* [1.5.6]
|
||||
|
||||
- Fix [#16](https://github.com/leecade/react-native-swiper/issues/16), [#36](https://github.com/leecade/react-native-swiper/issues/36), [#371](https://github.com/leecade/react-native-swiper/issues/371), [#410](https://github.com/leecade/react-native-swiper/issues/410), [#411](https://github.com/leecade/react-native-swiper/issues/411), [#422](https://github.com/leecade/react-native-swiper/issues/422), [#468](https://github.com/leecade/react-native-swiper/issues/468) Fix landscape orientation auto resize! (thanks [@ahmed3mar](https://github.com/ahmed3mar), [@timmywil](https://github.com/timmywil))
|
||||
- Add containerStyle prop to customize the view container.
|
||||
|
||||
* [1.5.5]
|
||||
- Update: using PropTypes from prop-types and Change View.propTypes to ViewPropTypes
|
||||
|
||||
- [1.5.4]
|
||||
+ Added easily accessible pagination point manipulation: use `dotColor` / `activeDotColor` and `dotStyle` / `activeDotStyle` (thanks [@denizs](https://github.com/denizs))
|
||||
+ Added scrollEnabled prop to documentation (thanks [@ibandominguez](https://github.com/ibandominguez))
|
||||
|
||||
- Added easily accessible pagination point manipulation: use `dotColor` / `activeDotColor` and `dotStyle` / `activeDotStyle` (thanks [@denizs](https://github.com/denizs))
|
||||
- Added scrollEnabled prop to documentation (thanks [@ibandominguez](https://github.com/ibandominguez))
|
||||
|
||||
- [1.5.3]
|
||||
+ Add loadMinimalLoader prop to customize `<ActivityIndicator />` (thanks [@Exilz](https://github.com/Exilz))
|
||||
+ Disable autoplay timer when prop changes to false (thanks [@dizlexik](https://github.com/dizlexik))
|
||||
+ Special thanks to [@hypatiah](https://github.com/dizlexik) for fixed some grammatical errors in README
|
||||
|
||||
- Add loadMinimalLoader prop to customize `<ActivityIndicator />` (thanks [@Exilz](https://github.com/Exilz))
|
||||
- Disable autoplay timer when prop changes to false (thanks [@dizlexik](https://github.com/dizlexik))
|
||||
- Special thanks to [@hypatiah](https://github.com/dizlexik) for fixed some grammatical errors in README
|
||||
|
||||
- [1.5.2]
|
||||
+ Add yarn lock
|
||||
+ Fix jitter when quickly swiping back and forth between pages (iOS) (thanks [@nemophrost](https://github.com/nemophrost))
|
||||
+ The first webview always reloaded when injecting the rest of the children (thanks [@eosterberg](https://github.com/eosterberg))
|
||||
- Add yarn lock
|
||||
- Fix jitter when quickly swiping back and forth between pages (iOS) (thanks [@nemophrost](https://github.com/nemophrost))
|
||||
- The first webview always reloaded when injecting the rest of the children (thanks [@eosterberg](https://github.com/eosterberg))
|
||||
|
||||
> see more: [CHANGELOG.md](CHANGELOG.md)
|
||||
|
||||
@ -70,29 +93,36 @@
|
||||
|
||||

|
||||
|
||||
|
||||
## Getting Started
|
||||
|
||||
- [Installation](#installation)
|
||||
- [Basic Usage](#basic-usage)
|
||||
- [Properties](#properties)
|
||||
+ [Basic](#basic)
|
||||
+ [Custom basic style & content](#custom-basic-style--content)
|
||||
+ [Pagination](#pagination)
|
||||
+ [Autoplay](#autoplay)
|
||||
+ [Control buttons](#control-buttons)
|
||||
+ [Props of Children](#props-of-children)
|
||||
+ [Basic props of `<ScrollView />`](#basic-props-of-scrollview-)
|
||||
+ [Supported ScrollResponder](#supported-scrollresponder)
|
||||
- [Basic](#basic)
|
||||
- [Custom basic style & content](#custom-basic-style--content)
|
||||
- [Pagination](#pagination)
|
||||
- [Autoplay](#autoplay)
|
||||
- [Control buttons](#control-buttons)
|
||||
- [Props of Children](#props-of-children)
|
||||
- [Basic props of `<ScrollView />`](#basic-props-of-scrollview-)
|
||||
- [Supported ScrollResponder](#supported-scrollresponder)
|
||||
- [Examples](#examples)
|
||||
- [Development](#development)
|
||||
|
||||
### Installation
|
||||
|
||||
> v1.5.14
|
||||
|
||||
```bash
|
||||
$ npm i react-native-swiper --save
|
||||
```
|
||||
|
||||
> v1.6.0-rc
|
||||
|
||||
```
|
||||
npm i --save react-native-swiper@next
|
||||
```
|
||||
|
||||
### Basic Usage
|
||||
|
||||
- Install `react-native` first
|
||||
@ -110,46 +140,40 @@ $ react-native init myproject
|
||||
- Then, edit `myproject/index.ios.js`, like this:
|
||||
|
||||
```jsx
|
||||
import React, { Component } from 'react';
|
||||
import {
|
||||
AppRegistry,
|
||||
StyleSheet,
|
||||
Text,
|
||||
View
|
||||
} from 'react-native';
|
||||
import React, { Component } from 'react'
|
||||
import { AppRegistry, StyleSheet, Text, View } from 'react-native'
|
||||
|
||||
import Swiper from 'react-native-swiper';
|
||||
import Swiper from 'react-native-swiper'
|
||||
|
||||
var styles = StyleSheet.create({
|
||||
wrapper: {
|
||||
},
|
||||
const styles = StyleSheet.create({
|
||||
wrapper: {},
|
||||
slide1: {
|
||||
flex: 1,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
backgroundColor: '#9DD6EB',
|
||||
backgroundColor: '#9DD6EB'
|
||||
},
|
||||
slide2: {
|
||||
flex: 1,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
backgroundColor: '#97CAE5',
|
||||
backgroundColor: '#97CAE5'
|
||||
},
|
||||
slide3: {
|
||||
flex: 1,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
backgroundColor: '#92BBD9',
|
||||
backgroundColor: '#92BBD9'
|
||||
},
|
||||
text: {
|
||||
color: '#fff',
|
||||
fontSize: 30,
|
||||
fontWeight: 'bold',
|
||||
fontWeight: 'bold'
|
||||
}
|
||||
})
|
||||
|
||||
var swiper = React.createClass({
|
||||
render: function() {
|
||||
export default class SwiperComponent extends Component {
|
||||
render() {
|
||||
return (
|
||||
<Swiper style={styles.wrapper} showsButtons={true}>
|
||||
<View style={styles.slide1}>
|
||||
@ -164,99 +188,100 @@ var swiper = React.createClass({
|
||||
</Swiper>
|
||||
)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
AppRegistry.registerComponent('myproject', () => swiper);
|
||||
AppRegistry.registerComponent('myproject', () => SwiperComponent)
|
||||
```
|
||||
|
||||
### Properties
|
||||
|
||||
#### Basic
|
||||
|
||||
| Prop | Default | Type | Description |
|
||||
| :------------ |:---------------:| :---------------:| :-----|
|
||||
| horizontal | true | `bool` | If `true`, the scroll view's children are arranged horizontally in a row instead of vertically in a column. |
|
||||
| loop | true | `bool` | Set to `false` to disable continuous loop mode. |
|
||||
| index | 0 | `number` | Index number of initial slide. |
|
||||
| showsButtons | false | `bool` | Set to `true` make control buttons visible. |
|
||||
| autoplay | false | `bool` | Set to `true` enable auto play mode. |
|
||||
| onIndexChanged | (index) => null | `func` | Called with the new index when the user swiped |
|
||||
| Prop | Default | Type | Description |
|
||||
| :------------- | :-------------: | :------: | :---------------------------------------------------------------------------------------------------------- |
|
||||
| horizontal | true | `bool` | If `true`, the scroll view's children are arranged horizontally in a row instead of vertically in a column. |
|
||||
| loop | true | `bool` | Set to `false` to disable continuous loop mode. |
|
||||
| index | 0 | `number` | Index number of initial slide. |
|
||||
| showsButtons | false | `bool` | Set to `true` make control buttons visible. |
|
||||
| autoplay | false | `bool` | Set to `true` enable auto play mode. |
|
||||
| onIndexChanged | (index) => null | `func` | Called with the new index when the user swiped |
|
||||
|
||||
#### Custom basic style & content
|
||||
|
||||
| Prop | Default | Type | Description |
|
||||
| :------------ |:---------------:| :---------------:| :-----|
|
||||
| width | - | `number` | If no specify default enable fullscreen mode by `flex: 1`. |
|
||||
| height | - | `number` | If no specify default fullscreen mode by `flex: 1`. |
|
||||
| style | {...} | `style` | See default style in source. |
|
||||
| loadMinimal | false | `bool` | Only load current index slide , `loadMinimalSize` slides before and after. |
|
||||
| loadMinimalSize | 1 | `number` | see `loadMinimal` |
|
||||
| loadMinimalLoader | `<ActivityIndicator />` | `element` | Custom loader to display when slides aren't loaded
|
||||
| Prop | Default | Type | Description |
|
||||
| :---------------- | :---------------------: | :-------: | :------------------------------------------------------------------------- |
|
||||
| width | - | `number` | If no specify default enable fullscreen mode by `flex: 1`. |
|
||||
| height | - | `number` | If no specify default fullscreen mode by `flex: 1`. |
|
||||
| style | {...} | `style` | See default style in source. |
|
||||
| containerStyle | {...} | `style` | See default container style in source. |
|
||||
| loadMinimal | false | `bool` | Only load current index slide , `loadMinimalSize` slides before and after. |
|
||||
| loadMinimalSize | 1 | `number` | see `loadMinimal` |
|
||||
| loadMinimalLoader | `<ActivityIndicator />` | `element` | Custom loader to display when slides aren't loaded |
|
||||
|
||||
#### Pagination
|
||||
|
||||
| Prop | Default | Type | Description |
|
||||
| :------------ |:---------------:| :---------------:| :-----|
|
||||
| showsPagination | true | `bool` | Set to `true` make pagination visible. |
|
||||
| paginationStyle | {...} | `style` | Custom styles will merge with the default styles. |
|
||||
| renderPagination | - | `function` | Complete control how to render pagination with three params (`index`, `total`, `context`) ref to `this.state.index` / `this.state.total` / `this`, For example: show numbers instead of dots. |
|
||||
| dot | `<View style={{backgroundColor:'rgba(0,0,0,.2)', width: 8, height: 8,borderRadius: 4, marginLeft: 3, marginRight: 3, marginTop: 3, marginBottom: 3,}} />` | `element` | Allow custom the dot element. |
|
||||
| activeDot | `<View style={{backgroundColor: '#007aff', width: 8, height: 8, borderRadius: 4, marginLeft: 3, marginRight: 3, marginTop: 3, marginBottom: 3,}} />` | `element` | Allow custom the active-dot element. |
|
||||
| dotStyle | - | `object` | Allow custom the active-dot element. |
|
||||
| dotColor | - | `string` | Allow custom the active-dot element. |
|
||||
| activeDotColor | - | `string` | Allow custom the active-dot element. |
|
||||
| activeDotStyle | - | `object` | Allow custom the active-dot element. |
|
||||
| Prop | Default | Type | Description |
|
||||
| :--------------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------: | :--------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| showsPagination | true | `bool` | Set to `true` make pagination visible. |
|
||||
| paginationStyle | {...} | `style` | Custom styles will merge with the default styles. |
|
||||
| renderPagination | - | `function` | Complete control how to render pagination with three params (`index`, `total`, `context`) ref to `this.state.index` / `this.state.total` / `this`, For example: show numbers instead of dots. |
|
||||
| dot | `<View style={{backgroundColor:'rgba(0,0,0,.2)', width: 8, height: 8,borderRadius: 4, marginLeft: 3, marginRight: 3, marginTop: 3, marginBottom: 3,}} />` | `element` | Allow custom the dot element. |
|
||||
| activeDot | `<View style={{backgroundColor: '#007aff', width: 8, height: 8, borderRadius: 4, marginLeft: 3, marginRight: 3, marginTop: 3, marginBottom: 3,}} />` | `element` | Allow custom the active-dot element. |
|
||||
| dotStyle | - | `object` | Allow custom the active-dot element. |
|
||||
| dotColor | - | `string` | Allow custom the active-dot element. |
|
||||
| activeDotColor | - | `string` | Allow custom the active-dot element. |
|
||||
| activeDotStyle | - | `object` | Allow custom the active-dot element. |
|
||||
|
||||
#### Autoplay
|
||||
|
||||
| Prop | Default | Type | Description |
|
||||
| :------------ |:---------------:| :---------------:| :-----|
|
||||
| autoplay | true | `bool` | Set to `true` enable auto play mode. |
|
||||
| autoplayTimeout | 2.5 | `number` | Delay between auto play transitions (in second). |
|
||||
| autoplayDirection | true | `bool` | Cycle direction control. |
|
||||
| Prop | Default | Type | Description |
|
||||
| :---------------- | :-----: | :------: | :----------------------------------------------- |
|
||||
| autoplay | true | `bool` | Set to `true` enable auto play mode. |
|
||||
| autoplayTimeout | 2.5 | `number` | Delay between auto play transitions (in second). |
|
||||
| autoplayDirection | true | `bool` | Cycle direction control. |
|
||||
|
||||
#### Control buttons
|
||||
|
||||
| Prop | Default | Type | Description |
|
||||
| :------------ |:---------------:| :---------------:| :-----|
|
||||
| showsButtons | true | `bool` | Set to `true` make control buttons visible. |
|
||||
| buttonWrapperStyle | `{backgroundColor: 'transparent', flexDirection: 'row', position: 'absolute', top: 0, left: 0, flex: 1, paddingHorizontal: 10, paddingVertical: 10, justifyContent: 'space-between', alignItems: 'center'}` | `style` | Custom styles. |
|
||||
| nextButton | `<Text style={styles.buttonText}>›</Text>` | `element` | Allow custom the next button. |
|
||||
| prevButton | `<Text style={styles.buttonText}>‹</Text>` | `element` | Allow custom the prev button. |
|
||||
| Prop | Default | Type | Description |
|
||||
| :----------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :-------: | :------------------------------------------ |
|
||||
| showsButtons | true | `bool` | Set to `true` make control buttons visible. |
|
||||
| buttonWrapperStyle | `{backgroundColor: 'transparent', flexDirection: 'row', position: 'absolute', top: 0, left: 0, flex: 1, paddingHorizontal: 10, paddingVertical: 10, justifyContent: 'space-between', alignItems: 'center'}` | `style` | Custom styles. |
|
||||
| nextButton | `<Text style={styles.buttonText}>›</Text>` | `element` | Allow custom the next button. |
|
||||
| prevButton | `<Text style={styles.buttonText}>‹</Text>` | `element` | Allow custom the prev button. |
|
||||
|
||||
#### Props of Children
|
||||
|
||||
| Prop | Default | Type | Description |
|
||||
| :------------ |:---------------:| :---------------:| :-----|
|
||||
| style | {...} | `style` | Custom styles will merge with the default styles. |
|
||||
| Prop | Default | Type | Description |
|
||||
| :---- | :----------------------------------: | :-------: | :------------------------------------------------------------- |
|
||||
| style | {...} | `style` | Custom styles will merge with the default styles. |
|
||||
| title | {<Text numberOfLines={1}>...</Text>} | `element` | If this parameter is not specified, will not render the title. |
|
||||
|
||||
#### Basic props of `<ScrollView />`
|
||||
|
||||
| Prop | Default | Type | Description |
|
||||
| :------------ |:---------------:| :---------------:| :-----|
|
||||
| horizontal | true | `bool` | If `true`, the scroll view's children are arranged horizontally in a row instead of vertically in a column. |
|
||||
| pagingEnabled | true | `bool` | If true, the scroll view stops on multiples of the scroll view's size when scrolling. This can be used for horizontal pagination. |
|
||||
| showsHorizontalScrollIndicator | false | `bool` | Set to `true` if you want to show horizontal scroll bar. |
|
||||
| showsVerticalScrollIndicator | false | `bool` | Set to `true` if you want to show vertical scroll bar. |
|
||||
| bounces | false | `bool` | If `true`, the scroll view bounces when it reaches the end of the content if the content is larger then the scroll view along the axis of the scroll direction. If `false`, it disables all bouncing even if the alwaysBounce* props are true. |
|
||||
| scrollsToTop | false | `bool` | If true, the scroll view scrolls to top when the status bar is tapped. |
|
||||
| removeClippedSubviews | true | `bool` | If true, offscreen child views (whose overflow value is hidden) are removed from their native backing superview when offscreen. This canimprove scrolling performance on long lists. |
|
||||
| automaticallyAdjustContentInsets | false | `bool` | Set to `true` if you need adjust content insets automation. |
|
||||
| scrollEnabled | true | `bool` | Enables/Disables swiping |
|
||||
| Prop | Default | Type | Description |
|
||||
| :------------------------------- | :-----: | :----: | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| horizontal | true | `bool` | If `true`, the scroll view's children are arranged horizontally in a row instead of vertically in a column. |
|
||||
| pagingEnabled | true | `bool` | If true, the scroll view stops on multiples of the scroll view's size when scrolling. This can be used for horizontal pagination. |
|
||||
| showsHorizontalScrollIndicator | false | `bool` | Set to `true` if you want to show horizontal scroll bar. |
|
||||
| showsVerticalScrollIndicator | false | `bool` | Set to `true` if you want to show vertical scroll bar. |
|
||||
| bounces | false | `bool` | If `true`, the scroll view bounces when it reaches the end of the content if the content is larger then the scroll view along the axis of the scroll direction. If `false`, it disables all bouncing even if the alwaysBounce\* props are true. |
|
||||
| scrollsToTop | false | `bool` | If true, the scroll view scrolls to top when the status bar is tapped. |
|
||||
| removeClippedSubviews | true | `bool` | If true, offscreen child views (whose overflow value is hidden) are removed from their native backing superview when offscreen. This canimprove scrolling performance on long lists. |
|
||||
| automaticallyAdjustContentInsets | false | `bool` | Set to `true` if you need adjust content insets automation. |
|
||||
| scrollEnabled | true | `bool` | Enables/Disables swiping |
|
||||
|
||||
> @see: http://facebook.github.io/react-native/docs/scrollview.html
|
||||
|
||||
#### Supported ScrollResponder
|
||||
|
||||
| Prop | Params | Type | Description |
|
||||
| :------------ |:---------------:| :---------------:| :-----|
|
||||
| onScrollBeginDrag | `e` / `state` / `context` | `function` | When animation begins after letting up |
|
||||
| onMomentumScrollEnd | `e` / `state` / `context` | `function` | Makes no sense why this occurs first during bounce |
|
||||
| onTouchStartCapture | `e` / `state` / `context` | `function` | Immediately after `onMomentumScrollEnd` |
|
||||
| onTouchStart | `e` / `state` / `context` | `function` | Same, but bubble phase |
|
||||
| onTouchEnd | `e` / `state` / `context` | `function` | You could hold the touch start for a long time |
|
||||
| onResponderRelease | `e` / `state` / `context` | `function` | When lifting up - you could pause forever before * lifting |
|
||||
| Prop | Params | Type | Description |
|
||||
| :------------------ | :-----------------------: | :--------: | :---------------------------------------------------------- |
|
||||
| onScrollBeginDrag | `e` / `state` / `context` | `function` | When animation begins after letting up |
|
||||
| onMomentumScrollEnd | `e` / `state` / `context` | `function` | Makes no sense why this occurs first during bounce |
|
||||
| onTouchStartCapture | `e` / `state` / `context` | `function` | Immediately after `onMomentumScrollEnd` |
|
||||
| onTouchStart | `e` / `state` / `context` | `function` | Same, but bubble phase |
|
||||
| onTouchEnd | `e` / `state` / `context` | `function` | You could hold the touch start for a long time |
|
||||
| onResponderRelease | `e` / `state` / `context` | `function` | When lifting up - you could pause forever before \* lifting |
|
||||
|
||||
> Note: each ScrollResponder be injected with two params: `state` and `context`, you can get `state` and `context`(ref to swiper's `this`) from params, for example:
|
||||
|
||||
@ -286,10 +311,10 @@ Scroll by relative index.
|
||||
|
||||
Parameters:
|
||||
|
||||
| Name | Type | default | Description |
|
||||
| :---- | :------: | :------: | :--- |
|
||||
| index | `number` | `undefined` | offset index |
|
||||
| animated | `bool` | `true` | offset index |
|
||||
| Name | Type | default | Description |
|
||||
| :------- | :------: | :---------: | :----------- |
|
||||
| index | `number` | `undefined` | offset index |
|
||||
| animated | `bool` | `true` | offset index |
|
||||
|
||||
### Examples
|
||||
|
||||
@ -305,14 +330,14 @@ $ react-native run-ios
|
||||
|
||||
```bash
|
||||
$ cd examples
|
||||
$ npm i
|
||||
$ npm run dev
|
||||
$ yarn
|
||||
$ yarn start
|
||||
$ react-native run-ios
|
||||
```
|
||||
|
||||
Then launch simulator to preview. Note that you just need to edit the source file `src/index.js`, the change will auto sync to examples.
|
||||
|
||||
And now that this project follows the [standard](https://github.com/feross/standard) code style, you'd better prepare it for IDE.
|
||||
After development, you should add test for your modification and make all tests passed to prevent other contributors break the feature in the future accidentally. We use detox + jest for e2e test now, you can read [Detox](https://github.com/wix/Detox) for more detail.
|
||||
|
||||
## Contribution
|
||||
|
||||
|
||||
@ -1,3 +0,0 @@
|
||||
{
|
||||
"presets": ["react-native"]
|
||||
}
|
||||
4
examples/.eslintrc.js
Normal file
@ -0,0 +1,4 @@
|
||||
module.exports = {
|
||||
root: true,
|
||||
extends: '@react-native-community',
|
||||
};
|
||||
@ -11,20 +11,54 @@
|
||||
; Ignore duplicate module providers
|
||||
; For RN Apps installed via npm, "Libraries" folder is inside
|
||||
; "node_modules/react-native" but in the source repo it is in the root
|
||||
.*/Libraries/react-native/React.js
|
||||
.*/Libraries/react-native/ReactNative.js
|
||||
node_modules/react-native/Libraries/react-native/React.js
|
||||
|
||||
; Ignore polyfills
|
||||
node_modules/react-native/Libraries/polyfills/.*
|
||||
|
||||
; These should not be required directly
|
||||
; require from fbjs/lib instead: require('fbjs/lib/warning')
|
||||
node_modules/warning/.*
|
||||
|
||||
; Flow doesn't support platforms
|
||||
.*/Libraries/Utilities/HMRLoadingView.js
|
||||
|
||||
[untyped]
|
||||
.*/node_modules/@react-native-community/cli/.*/.*
|
||||
|
||||
[include]
|
||||
|
||||
[libs]
|
||||
node_modules/react-native/Libraries/react-native/react-native-interface.js
|
||||
node_modules/react-native/flow
|
||||
flow/
|
||||
node_modules/react-native/flow/
|
||||
|
||||
[options]
|
||||
emoji=true
|
||||
|
||||
esproposal.optional_chaining=enable
|
||||
esproposal.nullish_coalescing=enable
|
||||
|
||||
module.file_ext=.js
|
||||
module.file_ext=.json
|
||||
module.file_ext=.ios.js
|
||||
|
||||
module.system=haste
|
||||
module.system.haste.use_name_reducers=true
|
||||
# get basename
|
||||
module.system.haste.name_reducers='^.*/\([a-zA-Z0-9$_.-]+\.js\(\.flow\)?\)$' -> '\1'
|
||||
# strip .js or .js.flow suffix
|
||||
module.system.haste.name_reducers='^\(.*\)\.js\(\.flow\)?$' -> '\1'
|
||||
# strip .ios suffix
|
||||
module.system.haste.name_reducers='^\(.*\)\.ios$' -> '\1'
|
||||
module.system.haste.name_reducers='^\(.*\)\.android$' -> '\1'
|
||||
module.system.haste.name_reducers='^\(.*\)\.native$' -> '\1'
|
||||
module.system.haste.paths.blacklist=.*/__tests__/.*
|
||||
module.system.haste.paths.blacklist=.*/__mocks__/.*
|
||||
module.system.haste.paths.whitelist=<PROJECT_ROOT>/node_modules/react-native/Libraries/.*
|
||||
module.system.haste.paths.whitelist=<PROJECT_ROOT>/node_modules/react-native/RNTester/.*
|
||||
module.system.haste.paths.whitelist=<PROJECT_ROOT>/node_modules/react-native/IntegrationTests/.*
|
||||
module.system.haste.paths.blacklist=<PROJECT_ROOT>/node_modules/react-native/Libraries/react-native/react-native-implementation.js
|
||||
module.system.haste.paths.blacklist=<PROJECT_ROOT>/node_modules/react-native/Libraries/Animated/src/polyfills/.*
|
||||
|
||||
munge_underscores=true
|
||||
|
||||
@ -32,14 +66,34 @@ module.name_mapper='^[./a-zA-Z0-9$_-]+\.\(bmp\|gif\|jpg\|jpeg\|png\|psd\|svg\|we
|
||||
|
||||
suppress_type=$FlowIssue
|
||||
suppress_type=$FlowFixMe
|
||||
suppress_type=$FixMe
|
||||
suppress_type=$FlowFixMeProps
|
||||
suppress_type=$FlowFixMeState
|
||||
|
||||
suppress_comment=\\(.\\|\n\\)*\\$FlowFixMe\\($\\|[^(]\\|(\\(>=0\\.\\(4[0-9]\\|[1-3][0-9]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\)
|
||||
suppress_comment=\\(.\\|\n\\)*\\$FlowIssue\\((\\(>=0\\.\\(4[0-9]\\|[1-3][0-9]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\)?:? #[0-9]+
|
||||
suppress_comment=\\(.\\|\n\\)*\\$FlowFixedInNextDeploy
|
||||
suppress_comment=\\(.\\|\n\\)*\\$FlowFixMe\\($\\|[^(]\\|(\\(<VERSION>\\)? *\\(site=[a-z,_]*react_native\\(_ios\\)?_\\(oss\\|fb\\)[a-z,_]*\\)?)\\)
|
||||
suppress_comment=\\(.\\|\n\\)*\\$FlowIssue\\((\\(<VERSION>\\)? *\\(site=[a-z,_]*react_native\\(_ios\\)?_\\(oss\\|fb\\)[a-z,_]*\\)?)\\)?:? #[0-9]+
|
||||
suppress_comment=\\(.\\|\n\\)*\\$FlowExpectedError
|
||||
|
||||
unsafe.enable_getters_and_setters=true
|
||||
[lints]
|
||||
sketchy-null-number=warn
|
||||
sketchy-null-mixed=warn
|
||||
sketchy-number=warn
|
||||
untyped-type-import=warn
|
||||
nonstrict-import=warn
|
||||
deprecated-type=warn
|
||||
unsafe-getters-setters=warn
|
||||
inexact-spread=warn
|
||||
unnecessary-invariant=warn
|
||||
signature-verification-failure=warn
|
||||
deprecated-utility=error
|
||||
|
||||
[strict]
|
||||
deprecated-type
|
||||
nonstrict-import
|
||||
sketchy-null
|
||||
unclear-type
|
||||
unsafe-getters-setters
|
||||
untyped-import
|
||||
untyped-type-import
|
||||
|
||||
[version]
|
||||
^0.49.1
|
||||
^0.98.0
|
||||
|
||||
17
examples/.gitignore
vendored
@ -46,8 +46,17 @@ buck-out/
|
||||
# It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the
|
||||
# screenshots whenever they are needed.
|
||||
# For more information about the recommended setup visit:
|
||||
# https://github.com/fastlane/fastlane/blob/master/fastlane/docs/Gitignore.md
|
||||
# https://docs.fastlane.tools/best-practices/source-control/
|
||||
|
||||
fastlane/report.xml
|
||||
fastlane/Preview.html
|
||||
fastlane/screenshots
|
||||
*/fastlane/report.xml
|
||||
*/fastlane/Preview.html
|
||||
*/fastlane/screenshots
|
||||
|
||||
# Bundle artifact
|
||||
*.jsbundle
|
||||
|
||||
# CocoaPods
|
||||
/ios/Pods/
|
||||
|
||||
# TestCase from issue
|
||||
TestCase-*/
|
||||
|
||||
10
examples/.prettierrc
Normal file
@ -0,0 +1,10 @@
|
||||
{
|
||||
"printWidth": 80,
|
||||
"tabWidth": 2,
|
||||
"useTabs": false,
|
||||
"semi": false,
|
||||
"singleQuote": true,
|
||||
"trailingComma": "none",
|
||||
"bracketSpacing": true,
|
||||
"jsxBracketSameLine": false
|
||||
}
|
||||
@ -1,9 +0,0 @@
|
||||
import { AppRegistry } from 'react-native'
|
||||
import Basic from './components/Basic/'
|
||||
// import Dynamic from './components/Dynamic/'
|
||||
// import LoadMinimal from './components/LoadMinimal/'
|
||||
// import Phone from './components/Phone/'
|
||||
// import PhotoView from './components/PhotoView/' // not working
|
||||
// import Swiper from './components/Swiper/' // working but no title displayed
|
||||
// import SwiperNumber from './components/SwiperNumber/' // working but no title displayed
|
||||
AppRegistry.registerComponent('examples', () => Basic);
|
||||
@ -1,12 +1,14 @@
|
||||
/**
|
||||
* @format
|
||||
*/
|
||||
|
||||
import 'react-native';
|
||||
import React from 'react';
|
||||
import Index from '../index.ios.js';
|
||||
import App from '../App';
|
||||
|
||||
// Note: test renderer must be required after react-native.
|
||||
import renderer from 'react-test-renderer';
|
||||
|
||||
it('renders correctly', () => {
|
||||
const tree = renderer.create(
|
||||
<Index />
|
||||
);
|
||||
renderer.create(<App />);
|
||||
});
|
||||
@ -1,12 +0,0 @@
|
||||
import 'react-native';
|
||||
import React from 'react';
|
||||
import Index from '../index.android.js';
|
||||
|
||||
// Note: test renderer must be required after react-native.
|
||||
import renderer from 'react-test-renderer';
|
||||
|
||||
it('renders correctly', () => {
|
||||
const tree = renderer.create(
|
||||
<Index />
|
||||
);
|
||||
});
|
||||
17
examples/android/.project
Normal file
@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>android</name>
|
||||
<comment>Project android created by Buildship.</comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.buildship.core.gradleprojectbuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.buildship.core.gradleprojectnature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
@ -0,0 +1,2 @@
|
||||
connection.project.dir=
|
||||
eclipse.preferences.version=1
|
||||
@ -8,23 +8,13 @@
|
||||
# - `buck install -r android/app` - compile, install and run application
|
||||
#
|
||||
|
||||
load(":build_defs.bzl", "create_aar_targets", "create_jar_targets")
|
||||
|
||||
lib_deps = []
|
||||
|
||||
for jarfile in glob(['libs/*.jar']):
|
||||
name = 'jars__' + jarfile[jarfile.rindex('/') + 1: jarfile.rindex('.jar')]
|
||||
lib_deps.append(':' + name)
|
||||
prebuilt_jar(
|
||||
name = name,
|
||||
binary_jar = jarfile,
|
||||
)
|
||||
create_aar_targets(glob(["libs/*.aar"]))
|
||||
|
||||
for aarfile in glob(['libs/*.aar']):
|
||||
name = 'aars__' + aarfile[aarfile.rindex('/') + 1: aarfile.rindex('.aar')]
|
||||
lib_deps.append(':' + name)
|
||||
android_prebuilt_aar(
|
||||
name = name,
|
||||
aar = aarfile,
|
||||
)
|
||||
create_jar_targets(glob(["libs/*.jar"]))
|
||||
|
||||
android_library(
|
||||
name = "all-libs",
|
||||
|
||||
@ -18,6 +18,9 @@ import com.android.build.OutputFile
|
||||
* // the entry file for bundle generation
|
||||
* entryFile: "index.android.js",
|
||||
*
|
||||
* // https://facebook.github.io/react-native/docs/performance#enable-the-ram-format
|
||||
* bundleCommand: "ram-bundle",
|
||||
*
|
||||
* // whether to bundle JS and assets in debug mode
|
||||
* bundleInDebug: false,
|
||||
*
|
||||
@ -72,6 +75,11 @@ import com.android.build.OutputFile
|
||||
* ]
|
||||
*/
|
||||
|
||||
project.ext.react = [
|
||||
entryFile: "index.js",
|
||||
enableHermes: false, // clean and rebuild if changing
|
||||
]
|
||||
|
||||
apply from: "../../node_modules/react-native/react.gradle"
|
||||
|
||||
/**
|
||||
@ -89,30 +97,67 @@ def enableSeparateBuildPerCPUArchitecture = false
|
||||
*/
|
||||
def enableProguardInReleaseBuilds = false
|
||||
|
||||
/**
|
||||
* The preferred build flavor of JavaScriptCore.
|
||||
*
|
||||
* For example, to use the international variant, you can use:
|
||||
* `def jscFlavor = 'org.webkit:android-jsc-intl:+'`
|
||||
*
|
||||
* The international variant includes ICU i18n library and necessary data
|
||||
* allowing to use e.g. `Date.toLocaleString` and `String.localeCompare` that
|
||||
* give correct results when using with locales other than en-US. Note that
|
||||
* this variant is about 6MiB larger per architecture than default.
|
||||
*/
|
||||
def jscFlavor = 'org.webkit:android-jsc:+'
|
||||
|
||||
/**
|
||||
* Whether to enable the Hermes VM.
|
||||
*
|
||||
* This should be set on project.ext.react and mirrored here. If it is not set
|
||||
* on project.ext.react, JavaScript will not be compiled to Hermes Bytecode
|
||||
* and the benefits of using Hermes will therefore be sharply reduced.
|
||||
*/
|
||||
def enableHermes = project.ext.react.get("enableHermes", false);
|
||||
|
||||
android {
|
||||
compileSdkVersion 23
|
||||
buildToolsVersion "23.0.1"
|
||||
compileSdkVersion rootProject.ext.compileSdkVersion
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_1_8
|
||||
targetCompatibility JavaVersion.VERSION_1_8
|
||||
}
|
||||
|
||||
defaultConfig {
|
||||
applicationId "com.examples"
|
||||
minSdkVersion 16
|
||||
targetSdkVersion 22
|
||||
minSdkVersion rootProject.ext.minSdkVersion
|
||||
targetSdkVersion rootProject.ext.targetSdkVersion
|
||||
versionCode 1
|
||||
versionName "1.0"
|
||||
ndk {
|
||||
abiFilters "armeabi-v7a", "x86"
|
||||
}
|
||||
}
|
||||
splits {
|
||||
abi {
|
||||
reset()
|
||||
enable enableSeparateBuildPerCPUArchitecture
|
||||
universalApk false // If true, also generate a universal APK
|
||||
include "armeabi-v7a", "x86"
|
||||
include "armeabi-v7a", "x86", "arm64-v8a", "x86_64"
|
||||
}
|
||||
}
|
||||
signingConfigs {
|
||||
debug {
|
||||
storeFile file('debug.keystore')
|
||||
storePassword 'android'
|
||||
keyAlias 'androiddebugkey'
|
||||
keyPassword 'android'
|
||||
}
|
||||
}
|
||||
buildTypes {
|
||||
debug {
|
||||
signingConfig signingConfigs.debug
|
||||
}
|
||||
release {
|
||||
// Caution! In production, you need to generate your own keystore file.
|
||||
// see https://facebook.github.io/react-native/docs/signed-apk-android.
|
||||
signingConfig signingConfigs.debug
|
||||
minifyEnabled enableProguardInReleaseBuilds
|
||||
proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
|
||||
}
|
||||
@ -121,21 +166,49 @@ android {
|
||||
applicationVariants.all { variant ->
|
||||
variant.outputs.each { output ->
|
||||
// For each separate APK per architecture, set a unique version code as described here:
|
||||
// http://tools.android.com/tech-docs/new-build-system/user-guide/apk-splits
|
||||
def versionCodes = ["armeabi-v7a":1, "x86":2]
|
||||
// https://developer.android.com/studio/build/configure-apk-splits.html
|
||||
def versionCodes = ["armeabi-v7a": 1, "x86": 2, "arm64-v8a": 3, "x86_64": 4]
|
||||
def abi = output.getFilter(OutputFile.ABI)
|
||||
if (abi != null) { // null for the universal-debug, universal-release variants
|
||||
output.versionCodeOverride =
|
||||
versionCodes.get(abi) * 1048576 + defaultConfig.versionCode
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
packagingOptions {
|
||||
pickFirst '**/armeabi-v7a/libc++_shared.so'
|
||||
pickFirst '**/x86/libc++_shared.so'
|
||||
pickFirst '**/arm64-v8a/libc++_shared.so'
|
||||
pickFirst '**/x86_64/libc++_shared.so'
|
||||
pickFirst '**/x86/libjsc.so'
|
||||
pickFirst '**/armeabi-v7a/libjsc.so'
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile fileTree(dir: "libs", include: ["*.jar"])
|
||||
compile "com.android.support:appcompat-v7:23.0.1"
|
||||
compile "com.facebook.react:react-native:+" // From node_modules
|
||||
implementation fileTree(dir: "libs", include: ["*.jar"])
|
||||
implementation "com.facebook.react:react-native:+" // From node_modules
|
||||
|
||||
// react-native-screens
|
||||
implementation 'androidx.appcompat:appcompat:1.1.0-rc01'
|
||||
implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0-alpha02'
|
||||
|
||||
if (enableHermes) {
|
||||
def hermesPath = "../../node_modules/hermesvm/android/";
|
||||
debugImplementation files(hermesPath + "hermes-debug.aar")
|
||||
releaseImplementation files(hermesPath + "hermes-release.aar")
|
||||
} else {
|
||||
implementation jscFlavor
|
||||
}
|
||||
|
||||
debugImplementation("com.facebook.flipper:flipper:${FLIPPER_VERSION}") {
|
||||
exclude group:'com.facebook.yoga'
|
||||
exclude group:'com.facebook.flipper', module: 'fbjni'
|
||||
exclude group:'com.facebook.fbjni', module: 'fbjni'
|
||||
exclude group:'com.facebook.litho', module: 'litho-annotations'
|
||||
}
|
||||
}
|
||||
|
||||
// Run this once to be able to run the application with BUCK
|
||||
@ -144,3 +217,5 @@ task copyDownloadableDepsToLibs(type: Copy) {
|
||||
from configurations.compile
|
||||
into 'libs'
|
||||
}
|
||||
|
||||
apply from: file("../../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesAppBuildGradle(project)
|
||||
|
||||
19
examples/android/app/build_defs.bzl
Normal file
@ -0,0 +1,19 @@
|
||||
"""Helper definitions to glob .aar and .jar targets"""
|
||||
|
||||
def create_aar_targets(aarfiles):
|
||||
for aarfile in aarfiles:
|
||||
name = "aars__" + aarfile[aarfile.rindex("/") + 1:aarfile.rindex(".aar")]
|
||||
lib_deps.append(":" + name)
|
||||
android_prebuilt_aar(
|
||||
name = name,
|
||||
aar = aarfile,
|
||||
)
|
||||
|
||||
def create_jar_targets(jarfiles):
|
||||
for jarfile in jarfiles:
|
||||
name = "jars__" + jarfile[jarfile.rindex("/") + 1:jarfile.rindex(".jar")]
|
||||
lib_deps.append(":" + name)
|
||||
prebuilt_jar(
|
||||
name = name,
|
||||
binary_jar = jarfile,
|
||||
)
|
||||
60
examples/android/app/proguard-rules.pro
vendored
@ -8,63 +8,3 @@
|
||||
# http://developer.android.com/guide/developing/tools/proguard.html
|
||||
|
||||
# Add any project specific keep options here:
|
||||
|
||||
# If your project uses WebView with JS, uncomment the following
|
||||
# and specify the fully qualified class name to the JavaScript interface
|
||||
# class:
|
||||
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
|
||||
# public *;
|
||||
#}
|
||||
|
||||
# Disabling obfuscation is useful if you collect stack traces from production crashes
|
||||
# (unless you are using a system that supports de-obfuscate the stack traces).
|
||||
-dontobfuscate
|
||||
|
||||
# React Native
|
||||
|
||||
# Keep our interfaces so they can be used by other ProGuard rules.
|
||||
# See http://sourceforge.net/p/proguard/bugs/466/
|
||||
-keep,allowobfuscation @interface com.facebook.proguard.annotations.DoNotStrip
|
||||
-keep,allowobfuscation @interface com.facebook.proguard.annotations.KeepGettersAndSetters
|
||||
-keep,allowobfuscation @interface com.facebook.common.internal.DoNotStrip
|
||||
|
||||
# Do not strip any method/class that is annotated with @DoNotStrip
|
||||
-keep @com.facebook.proguard.annotations.DoNotStrip class *
|
||||
-keep @com.facebook.common.internal.DoNotStrip class *
|
||||
-keepclassmembers class * {
|
||||
@com.facebook.proguard.annotations.DoNotStrip *;
|
||||
@com.facebook.common.internal.DoNotStrip *;
|
||||
}
|
||||
|
||||
-keepclassmembers @com.facebook.proguard.annotations.KeepGettersAndSetters class * {
|
||||
void set*(***);
|
||||
*** get*();
|
||||
}
|
||||
|
||||
-keep class * extends com.facebook.react.bridge.JavaScriptModule { *; }
|
||||
-keep class * extends com.facebook.react.bridge.NativeModule { *; }
|
||||
-keepclassmembers,includedescriptorclasses class * { native <methods>; }
|
||||
-keepclassmembers class * { @com.facebook.react.uimanager.UIProp <fields>; }
|
||||
-keepclassmembers class * { @com.facebook.react.uimanager.annotations.ReactProp <methods>; }
|
||||
-keepclassmembers class * { @com.facebook.react.uimanager.annotations.ReactPropGroup <methods>; }
|
||||
|
||||
-dontwarn com.facebook.react.**
|
||||
|
||||
# TextLayoutBuilder uses a non-public Android constructor within StaticLayout.
|
||||
# See libs/proxy/src/main/java/com/facebook/fbui/textlayoutbuilder/proxy for details.
|
||||
-dontwarn android.text.StaticLayout
|
||||
|
||||
# okhttp
|
||||
|
||||
-keepattributes Signature
|
||||
-keepattributes *Annotation*
|
||||
-keep class okhttp3.** { *; }
|
||||
-keep interface okhttp3.** { *; }
|
||||
-dontwarn okhttp3.**
|
||||
|
||||
# okio
|
||||
|
||||
-keep class sun.misc.Unsafe { *; }
|
||||
-dontwarn java.nio.file.*
|
||||
-dontwarn org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement
|
||||
-dontwarn okio.**
|
||||
|
||||
8
examples/android/app/src/debug/AndroidManifest.xml
Normal file
@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools">
|
||||
|
||||
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
|
||||
|
||||
<application android:usesCleartextTraffic="true" tools:targetApi="28" tools:ignore="GoogleAppIndexingWarning" />
|
||||
</manifest>
|
||||
@ -0,0 +1,67 @@
|
||||
package com.example;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import com.facebook.flipper.android.AndroidFlipperClient;
|
||||
import com.facebook.flipper.android.utils.FlipperUtils;
|
||||
import com.facebook.flipper.core.FlipperClient;
|
||||
import com.facebook.flipper.plugins.crashreporter.CrashReporterPlugin;
|
||||
import com.facebook.flipper.plugins.databases.DatabasesFlipperPlugin;
|
||||
import com.facebook.flipper.plugins.fresco.FrescoFlipperPlugin;
|
||||
import com.facebook.flipper.plugins.inspector.DescriptorMapping;
|
||||
import com.facebook.flipper.plugins.inspector.InspectorFlipperPlugin;
|
||||
import com.facebook.flipper.plugins.network.FlipperOkhttpInterceptor;
|
||||
import com.facebook.flipper.plugins.network.NetworkFlipperPlugin;
|
||||
import com.facebook.flipper.plugins.react.ReactFlipperPlugin;
|
||||
import com.facebook.flipper.plugins.sharedpreferences.SharedPreferencesFlipperPlugin;
|
||||
import com.facebook.react.ReactInstanceManager;
|
||||
import com.facebook.react.bridge.ReactContext;
|
||||
import com.facebook.react.modules.network.NetworkingModule;
|
||||
import okhttp3.OkHttpClient;
|
||||
|
||||
public class ReactNativeFlipper {
|
||||
public static void initializeFlipper(Context context, ReactInstanceManager reactInstanceManager) {
|
||||
if (FlipperUtils.shouldEnableFlipper(context)) {
|
||||
final FlipperClient client = AndroidFlipperClient.getInstance(context);
|
||||
|
||||
client.addPlugin(new InspectorFlipperPlugin(context, DescriptorMapping.withDefaults()));
|
||||
client.addPlugin(new ReactFlipperPlugin());
|
||||
client.addPlugin(new DatabasesFlipperPlugin(context));
|
||||
client.addPlugin(new SharedPreferencesFlipperPlugin(context));
|
||||
client.addPlugin(CrashReporterPlugin.getInstance());
|
||||
|
||||
NetworkFlipperPlugin networkFlipperPlugin = new NetworkFlipperPlugin();
|
||||
NetworkingModule.setCustomClientBuilder(
|
||||
new NetworkingModule.CustomClientBuilder() {
|
||||
@Override
|
||||
public void apply(OkHttpClient.Builder builder) {
|
||||
builder.addNetworkInterceptor(new FlipperOkhttpInterceptor(networkFlipperPlugin));
|
||||
}
|
||||
});
|
||||
client.addPlugin(networkFlipperPlugin);
|
||||
client.start();
|
||||
|
||||
// Fresco Plugin needs to ensure that ImagePipelineFactory is initialized
|
||||
// Hence we run if after all native modules have been initialized
|
||||
ReactContext reactContext = reactInstanceManager.getCurrentReactContext();
|
||||
if (reactContext == null) {
|
||||
reactInstanceManager.addReactInstanceEventListener(
|
||||
new ReactInstanceManager.ReactInstanceEventListener() {
|
||||
@Override
|
||||
public void onReactContextInitialized(ReactContext reactContext) {
|
||||
reactInstanceManager.removeReactInstanceEventListener(this);
|
||||
reactContext.runOnNativeModulesQueueThread(
|
||||
new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
client.addPlugin(new FrescoFlipperPlugin());
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
} else {
|
||||
client.addPlugin(new FrescoFlipperPlugin());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,20 +1,14 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.examples"
|
||||
android:versionCode="1"
|
||||
android:versionName="1.0">
|
||||
package="com.examples">
|
||||
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
|
||||
|
||||
<uses-sdk
|
||||
android:minSdkVersion="16"
|
||||
android:targetSdkVersion="22" />
|
||||
|
||||
<application
|
||||
android:name=".MainApplication"
|
||||
android:allowBackup="true"
|
||||
android:label="@string/app_name"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:roundIcon="@mipmap/ic_launcher_round"
|
||||
android:allowBackup="false"
|
||||
android:theme="@style/AppTheme">
|
||||
<activity
|
||||
android:name=".MainActivity"
|
||||
|
||||
@ -1,14 +1,19 @@
|
||||
package com.examples;
|
||||
|
||||
import android.app.Application;
|
||||
import android.content.Context;
|
||||
import android.util.Log;
|
||||
|
||||
import com.facebook.react.PackageList;
|
||||
import com.facebook.hermes.reactexecutor.HermesExecutorFactory;
|
||||
import com.facebook.react.bridge.JavaScriptExecutorFactory;
|
||||
import com.facebook.react.ReactApplication;
|
||||
import com.facebook.react.ReactInstanceManager;
|
||||
import com.facebook.react.ReactNativeHost;
|
||||
import com.facebook.react.ReactPackage;
|
||||
import com.facebook.react.shell.MainReactPackage;
|
||||
import com.facebook.soloader.SoLoader;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.List;
|
||||
|
||||
public class MainApplication extends Application implements ReactApplication {
|
||||
@ -21,9 +26,16 @@ public class MainApplication extends Application implements ReactApplication {
|
||||
|
||||
@Override
|
||||
protected List<ReactPackage> getPackages() {
|
||||
return Arrays.<ReactPackage>asList(
|
||||
new MainReactPackage()
|
||||
);
|
||||
@SuppressWarnings("UnnecessaryLocalVariable")
|
||||
List<ReactPackage> packages = new PackageList(this).getPackages();
|
||||
// Packages that cannot be autolinked yet can be added manually here, for example:
|
||||
// packages.add(new MyReactNativePackage());
|
||||
return packages;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getJSMainModuleName() {
|
||||
return "index";
|
||||
}
|
||||
};
|
||||
|
||||
@ -36,5 +48,36 @@ public class MainApplication extends Application implements ReactApplication {
|
||||
public void onCreate() {
|
||||
super.onCreate();
|
||||
SoLoader.init(this, /* native exopackage */ false);
|
||||
initializeFlipper(this, getReactNativeHost().getReactInstanceManager());
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads Flipper in React Native templates. Call this in the onCreate method
|
||||
* with something like initializeFlipper(this,
|
||||
* getReactNativeHost().getReactInstanceManager());
|
||||
*
|
||||
* @param context
|
||||
*/
|
||||
private static void initializeFlipper(Context context, ReactInstanceManager reactInstanceManager) {
|
||||
if (BuildConfig.DEBUG) {
|
||||
try {
|
||||
/*
|
||||
* We use reflection here to pick up the class that initializes Flipper, since
|
||||
* Flipper library is not available in release mode
|
||||
*/
|
||||
Class<?> aClass = Class.forName("com.example.ReactNativeFlipper");
|
||||
aClass.getMethod("initializeFlipper", Context.class, ReactInstanceManager.class).invoke(null, context,
|
||||
reactInstanceManager);
|
||||
} catch (ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
} catch (NoSuchMethodException e) {
|
||||
e.printStackTrace();
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
} catch (InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
Before Width: | Height: | Size: 3.3 KiB After Width: | Height: | Size: 3.0 KiB |
|
After Width: | Height: | Size: 4.9 KiB |
|
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 2.0 KiB |
|
After Width: | Height: | Size: 2.8 KiB |
|
Before Width: | Height: | Size: 4.7 KiB After Width: | Height: | Size: 4.5 KiB |
|
After Width: | Height: | Size: 6.9 KiB |
|
Before Width: | Height: | Size: 7.5 KiB After Width: | Height: | Size: 6.3 KiB |
|
After Width: | Height: | Size: 10 KiB |
BIN
examples/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
Normal file
|
After Width: | Height: | Size: 9.0 KiB |
|
After Width: | Height: | Size: 15 KiB |
@ -3,6 +3,7 @@
|
||||
<!-- Base application theme. -->
|
||||
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
|
||||
<!-- Customize your theme here. -->
|
||||
<item name="android:textColor">#000000</item>
|
||||
</style>
|
||||
|
||||
</resources>
|
||||
|
||||
@ -1,11 +1,19 @@
|
||||
// Top-level build file where you can add configuration options common to all sub-projects/modules.
|
||||
|
||||
buildscript {
|
||||
ext {
|
||||
buildToolsVersion = "28.0.3"
|
||||
minSdkVersion = 16
|
||||
compileSdkVersion = 28
|
||||
targetSdkVersion = 28
|
||||
supportLibVersion = "28.0.0"
|
||||
}
|
||||
repositories {
|
||||
google()
|
||||
jcenter()
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:2.2.3'
|
||||
classpath("com.android.tools.build:gradle:3.4.1")
|
||||
|
||||
// NOTE: Do not place your application dependencies here; they belong
|
||||
// in the individual module build.gradle files
|
||||
@ -15,10 +23,16 @@ buildscript {
|
||||
allprojects {
|
||||
repositories {
|
||||
mavenLocal()
|
||||
jcenter()
|
||||
maven {
|
||||
// All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
|
||||
url "$rootDir/../node_modules/react-native/android"
|
||||
url("$rootDir/../node_modules/react-native/android")
|
||||
}
|
||||
maven {
|
||||
// Android JSC is installed from npm
|
||||
url("$rootDir/../node_modules/jsc-android/dist")
|
||||
}
|
||||
|
||||
google()
|
||||
jcenter()
|
||||
}
|
||||
}
|
||||
|
||||
@ -17,4 +17,8 @@
|
||||
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
|
||||
# org.gradle.parallel=true
|
||||
|
||||
android.useDeprecatedNdk=true
|
||||
android.useAndroidX=true
|
||||
android.enableJetifier=true
|
||||
|
||||
# Version of flipper SDK to use with React Native
|
||||
FLIPPER_VERSION=0.23.4
|
||||
|
||||
BIN
examples/android/gradle/wrapper/gradle-wrapper.jar
vendored
@ -1,5 +1,5 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-all.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-all.zip
|
||||
|
||||
126
examples/android/gradlew
vendored
@ -1,4 +1,20 @@
|
||||
#!/usr/bin/env bash
|
||||
#!/usr/bin/env sh
|
||||
|
||||
#
|
||||
# Copyright 2015 the original author or authors.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
##############################################################################
|
||||
##
|
||||
@ -6,47 +22,6 @@
|
||||
##
|
||||
##############################################################################
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS=""
|
||||
|
||||
APP_NAME="Gradle"
|
||||
APP_BASE_NAME=`basename "$0"`
|
||||
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||
MAX_FD="maximum"
|
||||
|
||||
warn ( ) {
|
||||
echo "$*"
|
||||
}
|
||||
|
||||
die ( ) {
|
||||
echo
|
||||
echo "$*"
|
||||
echo
|
||||
exit 1
|
||||
}
|
||||
|
||||
# OS specific support (must be 'true' or 'false').
|
||||
cygwin=false
|
||||
msys=false
|
||||
darwin=false
|
||||
case "`uname`" in
|
||||
CYGWIN* )
|
||||
cygwin=true
|
||||
;;
|
||||
Darwin* )
|
||||
darwin=true
|
||||
;;
|
||||
MINGW* )
|
||||
msys=true
|
||||
;;
|
||||
esac
|
||||
|
||||
# For Cygwin, ensure paths are in UNIX format before anything is touched.
|
||||
if $cygwin ; then
|
||||
[ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
|
||||
fi
|
||||
|
||||
# Attempt to set APP_HOME
|
||||
# Resolve links: $0 may be a link
|
||||
PRG="$0"
|
||||
@ -61,9 +36,49 @@ while [ -h "$PRG" ] ; do
|
||||
fi
|
||||
done
|
||||
SAVED="`pwd`"
|
||||
cd "`dirname \"$PRG\"`/" >&-
|
||||
cd "`dirname \"$PRG\"`/" >/dev/null
|
||||
APP_HOME="`pwd -P`"
|
||||
cd "$SAVED" >&-
|
||||
cd "$SAVED" >/dev/null
|
||||
|
||||
APP_NAME="Gradle"
|
||||
APP_BASE_NAME=`basename "$0"`
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||
MAX_FD="maximum"
|
||||
|
||||
warn () {
|
||||
echo "$*"
|
||||
}
|
||||
|
||||
die () {
|
||||
echo
|
||||
echo "$*"
|
||||
echo
|
||||
exit 1
|
||||
}
|
||||
|
||||
# OS specific support (must be 'true' or 'false').
|
||||
cygwin=false
|
||||
msys=false
|
||||
darwin=false
|
||||
nonstop=false
|
||||
case "`uname`" in
|
||||
CYGWIN* )
|
||||
cygwin=true
|
||||
;;
|
||||
Darwin* )
|
||||
darwin=true
|
||||
;;
|
||||
MINGW* )
|
||||
msys=true
|
||||
;;
|
||||
NONSTOP* )
|
||||
nonstop=true
|
||||
;;
|
||||
esac
|
||||
|
||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||
|
||||
@ -90,7 +105,7 @@ location of your Java installation."
|
||||
fi
|
||||
|
||||
# Increase the maximum file descriptors if we can.
|
||||
if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
|
||||
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
|
||||
MAX_FD_LIMIT=`ulimit -H -n`
|
||||
if [ $? -eq 0 ] ; then
|
||||
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
|
||||
@ -114,6 +129,7 @@ fi
|
||||
if $cygwin ; then
|
||||
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
||||
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
||||
JAVACMD=`cygpath --unix "$JAVACMD"`
|
||||
|
||||
# We build the pattern for arguments to be converted via cygpath
|
||||
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
|
||||
@ -154,11 +170,19 @@ if $cygwin ; then
|
||||
esac
|
||||
fi
|
||||
|
||||
# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
|
||||
function splitJvmOpts() {
|
||||
JVM_OPTS=("$@")
|
||||
# Escape application args
|
||||
save () {
|
||||
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
|
||||
echo " "
|
||||
}
|
||||
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
|
||||
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
|
||||
APP_ARGS=$(save "$@")
|
||||
|
||||
exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
|
||||
# Collect all arguments for the java command, following the shell quoting and substitution rules
|
||||
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
|
||||
|
||||
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
|
||||
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
|
||||
cd "$(dirname "$0")"
|
||||
fi
|
||||
|
||||
exec "$JAVACMD" "$@"
|
||||
|
||||
30
examples/android/gradlew.bat
vendored
@ -1,3 +1,19 @@
|
||||
@rem
|
||||
@rem Copyright 2015 the original author or authors.
|
||||
@rem
|
||||
@rem Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@rem you may not use this file except in compliance with the License.
|
||||
@rem You may obtain a copy of the License at
|
||||
@rem
|
||||
@rem http://www.apache.org/licenses/LICENSE-2.0
|
||||
@rem
|
||||
@rem Unless required by applicable law or agreed to in writing, software
|
||||
@rem distributed under the License is distributed on an "AS IS" BASIS,
|
||||
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@rem See the License for the specific language governing permissions and
|
||||
@rem limitations under the License.
|
||||
@rem
|
||||
|
||||
@if "%DEBUG%" == "" @echo off
|
||||
@rem ##########################################################################
|
||||
@rem
|
||||
@ -8,14 +24,14 @@
|
||||
@rem Set local scope for the variables with windows NT shell
|
||||
if "%OS%"=="Windows_NT" setlocal
|
||||
|
||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
set DEFAULT_JVM_OPTS=
|
||||
|
||||
set DIRNAME=%~dp0
|
||||
if "%DIRNAME%" == "" set DIRNAME=.
|
||||
set APP_BASE_NAME=%~n0
|
||||
set APP_HOME=%DIRNAME%
|
||||
|
||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
|
||||
|
||||
@rem Find java.exe
|
||||
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||
|
||||
@ -46,10 +62,9 @@ echo location of your Java installation.
|
||||
goto fail
|
||||
|
||||
:init
|
||||
@rem Get command-line arguments, handling Windowz variants
|
||||
@rem Get command-line arguments, handling Windows variants
|
||||
|
||||
if not "%OS%" == "Windows_NT" goto win9xME_args
|
||||
if "%@eval[2+2]" == "4" goto 4NT_args
|
||||
|
||||
:win9xME_args
|
||||
@rem Slurp the command line arguments.
|
||||
@ -60,11 +75,6 @@ set _SKIP=2
|
||||
if "x%~1" == "x" goto execute
|
||||
|
||||
set CMD_LINE_ARGS=%*
|
||||
goto execute
|
||||
|
||||
:4NT_args
|
||||
@rem Get arguments from the 4NT Shell from JP Software
|
||||
set CMD_LINE_ARGS=%$
|
||||
|
||||
:execute
|
||||
@rem Setup the command line
|
||||
|
||||
@ -1,8 +0,0 @@
|
||||
keystore(
|
||||
name = "debug",
|
||||
properties = "debug.keystore.properties",
|
||||
store = "debug.keystore",
|
||||
visibility = [
|
||||
"PUBLIC",
|
||||
],
|
||||
)
|
||||
@ -1,4 +0,0 @@
|
||||
key.store=debug.keystore
|
||||
key.alias=androiddebugkey
|
||||
key.store.password=android
|
||||
key.alias.password=android
|
||||
@ -1,3 +1,3 @@
|
||||
rootProject.name = 'examples'
|
||||
|
||||
apply from: file("../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesSettingsGradle(settings)
|
||||
include ':app'
|
||||
|
||||
3
examples/babel.config.js
Normal file
@ -0,0 +1,3 @@
|
||||
module.exports = {
|
||||
presets: ['module:metro-react-native-babel-preset'],
|
||||
};
|
||||
44
examples/components/AutoPlay/index.tsx
Normal file
@ -0,0 +1,44 @@
|
||||
import React from 'react'
|
||||
import { Text, View, StyleSheet } from 'react-native'
|
||||
import Swiper from 'react-native-swiper'
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
wrapper: {},
|
||||
slide1: {
|
||||
flex: 1,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
backgroundColor: '#9DD6EB'
|
||||
},
|
||||
slide2: {
|
||||
flex: 1,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
backgroundColor: '#97CAE5'
|
||||
},
|
||||
slide3: {
|
||||
flex: 1,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
backgroundColor: '#92BBD9'
|
||||
},
|
||||
text: {
|
||||
color: '#fff',
|
||||
fontSize: 30,
|
||||
fontWeight: 'bold'
|
||||
}
|
||||
})
|
||||
|
||||
export default () => (
|
||||
<Swiper style={styles.wrapper} autoplay>
|
||||
<View testID="Hello" style={styles.slide1}>
|
||||
<Text style={styles.text}>Hello Swiper</Text>
|
||||
</View>
|
||||
<View testID="Beautiful" style={styles.slide2}>
|
||||
<Text style={styles.text}>Beautiful</Text>
|
||||
</View>
|
||||
<View testID="Simple" style={styles.slide3}>
|
||||
<Text style={styles.text}>And simple</Text>
|
||||
</View>
|
||||
</Swiper>
|
||||
)
|
||||
@ -1,13 +1,9 @@
|
||||
import React from 'react'
|
||||
import {
|
||||
Text,
|
||||
View
|
||||
} from 'react-native'
|
||||
import { Text, View } from 'react-native'
|
||||
import Swiper from 'react-native-swiper'
|
||||
|
||||
var styles = {
|
||||
wrapper: {
|
||||
},
|
||||
wrapper: {},
|
||||
slide1: {
|
||||
flex: 1,
|
||||
justifyContent: 'center',
|
||||
@ -33,14 +29,16 @@ var styles = {
|
||||
}
|
||||
}
|
||||
|
||||
export default () => <Swiper style={styles.wrapper} showsButtons>
|
||||
<View style={styles.slide1}>
|
||||
<Text style={styles.text}>Hello Swiper</Text>
|
||||
</View>
|
||||
<View style={styles.slide2}>
|
||||
<Text style={styles.text}>Beautiful</Text>
|
||||
</View>
|
||||
<View style={styles.slide3}>
|
||||
<Text style={styles.text}>And simple</Text>
|
||||
</View>
|
||||
</Swiper>
|
||||
export default () => (
|
||||
<Swiper style={styles.wrapper} showsButtons loop={false}>
|
||||
<View testID="Hello" style={styles.slide1}>
|
||||
<Text style={styles.text}>Hello Swiper</Text>
|
||||
</View>
|
||||
<View testID="Beautiful" style={styles.slide2}>
|
||||
<Text style={styles.text}>Beautiful</Text>
|
||||
</View>
|
||||
<View testID="Simple" style={styles.slide3}>
|
||||
<Text style={styles.text}>And simple</Text>
|
||||
</View>
|
||||
</Swiper>
|
||||
)
|
||||
|
||||
51
examples/components/DisableButton/index.tsx
Normal file
@ -0,0 +1,51 @@
|
||||
import React from 'react'
|
||||
import { Text, View } from 'react-native'
|
||||
import Swiper from 'react-native-swiper'
|
||||
|
||||
const styles = {
|
||||
wrapper: {},
|
||||
slide1: {
|
||||
flex: 1,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
backgroundColor: '#9DD6EB'
|
||||
},
|
||||
slide2: {
|
||||
flex: 1,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
backgroundColor: '#97CAE5'
|
||||
},
|
||||
slide3: {
|
||||
flex: 1,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
backgroundColor: '#92BBD9'
|
||||
},
|
||||
text: {
|
||||
color: '#fff',
|
||||
fontSize: 30,
|
||||
fontWeight: 'bold'
|
||||
}
|
||||
}
|
||||
|
||||
export default () => (
|
||||
<Swiper
|
||||
style={styles.wrapper}
|
||||
showsButtons
|
||||
// disable button onPress behavior
|
||||
disablePrevButton
|
||||
disableNextButton
|
||||
loop={false}
|
||||
>
|
||||
<View style={styles.slide1}>
|
||||
<Text style={styles.text}>Hello Swiper</Text>
|
||||
</View>
|
||||
<View style={styles.slide2}>
|
||||
<Text style={styles.text}>Beautiful</Text>
|
||||
</View>
|
||||
<View style={styles.slide3}>
|
||||
<Text style={styles.text}>And simple</Text>
|
||||
</View>
|
||||
</Swiper>
|
||||
)
|
||||
@ -1,8 +1,5 @@
|
||||
import React, { Component } from 'react'
|
||||
import {
|
||||
Text,
|
||||
View
|
||||
} from 'react-native'
|
||||
import { Text, View } from 'react-native'
|
||||
import Swiper from 'react-native-swiper'
|
||||
|
||||
const styles = {
|
||||
@ -35,13 +32,13 @@ const styles = {
|
||||
}
|
||||
|
||||
export default class extends Component {
|
||||
constructor (props) {
|
||||
constructor(props) {
|
||||
super(props)
|
||||
this.state = {
|
||||
items: []
|
||||
}
|
||||
}
|
||||
componentDidMount () {
|
||||
componentDidMount() {
|
||||
this.setState({
|
||||
items: [
|
||||
{ title: 'Hello Swiper', css: styles.slide1 },
|
||||
@ -50,7 +47,7 @@ export default class extends Component {
|
||||
]
|
||||
})
|
||||
}
|
||||
render () {
|
||||
render() {
|
||||
return (
|
||||
<Swiper showsButtons>
|
||||
{this.state.items.map((item, key) => {
|
||||
|
||||
@ -1,95 +0,0 @@
|
||||
import React, { Component } from 'react'
|
||||
import {
|
||||
Text,
|
||||
View,
|
||||
Image,
|
||||
Dimensions
|
||||
} from 'react-native'
|
||||
import Swiper from 'react-native-swiper'
|
||||
const { width } = Dimensions.get('window')
|
||||
const loading = require('./img/loading.gif')
|
||||
|
||||
const styles = {
|
||||
wrapper: {
|
||||
},
|
||||
|
||||
slide: {
|
||||
flex: 1,
|
||||
justifyContent: 'center',
|
||||
backgroundColor: 'transparent'
|
||||
},
|
||||
image: {
|
||||
width,
|
||||
flex: 1,
|
||||
backgroundColor: 'transparent'
|
||||
},
|
||||
|
||||
loadingView: {
|
||||
position: 'absolute',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
left: 0,
|
||||
right: 0,
|
||||
top: 0,
|
||||
bottom: 0,
|
||||
backgroundColor: 'rgba(0,0,0,.5)'
|
||||
},
|
||||
|
||||
loadingImage: {
|
||||
width: 60,
|
||||
height: 60
|
||||
}
|
||||
}
|
||||
|
||||
const Slide = props => {
|
||||
return (<View style={styles.slide}>
|
||||
<Image onLoad={props.loadHandle.bind(null, props.i)} style={styles.image} source={{uri: props.uri}} />
|
||||
{
|
||||
!props.loaded && <View style={styles.loadingView}>
|
||||
<Image style={styles.loadingImage} source={loading} />
|
||||
</View>
|
||||
}
|
||||
</View>)
|
||||
}
|
||||
|
||||
export default class extends Component {
|
||||
constructor (props) {
|
||||
super(props)
|
||||
this.state = {
|
||||
imgList: [
|
||||
'https://gitlab.pro/yuji/demo/uploads/d6133098b53fe1a5f3c5c00cf3c2d670/DVrj5Hz.jpg_1',
|
||||
'https://gitlab.pro/yuji/demo/uploads/2d5122a2504e5cbdf01f4fcf85f2594b/Mwb8VWH.jpg',
|
||||
'https://gitlab.pro/yuji/demo/uploads/4421f77012d43a0b4e7cfbe1144aac7c/XFVzKhq.jpg',
|
||||
'https://gitlab.pro/yuji/demo/uploads/576ef91941b0bda5761dde6914dae9f0/kD3eeHe.jpg'
|
||||
],
|
||||
loadQueue: [0, 0, 0, 0]
|
||||
}
|
||||
this.loadHandle = this.loadHandle.bind(this)
|
||||
}
|
||||
loadHandle (i) {
|
||||
let loadQueue = this.state.loadQueue
|
||||
loadQueue[i] = 1
|
||||
this.setState({
|
||||
loadQueue
|
||||
})
|
||||
}
|
||||
render () {
|
||||
return (
|
||||
<View style={{flex: 1}}>
|
||||
<Swiper loadMinimal loadMinimalSize={1} style={styles.wrapper} loop={false}>
|
||||
{
|
||||
this.state.imgList.map((item, i) => <Slide
|
||||
loadHandle={this.loadHandle}
|
||||
loaded={!!this.state.loadQueue[i]}
|
||||
uri={item}
|
||||
i={i}
|
||||
key={i} />)
|
||||
}
|
||||
</Swiper>
|
||||
<View>
|
||||
<Text>Current Loaded Images: {this.state.loadQueue}</Text>
|
||||
</View>
|
||||
</View>
|
||||
)
|
||||
}
|
||||
}
|
||||
118
examples/components/LoadMinimal/index.tsx
Normal file
@ -0,0 +1,118 @@
|
||||
import React, { useState, useCallback } from 'react'
|
||||
import { Text, View, Image, Dimensions, StyleSheet } from 'react-native'
|
||||
import Swiper from 'react-native-swiper'
|
||||
import { Model } from 'react-model'
|
||||
const { width } = Dimensions.get('window')
|
||||
const loading = require('./img/loading.gif')
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
wrapper: {},
|
||||
|
||||
slide: {
|
||||
flex: 1,
|
||||
justifyContent: 'center',
|
||||
backgroundColor: 'transparent'
|
||||
},
|
||||
image: {
|
||||
width,
|
||||
flex: 1,
|
||||
backgroundColor: 'transparent'
|
||||
},
|
||||
|
||||
loadingView: {
|
||||
position: 'absolute',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
left: 0,
|
||||
right: 0,
|
||||
top: 0,
|
||||
bottom: 0,
|
||||
backgroundColor: 'rgba(0,0,0,.5)'
|
||||
},
|
||||
|
||||
loadingImage: {
|
||||
width: 60,
|
||||
height: 60
|
||||
}
|
||||
})
|
||||
|
||||
interface SlideState {
|
||||
imgList: string[]
|
||||
loadQueue: number[]
|
||||
}
|
||||
|
||||
interface SlideActions {
|
||||
loaded: number
|
||||
}
|
||||
|
||||
const SlideSchema: ModelType<SlideState, SlideActions> = {
|
||||
state: {
|
||||
imgList: [
|
||||
'https://www.mordeo.org/files/uploads/2016/10/Cute-Angry-Birds-Mobile-Wallpaper.jpg',
|
||||
'http://www.glittergraphics.org/img/74/743564/cute-wallpapers-for-mobile.jpg',
|
||||
'https://wallpapercave.com/wp/wp2807409.jpg',
|
||||
'https://preppywallpapers.com/wp-content/uploads/2018/08/Gorgeous-iPhone-Wallpaper-Collection-11.jpg'
|
||||
],
|
||||
loadQueue: [0, 0, 0, 0]
|
||||
},
|
||||
actions: {
|
||||
loaded: index => {
|
||||
return state => {
|
||||
state.loadQueue[index] = 1
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const Slide = props => {
|
||||
return (
|
||||
<View style={styles.slide}>
|
||||
<Image
|
||||
onLoad={() => {
|
||||
props.loadHandle(props.i)
|
||||
}}
|
||||
style={styles.image}
|
||||
source={{ uri: props.uri }}
|
||||
/>
|
||||
{!props.loaded && (
|
||||
<View style={styles.loadingView}>
|
||||
<Image style={styles.loadingImage} source={loading} />
|
||||
</View>
|
||||
)}
|
||||
</View>
|
||||
)
|
||||
}
|
||||
|
||||
const Page = () => {
|
||||
const [{ useStore }] = useState(() => Model(SlideSchema))
|
||||
const [state, actions] = useStore()
|
||||
const loadHandle = useCallback((i: number) => {
|
||||
actions.loaded(i)
|
||||
}, [])
|
||||
return (
|
||||
<View style={{ flex: 1 }}>
|
||||
<Swiper
|
||||
loadMinimal
|
||||
loadMinimalSize={1}
|
||||
// index={0}
|
||||
style={styles.wrapper}
|
||||
loop={true}
|
||||
>
|
||||
{state.imgList.map((item, i) => (
|
||||
<Slide
|
||||
loadHandle={loadHandle}
|
||||
uri={item}
|
||||
i={i}
|
||||
key={i}
|
||||
loaded={state.loadQueue[i]}
|
||||
/>
|
||||
))}
|
||||
</Swiper>
|
||||
<View>
|
||||
<Text>Current Loaded Images: {state.loadQueue}</Text>
|
||||
</View>
|
||||
</View>
|
||||
)
|
||||
}
|
||||
|
||||
export default Page
|
||||
44
examples/components/Loop/index.tsx
Normal file
@ -0,0 +1,44 @@
|
||||
import React from 'react'
|
||||
import { Text, View, StyleSheet } from 'react-native'
|
||||
import Swiper from 'react-native-swiper'
|
||||
|
||||
var styles = StyleSheet.create({
|
||||
wrapper: {},
|
||||
slide1: {
|
||||
flex: 1,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
backgroundColor: '#9DD6EB'
|
||||
},
|
||||
slide2: {
|
||||
flex: 1,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
backgroundColor: '#97CAE5'
|
||||
},
|
||||
slide3: {
|
||||
flex: 1,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
backgroundColor: '#92BBD9'
|
||||
},
|
||||
text: {
|
||||
color: '#fff',
|
||||
fontSize: 30,
|
||||
fontWeight: 'bold'
|
||||
}
|
||||
})
|
||||
|
||||
export default () => (
|
||||
<Swiper style={styles.wrapper} loop={true} index={0} showsButtons>
|
||||
<View style={styles.slide1}>
|
||||
<Text style={styles.text}>Hello Swiper</Text>
|
||||
</View>
|
||||
<View style={styles.slide2}>
|
||||
<Text style={styles.text}>Beautiful</Text>
|
||||
</View>
|
||||
<View style={styles.slide3}>
|
||||
<Text style={styles.text}>And simple</Text>
|
||||
</View>
|
||||
</Swiper>
|
||||
)
|
||||
77
examples/components/NestSwiper/index.tsx
Normal file
@ -0,0 +1,77 @@
|
||||
import React, { useRef, useState } from 'react'
|
||||
import { Text, View, StyleSheet, Dimensions } from 'react-native'
|
||||
import Swiper from 'react-native-swiper'
|
||||
|
||||
var styles = StyleSheet.create({
|
||||
wrapper: {},
|
||||
slide1: {
|
||||
flex: 1,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
backgroundColor: '#9DD6EB'
|
||||
},
|
||||
slide2: {
|
||||
flex: 1,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
backgroundColor: '#97CAE5'
|
||||
},
|
||||
slide3: {
|
||||
flex: 1,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
backgroundColor: '#92BBD9'
|
||||
},
|
||||
text: {
|
||||
color: '#fff',
|
||||
fontSize: 30,
|
||||
fontWeight: 'bold'
|
||||
}
|
||||
})
|
||||
|
||||
export default () => {
|
||||
const swiper = useRef(null)
|
||||
const [enable, setEnable] = useState(true)
|
||||
return (
|
||||
<Swiper
|
||||
ref={swiper}
|
||||
containerStyle={styles.wrapper}
|
||||
scrollEnabled={enable}
|
||||
index={0}
|
||||
showsButtons
|
||||
>
|
||||
<View style={{ flex: 1, height: Dimensions.get('window').height }}>
|
||||
<View style={{ height: 300 }}>
|
||||
<Swiper
|
||||
index={1}
|
||||
onTouchStart={e => {
|
||||
setEnable(false)
|
||||
}}
|
||||
onTouchEnd={e => {
|
||||
setEnable(true)
|
||||
}}
|
||||
onMomentumScrollEnd={e => {
|
||||
setEnable(true)
|
||||
}}
|
||||
>
|
||||
<View style={styles.slide1}>
|
||||
<Text style={styles.text}>Nested: Hello Swiper</Text>
|
||||
</View>
|
||||
<View style={styles.slide2}>
|
||||
<Text style={styles.text}>Nested: Beautiful</Text>
|
||||
</View>
|
||||
<View style={styles.slide3}>
|
||||
<Text style={styles.text}>Nested: And simple</Text>
|
||||
</View>
|
||||
</Swiper>
|
||||
</View>
|
||||
</View>
|
||||
<View style={styles.slide2}>
|
||||
<Text style={styles.text}>Beautiful</Text>
|
||||
</View>
|
||||
<View style={styles.slide3}>
|
||||
<Text style={styles.text}>And simple</Text>
|
||||
</View>
|
||||
</Swiper>
|
||||
)
|
||||
}
|
||||
@ -1,10 +1,5 @@
|
||||
import React, { Component } from 'react'
|
||||
import {
|
||||
View,
|
||||
Image,
|
||||
StatusBar,
|
||||
Dimensions
|
||||
} from 'react-native'
|
||||
import { View, Image, StatusBar, Dimensions } from 'react-native'
|
||||
import Swiper from 'react-native-swiper'
|
||||
const { width, height } = Dimensions.get('window')
|
||||
|
||||
@ -18,7 +13,7 @@ const styles = {
|
||||
backgroundColor: 'transparent'
|
||||
},
|
||||
container: {
|
||||
flex: 1,
|
||||
flex: 1
|
||||
},
|
||||
|
||||
imgBackground: {
|
||||
@ -30,38 +25,59 @@ const styles = {
|
||||
|
||||
image: {
|
||||
width,
|
||||
height,
|
||||
height
|
||||
}
|
||||
}
|
||||
|
||||
export default class extends Component {
|
||||
render () {
|
||||
render() {
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<StatusBar barStyle='light-content' />
|
||||
<Image
|
||||
source={require('./img/bg.jpg')}
|
||||
style={styles.imgBackground}
|
||||
/>
|
||||
<Swiper style={styles.wrapper}
|
||||
dot={<View style={{backgroundColor: 'rgba(255,255,255,.3)', width: 13, height: 13, borderRadius: 7, marginLeft: 7, marginRight: 7}} />}
|
||||
activeDot={<View style={{backgroundColor: '#fff', width: 13, height: 13, borderRadius: 7, marginLeft: 7, marginRight: 7}} />}
|
||||
<StatusBar barStyle="light-content" />
|
||||
<Image source={require('./img/bg.jpg')} style={styles.imgBackground} />
|
||||
<Swiper
|
||||
style={styles.wrapper}
|
||||
dot={
|
||||
<View
|
||||
style={{
|
||||
backgroundColor: 'rgba(255,255,255,.3)',
|
||||
width: 13,
|
||||
height: 13,
|
||||
borderRadius: 7,
|
||||
marginLeft: 7,
|
||||
marginRight: 7
|
||||
}}
|
||||
/>
|
||||
}
|
||||
activeDot={
|
||||
<View
|
||||
style={{
|
||||
backgroundColor: '#fff',
|
||||
width: 13,
|
||||
height: 13,
|
||||
borderRadius: 7,
|
||||
marginLeft: 7,
|
||||
marginRight: 7
|
||||
}}
|
||||
/>
|
||||
}
|
||||
paginationStyle={{
|
||||
bottom: 70
|
||||
}}
|
||||
loop={false}>
|
||||
loop={false}
|
||||
>
|
||||
<View style={styles.slide}>
|
||||
<Image
|
||||
style={styles.image}
|
||||
source={require('./img/1.jpg')}
|
||||
resizeMode='cover'
|
||||
resizeMode="cover"
|
||||
/>
|
||||
</View>
|
||||
<View style={styles.slide}>
|
||||
<Image
|
||||
style={styles.image}
|
||||
source={require('./img/2.jpg')}
|
||||
resizeMode='cover'
|
||||
resizeMode="cover"
|
||||
/>
|
||||
</View>
|
||||
<View style={styles.slide}>
|
||||
|
||||
@ -48,47 +48,62 @@ var styles = {
|
||||
|
||||
const renderPagination = (index, total, context) => {
|
||||
return (
|
||||
<View style={{
|
||||
position: 'absolute',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
top: 25,
|
||||
left: 0,
|
||||
right: 0
|
||||
}}>
|
||||
<View style={{
|
||||
borderRadius: 7,
|
||||
backgroundColor: 'rgba(255,255,255,.15)',
|
||||
padding: 3,
|
||||
paddingHorizontal: 7
|
||||
}}>
|
||||
<Text style={{
|
||||
color: '#fff',
|
||||
fontSize: 14
|
||||
}}>{index + 1} / {total}</Text>
|
||||
<View
|
||||
style={{
|
||||
position: 'absolute',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
top: 25,
|
||||
left: 0,
|
||||
right: 0
|
||||
}}
|
||||
>
|
||||
<View
|
||||
style={{
|
||||
borderRadius: 7,
|
||||
backgroundColor: 'rgba(255,255,255,.15)',
|
||||
padding: 3,
|
||||
paddingHorizontal: 7
|
||||
}}
|
||||
>
|
||||
<Text
|
||||
style={{
|
||||
color: '#fff',
|
||||
fontSize: 14
|
||||
}}
|
||||
>
|
||||
{index + 1} / {total}
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
)
|
||||
}
|
||||
|
||||
const Viewer = props => <Swiper index={props.index} style={styles.wrapper} renderPagination={renderPagination}>
|
||||
{
|
||||
props.imgList.map((item, i) => <View key={i} style={styles.slide}>
|
||||
<TouchableWithoutFeedback onPress={e => props.pressHandle()}>
|
||||
<PhotoView
|
||||
source={{uri: item}}
|
||||
resizeMode='contain'
|
||||
minimumZoomScale={0.5}
|
||||
maximumZoomScale={3}
|
||||
androidScaleType='center'
|
||||
style={styles.photo} />
|
||||
</TouchableWithoutFeedback>
|
||||
</View>)
|
||||
}
|
||||
</Swiper>
|
||||
const Viewer = props => (
|
||||
<Swiper
|
||||
index={props.index}
|
||||
style={styles.wrapper}
|
||||
renderPagination={renderPagination}
|
||||
>
|
||||
{props.imgList.map((item, i) => (
|
||||
<View key={i} style={styles.slide}>
|
||||
<TouchableWithoutFeedback onPress={e => props.pressHandle()}>
|
||||
<PhotoView
|
||||
source={{ uri: item }}
|
||||
resizeMode="contain"
|
||||
minimumZoomScale={0.5}
|
||||
maximumZoomScale={3}
|
||||
androidScaleType="center"
|
||||
style={styles.photo}
|
||||
/>
|
||||
</TouchableWithoutFeedback>
|
||||
</View>
|
||||
))}
|
||||
</Swiper>
|
||||
)
|
||||
|
||||
export default class extends Component {
|
||||
constructor (props) {
|
||||
constructor(props) {
|
||||
super(props)
|
||||
this.state = {
|
||||
imgList: [
|
||||
@ -102,30 +117,35 @@ export default class extends Component {
|
||||
this.viewerPressHandle = this.viewerPressHandle.bind(this)
|
||||
this.thumbPressHandle = this.thumbPressHandle.bind(this)
|
||||
}
|
||||
viewerPressHandle () {
|
||||
viewerPressHandle() {
|
||||
this.setState({
|
||||
showViewer: false
|
||||
})
|
||||
}
|
||||
thumbPressHandle (i) {
|
||||
thumbPressHandle(i) {
|
||||
this.setState({
|
||||
showIndex: i,
|
||||
showViewer: true
|
||||
})
|
||||
}
|
||||
render () {
|
||||
return (<View style={{position: 'relative'}}>
|
||||
{this.state.showViewer && <Viewer
|
||||
index={this.state.showIndex}
|
||||
pressHandle={this.viewerPressHandle}
|
||||
imgList={this.state.imgList} />}
|
||||
<View style={styles.thumbWrap}>
|
||||
{
|
||||
this.state.imgList.map((item, i) => <TouchableOpacity key={i} onPress={e => this.thumbPressHandle(i)}>
|
||||
<Image style={styles.thumb} source={{uri: item}} />
|
||||
</TouchableOpacity>)
|
||||
}
|
||||
render() {
|
||||
return (
|
||||
<View style={{ position: 'relative' }}>
|
||||
{this.state.showViewer && (
|
||||
<Viewer
|
||||
index={this.state.showIndex}
|
||||
pressHandle={this.viewerPressHandle}
|
||||
imgList={this.state.imgList}
|
||||
/>
|
||||
)}
|
||||
<View style={styles.thumbWrap}>
|
||||
{this.state.imgList.map((item, i) => (
|
||||
<TouchableOpacity key={i} onPress={e => this.thumbPressHandle(i)}>
|
||||
<Image style={styles.thumb} source={{ uri: item }} />
|
||||
</TouchableOpacity>
|
||||
))}
|
||||
</View>
|
||||
</View>
|
||||
</View>)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,10 +1,5 @@
|
||||
import React, { Component } from 'react'
|
||||
import {
|
||||
Text,
|
||||
View,
|
||||
Image,
|
||||
Dimensions
|
||||
} from 'react-native'
|
||||
import { Text, View, Image, Dimensions } from 'react-native'
|
||||
import Swiper from 'react-native-swiper'
|
||||
const { width } = Dimensions.get('window')
|
||||
|
||||
@ -13,8 +8,7 @@ const styles = {
|
||||
flex: 1
|
||||
},
|
||||
|
||||
wrapper: {
|
||||
},
|
||||
wrapper: {},
|
||||
|
||||
slide: {
|
||||
flex: 1,
|
||||
@ -56,7 +50,7 @@ const styles = {
|
||||
}
|
||||
|
||||
export default class extends Component {
|
||||
render () {
|
||||
render() {
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<Swiper style={styles.wrapper} height={200} horizontal={false} autoplay>
|
||||
@ -71,24 +65,92 @@ export default class extends Component {
|
||||
</View>
|
||||
</Swiper>
|
||||
|
||||
<Swiper style={styles.wrapper} height={240}
|
||||
onMomentumScrollEnd={(e, state, context) => console.log('index:', state.index)}
|
||||
dot={<View style={{backgroundColor: 'rgba(0,0,0,.2)', width: 5, height: 5, borderRadius: 4, marginLeft: 3, marginRight: 3, marginTop: 3, marginBottom: 3}} />}
|
||||
activeDot={<View style={{backgroundColor: '#000', width: 8, height: 8, borderRadius: 4, marginLeft: 3, marginRight: 3, marginTop: 3, marginBottom: 3}} />}
|
||||
<Swiper
|
||||
style={styles.wrapper}
|
||||
height={240}
|
||||
onMomentumScrollEnd={(e, state, context) =>
|
||||
console.log('index:', state.index)
|
||||
}
|
||||
dot={
|
||||
<View
|
||||
style={{
|
||||
backgroundColor: 'rgba(0,0,0,.2)',
|
||||
width: 5,
|
||||
height: 5,
|
||||
borderRadius: 4,
|
||||
marginLeft: 3,
|
||||
marginRight: 3,
|
||||
marginTop: 3,
|
||||
marginBottom: 3
|
||||
}}
|
||||
/>
|
||||
}
|
||||
activeDot={
|
||||
<View
|
||||
style={{
|
||||
backgroundColor: '#000',
|
||||
width: 8,
|
||||
height: 8,
|
||||
borderRadius: 4,
|
||||
marginLeft: 3,
|
||||
marginRight: 3,
|
||||
marginTop: 3,
|
||||
marginBottom: 3
|
||||
}}
|
||||
/>
|
||||
}
|
||||
paginationStyle={{
|
||||
bottom: -23, left: null, right: 10
|
||||
}} loop>
|
||||
<View style={styles.slide} title={<Text numberOfLines={1}>Aussie tourist dies at Bali hotel</Text>}>
|
||||
<Image resizeMode='stretch' style={styles.image} source={require('./img/1.jpg')} />
|
||||
bottom: -23,
|
||||
left: null,
|
||||
right: 10
|
||||
}}
|
||||
loop
|
||||
>
|
||||
<View
|
||||
style={styles.slide}
|
||||
title={
|
||||
<Text numberOfLines={1}>Aussie tourist dies at Bali hotel</Text>
|
||||
}
|
||||
>
|
||||
<Image
|
||||
resizeMode="stretch"
|
||||
style={styles.image}
|
||||
source={require('./img/1.jpg')}
|
||||
/>
|
||||
</View>
|
||||
<View style={styles.slide} title={<Text numberOfLines={1}>Big lie behind Nine’s new show</Text>}>
|
||||
<Image resizeMode='stretch' style={styles.image} source={require('./img/2.jpg')} />
|
||||
<View
|
||||
style={styles.slide}
|
||||
title={
|
||||
<Text numberOfLines={1}>Big lie behind Nine’s new show</Text>
|
||||
}
|
||||
>
|
||||
<Image
|
||||
resizeMode="stretch"
|
||||
style={styles.image}
|
||||
source={require('./img/2.jpg')}
|
||||
/>
|
||||
</View>
|
||||
<View style={styles.slide} title={<Text numberOfLines={1}>Why Stone split from Garfield</Text>}>
|
||||
<Image resizeMode='stretch' style={styles.image} source={require('./img/3.jpg')} />
|
||||
<View
|
||||
style={styles.slide}
|
||||
title={<Text numberOfLines={1}>Why Stone split from Garfield</Text>}
|
||||
>
|
||||
<Image
|
||||
resizeMode="stretch"
|
||||
style={styles.image}
|
||||
source={require('./img/3.jpg')}
|
||||
/>
|
||||
</View>
|
||||
<View style={styles.slide} title={<Text numberOfLines={1}>Learn from Kim K to land that job</Text>}>
|
||||
<Image resizeMode='stretch' style={styles.image} source={require('./img/4.jpg')} />
|
||||
<View
|
||||
style={styles.slide}
|
||||
title={
|
||||
<Text numberOfLines={1}>Learn from Kim K to land that job</Text>
|
||||
}
|
||||
>
|
||||
<Image
|
||||
resizeMode="stretch"
|
||||
style={styles.image}
|
||||
source={require('./img/4.jpg')}
|
||||
/>
|
||||
</View>
|
||||
</Swiper>
|
||||
</View>
|
||||
|
||||
@ -1,16 +1,10 @@
|
||||
import React, { Component } from 'react'
|
||||
import {
|
||||
Text,
|
||||
View,
|
||||
Image,
|
||||
Dimensions
|
||||
} from 'react-native'
|
||||
import { Text, View, Image, Dimensions } from 'react-native'
|
||||
import Swiper from 'react-native-swiper'
|
||||
const { width } = Dimensions.get('window')
|
||||
|
||||
const styles = {
|
||||
wrapper: {
|
||||
},
|
||||
wrapper: {},
|
||||
slide: {
|
||||
flex: 1,
|
||||
justifyContent: 'center',
|
||||
@ -47,26 +41,42 @@ const renderPagination = (index, total, context) => {
|
||||
}
|
||||
|
||||
export default class extends Component {
|
||||
render () {
|
||||
render() {
|
||||
return (
|
||||
<Swiper
|
||||
style={styles.wrapper}
|
||||
renderPagination={renderPagination}
|
||||
loop={false}
|
||||
<Swiper
|
||||
style={styles.wrapper}
|
||||
renderPagination={renderPagination}
|
||||
loop={false}
|
||||
>
|
||||
<View
|
||||
style={styles.slide}
|
||||
title={
|
||||
<Text numberOfLines={1}>Aussie tourist dies at Bali hotel</Text>
|
||||
}
|
||||
>
|
||||
<View style={styles.slide} title={<Text numberOfLines={1}>Aussie tourist dies at Bali hotel</Text>}>
|
||||
<Image style={styles.image} source={require('./img/1.jpg')} />
|
||||
</View>
|
||||
<View style={styles.slide} title={<Text numberOfLines={1}>Big lie behind Nine’s new show</Text>}>
|
||||
<Image style={styles.image} source={require('./img/2.jpg')} />
|
||||
</View>
|
||||
<View style={styles.slide} title={<Text numberOfLines={1}>Why Stone split from Garfield</Text>}>
|
||||
<Image style={styles.image} source={require('./img/3.jpg')} />
|
||||
</View>
|
||||
<View style={styles.slide} title={<Text numberOfLines={1}>Learn from Kim K to land that job</Text>}>
|
||||
<Image style={styles.image} source={require('./img/4.jpg')} />
|
||||
</View>
|
||||
</Swiper>
|
||||
<Image style={styles.image} source={require('./img/1.jpg')} />
|
||||
</View>
|
||||
<View
|
||||
style={styles.slide}
|
||||
title={<Text numberOfLines={1}>Big lie behind Nine’s new show</Text>}
|
||||
>
|
||||
<Image style={styles.image} source={require('./img/2.jpg')} />
|
||||
</View>
|
||||
<View
|
||||
style={styles.slide}
|
||||
title={<Text numberOfLines={1}>Why Stone split from Garfield</Text>}
|
||||
>
|
||||
<Image style={styles.image} source={require('./img/3.jpg')} />
|
||||
</View>
|
||||
<View
|
||||
style={styles.slide}
|
||||
title={
|
||||
<Text numberOfLines={1}>Learn from Kim K to land that job</Text>
|
||||
}
|
||||
>
|
||||
<Image style={styles.image} source={require('./img/4.jpg')} />
|
||||
</View>
|
||||
</Swiper>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
34
examples/e2e/AutoPlay.spec.js
Normal file
@ -0,0 +1,34 @@
|
||||
describe('AutoPlay', () => {
|
||||
beforeEach(async () => {
|
||||
await device.reloadReactNative()
|
||||
await element(by.id('AutoPlay')).tap()
|
||||
})
|
||||
|
||||
it('should execute scrollBy(1) every 2.5s', async () => {
|
||||
// Initial with first swiper
|
||||
await expect(element(by.id('Hello'))).toBeVisible()
|
||||
await expect(element(by.id('Beautiful'))).toBeNotVisible()
|
||||
await expect(element(by.id('Simple'))).toBeNotVisible()
|
||||
|
||||
// after 2.5s => second swiper
|
||||
await new Promise(r => setTimeout(r, 2500))
|
||||
|
||||
await expect(element(by.id('Hello'))).toBeNotVisible()
|
||||
await expect(element(by.id('Beautiful'))).toBeVisible()
|
||||
await expect(element(by.id('Simple'))).toBeNotVisible()
|
||||
|
||||
// after 5s => second swiper
|
||||
await new Promise(r => setTimeout(r, 2500))
|
||||
|
||||
await expect(element(by.id('Hello'))).toBeNotVisible()
|
||||
await expect(element(by.id('Beautiful'))).toBeNotVisible()
|
||||
await expect(element(by.id('Simple'))).toBeVisible()
|
||||
|
||||
// after 7.5s => second swiper
|
||||
await new Promise(r => setTimeout(r, 2500))
|
||||
|
||||
await expect(element(by.id('Hello'))).toBeVisible()
|
||||
await expect(element(by.id('Beautiful'))).toBeNotVisible()
|
||||
await expect(element(by.id('Simple'))).toBeNotVisible()
|
||||
})
|
||||
})
|
||||
32
examples/e2e/Basic.spec.js
Normal file
@ -0,0 +1,32 @@
|
||||
describe('Basic', () => {
|
||||
beforeEach(async () => {
|
||||
await device.reloadReactNative()
|
||||
await element(by.id('Basic')).tap()
|
||||
})
|
||||
|
||||
it('should have Basic swiper', async () => {
|
||||
await expect(element(by.id('Hello'))).toBeVisible()
|
||||
await expect(element(by.id('Beautiful'))).toBeNotVisible()
|
||||
await expect(element(by.id('Simple'))).toBeNotVisible()
|
||||
})
|
||||
|
||||
it('should be the same swiper after swipe right when loop={false}', async () => {
|
||||
await element(by.id('Hello')).swipe('right')
|
||||
await expect(element(by.id('Hello'))).toBeVisible()
|
||||
await expect(element(by.id('Beautiful'))).toBeNotVisible()
|
||||
})
|
||||
|
||||
it('should be Beautiful swiper after swipe left', async () => {
|
||||
await element(by.id('Hello')).swipe('left')
|
||||
await expect(element(by.id('Hello'))).toBeNotVisible()
|
||||
await expect(element(by.id('Beautiful'))).toBeVisible()
|
||||
})
|
||||
|
||||
it('should be Simple swiper after swipe left twice', async () => {
|
||||
await element(by.id('Hello')).swipe('left')
|
||||
await element(by.id('Beautiful')).swipe('left')
|
||||
await expect(element(by.id('Hello'))).toBeNotVisible()
|
||||
await expect(element(by.id('Beautiful'))).toBeNotVisible()
|
||||
await expect(element(by.id('Simple'))).toBeVisible()
|
||||
})
|
||||
})
|
||||
6
examples/e2e/NestSwiper.spec.js
Normal file
@ -0,0 +1,6 @@
|
||||
describe('AutoPlay', () => {
|
||||
beforeEach(async () => {
|
||||
await device.reloadReactNative()
|
||||
await element(by.id('NestSwiper')).tap()
|
||||
})
|
||||
}
|
||||
6
examples/e2e/config.json
Normal file
@ -0,0 +1,6 @@
|
||||
{
|
||||
"setupFilesAfterEnv": ["./init.js"],
|
||||
"testEnvironment": "node",
|
||||
"reporters": ["detox/runners/jest/streamlineReporter"],
|
||||
"verbose": true
|
||||
}
|
||||
25
examples/e2e/init.js
Normal file
@ -0,0 +1,25 @@
|
||||
const detox = require('detox');
|
||||
const config = require('../package.json').detox;
|
||||
const adapter = require('detox/runners/jest/adapter');
|
||||
const specReporter = require('detox/runners/jest/specReporter');
|
||||
|
||||
// Set the default timeout
|
||||
jest.setTimeout(120000);
|
||||
jasmine.getEnv().addReporter(adapter);
|
||||
|
||||
// This takes care of generating status logs on a per-spec basis. By default, jest only reports at file-level.
|
||||
// This is strictly optional.
|
||||
jasmine.getEnv().addReporter(specReporter);
|
||||
|
||||
beforeAll(async () => {
|
||||
await detox.init(config);
|
||||
});
|
||||
|
||||
beforeEach(async () => {
|
||||
await adapter.beforeEach();
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
await adapter.afterAll();
|
||||
await detox.cleanup();
|
||||
});
|
||||
@ -1 +0,0 @@
|
||||
import './App'
|
||||
@ -1 +0,0 @@
|
||||
import './App'
|
||||
120
examples/index.tsx
Normal file
@ -0,0 +1,120 @@
|
||||
/**
|
||||
* @format
|
||||
*/
|
||||
import React from 'react'
|
||||
import {
|
||||
AppRegistry,
|
||||
Text,
|
||||
SafeAreaView,
|
||||
View,
|
||||
StyleSheet,
|
||||
FlatList,
|
||||
TouchableOpacity
|
||||
} from 'react-native'
|
||||
import { createStackNavigator } from 'react-navigation-stack'
|
||||
import { name as appName } from './app.json'
|
||||
|
||||
import AutoPlay from './components/AutoPlay'
|
||||
import Basic from './components/Basic' // Only update index when scrollEnd
|
||||
import DisableButton from './components/DisableButton'
|
||||
import Loop from './components/Loop'
|
||||
import Dynamic from './components/Dynamic'
|
||||
import LoadMinimal from './components/LoadMinimal' // flicker existing when shift from last to first on Android (or last to first)
|
||||
import NestSwiper from './components/NestSwiper'
|
||||
import Phone from './components/Phone'
|
||||
// import PhotoView from './components/PhotoView/'; // not working
|
||||
import Swiper from './components/Swiper' // working but no title displayed, direction vertical not work well on android
|
||||
import SwiperNumber from './components/SwiperNumber' // working but no title displayed
|
||||
import { createAppContainer } from 'react-navigation'
|
||||
|
||||
const DATA = [
|
||||
{
|
||||
name: 'AutoPlay'
|
||||
},
|
||||
{
|
||||
name: 'Basic'
|
||||
},
|
||||
{
|
||||
name: 'DisableButton'
|
||||
},
|
||||
{
|
||||
name: 'Dynamic'
|
||||
},
|
||||
{
|
||||
name: 'Loop'
|
||||
},
|
||||
{
|
||||
name: 'LoadMinimal'
|
||||
},
|
||||
{
|
||||
name: 'NestSwiper'
|
||||
},
|
||||
{
|
||||
name: 'Phone'
|
||||
},
|
||||
{
|
||||
name: 'Swiper'
|
||||
},
|
||||
{
|
||||
name: 'SwiperNumber'
|
||||
}
|
||||
]
|
||||
|
||||
function Item({ title, navigation }) {
|
||||
return (
|
||||
<TouchableOpacity onPress={() => navigation.navigate(title)}>
|
||||
<View testID={title} style={styles.item}>
|
||||
<Text style={styles.title}>{title}</Text>
|
||||
</View>
|
||||
</TouchableOpacity>
|
||||
)
|
||||
}
|
||||
|
||||
const Home = ({ navigation }) => {
|
||||
return (
|
||||
<SafeAreaView style={{ flex: 1 }}>
|
||||
<FlatList
|
||||
data={DATA}
|
||||
renderItem={({ item }) => (
|
||||
<Item navigation={navigation} title={item.name}></Item>
|
||||
)}
|
||||
keyExtractor={item => item.name}
|
||||
/>
|
||||
</SafeAreaView>
|
||||
)
|
||||
}
|
||||
|
||||
const AppNavigator = createStackNavigator(
|
||||
{
|
||||
Home,
|
||||
AutoPlay,
|
||||
Basic,
|
||||
DisableButton,
|
||||
Loop,
|
||||
Dynamic,
|
||||
LoadMinimal,
|
||||
NestSwiper,
|
||||
Phone,
|
||||
Swiper,
|
||||
SwiperNumber
|
||||
},
|
||||
{
|
||||
initialRouteName: 'Home'
|
||||
}
|
||||
)
|
||||
|
||||
const App = createAppContainer(AppNavigator)
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
item: {
|
||||
backgroundColor: '#ede',
|
||||
padding: 16,
|
||||
marginVertical: 8,
|
||||
marginHorizontal: 16
|
||||
},
|
||||
title: {
|
||||
fontSize: 24
|
||||
}
|
||||
})
|
||||
|
||||
AppRegistry.registerComponent(appName, () => App)
|
||||
46
examples/ios/Podfile
Normal file
@ -0,0 +1,46 @@
|
||||
platform :ios, '9.0'
|
||||
require_relative '../node_modules/@react-native-community/cli-platform-ios/native_modules'
|
||||
|
||||
target 'examples' do
|
||||
# Pods for examples
|
||||
pod 'React', :path => '../node_modules/react-native/'
|
||||
pod 'React-Core', :path => '../node_modules/react-native/React'
|
||||
pod 'React-DevSupport', :path => '../node_modules/react-native/React'
|
||||
pod 'React-RCTActionSheet', :path => '../node_modules/react-native/Libraries/ActionSheetIOS'
|
||||
pod 'React-RCTAnimation', :path => '../node_modules/react-native/Libraries/NativeAnimation'
|
||||
pod 'React-RCTBlob', :path => '../node_modules/react-native/Libraries/Blob'
|
||||
pod 'React-RCTImage', :path => '../node_modules/react-native/Libraries/Image'
|
||||
pod 'React-RCTLinking', :path => '../node_modules/react-native/Libraries/LinkingIOS'
|
||||
pod 'React-RCTNetwork', :path => '../node_modules/react-native/Libraries/Network'
|
||||
pod 'React-RCTSettings', :path => '../node_modules/react-native/Libraries/Settings'
|
||||
pod 'React-RCTText', :path => '../node_modules/react-native/Libraries/Text'
|
||||
pod 'React-RCTVibration', :path => '../node_modules/react-native/Libraries/Vibration'
|
||||
pod 'React-RCTWebSocket', :path => '../node_modules/react-native/Libraries/WebSocket'
|
||||
|
||||
pod 'React-cxxreact', :path => '../node_modules/react-native/ReactCommon/cxxreact'
|
||||
pod 'React-jsi', :path => '../node_modules/react-native/ReactCommon/jsi'
|
||||
pod 'React-jsiexecutor', :path => '../node_modules/react-native/ReactCommon/jsiexecutor'
|
||||
pod 'React-jsinspector', :path => '../node_modules/react-native/ReactCommon/jsinspector'
|
||||
pod 'yoga', :path => '../node_modules/react-native/ReactCommon/yoga'
|
||||
|
||||
pod 'DoubleConversion', :podspec => '../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec'
|
||||
pod 'glog', :podspec => '../node_modules/react-native/third-party-podspecs/glog.podspec'
|
||||
pod 'Folly', :podspec => '../node_modules/react-native/third-party-podspecs/Folly.podspec'
|
||||
|
||||
target 'examplesTests' do
|
||||
inherit! :search_paths
|
||||
# Pods for testing
|
||||
end
|
||||
|
||||
use_native_modules!
|
||||
end
|
||||
|
||||
target 'examples-tvOS' do
|
||||
# Pods for examples-tvOS
|
||||
|
||||
target 'examples-tvOSTests' do
|
||||
inherit! :search_paths
|
||||
# Pods for testing
|
||||
end
|
||||
|
||||
end
|
||||
199
examples/ios/Podfile.lock
Normal file
@ -0,0 +1,199 @@
|
||||
PODS:
|
||||
- boost-for-react-native (1.63.0)
|
||||
- DoubleConversion (1.1.6)
|
||||
- Folly (2018.10.22.00):
|
||||
- boost-for-react-native
|
||||
- DoubleConversion
|
||||
- Folly/Default (= 2018.10.22.00)
|
||||
- glog
|
||||
- Folly/Default (2018.10.22.00):
|
||||
- boost-for-react-native
|
||||
- DoubleConversion
|
||||
- glog
|
||||
- glog (0.3.5)
|
||||
- React (0.60.5):
|
||||
- React-Core (= 0.60.5)
|
||||
- React-DevSupport (= 0.60.5)
|
||||
- React-RCTActionSheet (= 0.60.5)
|
||||
- React-RCTAnimation (= 0.60.5)
|
||||
- React-RCTBlob (= 0.60.5)
|
||||
- React-RCTImage (= 0.60.5)
|
||||
- React-RCTLinking (= 0.60.5)
|
||||
- React-RCTNetwork (= 0.60.5)
|
||||
- React-RCTSettings (= 0.60.5)
|
||||
- React-RCTText (= 0.60.5)
|
||||
- React-RCTVibration (= 0.60.5)
|
||||
- React-RCTWebSocket (= 0.60.5)
|
||||
- React-Core (0.60.5):
|
||||
- Folly (= 2018.10.22.00)
|
||||
- React-cxxreact (= 0.60.5)
|
||||
- React-jsiexecutor (= 0.60.5)
|
||||
- yoga (= 0.60.5.React)
|
||||
- React-cxxreact (0.60.5):
|
||||
- boost-for-react-native (= 1.63.0)
|
||||
- DoubleConversion
|
||||
- Folly (= 2018.10.22.00)
|
||||
- glog
|
||||
- React-jsinspector (= 0.60.5)
|
||||
- React-DevSupport (0.60.5):
|
||||
- React-Core (= 0.60.5)
|
||||
- React-RCTWebSocket (= 0.60.5)
|
||||
- React-jsi (0.60.5):
|
||||
- boost-for-react-native (= 1.63.0)
|
||||
- DoubleConversion
|
||||
- Folly (= 2018.10.22.00)
|
||||
- glog
|
||||
- React-jsi/Default (= 0.60.5)
|
||||
- React-jsi/Default (0.60.5):
|
||||
- boost-for-react-native (= 1.63.0)
|
||||
- DoubleConversion
|
||||
- Folly (= 2018.10.22.00)
|
||||
- glog
|
||||
- React-jsiexecutor (0.60.5):
|
||||
- DoubleConversion
|
||||
- Folly (= 2018.10.22.00)
|
||||
- glog
|
||||
- React-cxxreact (= 0.60.5)
|
||||
- React-jsi (= 0.60.5)
|
||||
- React-jsinspector (0.60.5)
|
||||
- React-RCTActionSheet (0.60.5):
|
||||
- React-Core (= 0.60.5)
|
||||
- React-RCTAnimation (0.60.5):
|
||||
- React-Core (= 0.60.5)
|
||||
- React-RCTBlob (0.60.5):
|
||||
- React-Core (= 0.60.5)
|
||||
- React-RCTNetwork (= 0.60.5)
|
||||
- React-RCTWebSocket (= 0.60.5)
|
||||
- React-RCTImage (0.60.5):
|
||||
- React-Core (= 0.60.5)
|
||||
- React-RCTNetwork (= 0.60.5)
|
||||
- React-RCTLinking (0.60.5):
|
||||
- React-Core (= 0.60.5)
|
||||
- React-RCTNetwork (0.60.5):
|
||||
- React-Core (= 0.60.5)
|
||||
- React-RCTSettings (0.60.5):
|
||||
- React-Core (= 0.60.5)
|
||||
- React-RCTText (0.60.5):
|
||||
- React-Core (= 0.60.5)
|
||||
- React-RCTVibration (0.60.5):
|
||||
- React-Core (= 0.60.5)
|
||||
- React-RCTWebSocket (0.60.5):
|
||||
- React-Core (= 0.60.5)
|
||||
- RNGestureHandler (1.4.1):
|
||||
- React
|
||||
- RNReanimated (1.3.0):
|
||||
- React
|
||||
- RNScreens (1.0.0-alpha.23):
|
||||
- React
|
||||
- yoga (0.60.5.React)
|
||||
|
||||
DEPENDENCIES:
|
||||
- DoubleConversion (from `../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec`)
|
||||
- Folly (from `../node_modules/react-native/third-party-podspecs/Folly.podspec`)
|
||||
- glog (from `../node_modules/react-native/third-party-podspecs/glog.podspec`)
|
||||
- React (from `../node_modules/react-native/`)
|
||||
- React-Core (from `../node_modules/react-native/React`)
|
||||
- React-cxxreact (from `../node_modules/react-native/ReactCommon/cxxreact`)
|
||||
- React-DevSupport (from `../node_modules/react-native/React`)
|
||||
- React-jsi (from `../node_modules/react-native/ReactCommon/jsi`)
|
||||
- React-jsiexecutor (from `../node_modules/react-native/ReactCommon/jsiexecutor`)
|
||||
- React-jsinspector (from `../node_modules/react-native/ReactCommon/jsinspector`)
|
||||
- React-RCTActionSheet (from `../node_modules/react-native/Libraries/ActionSheetIOS`)
|
||||
- React-RCTAnimation (from `../node_modules/react-native/Libraries/NativeAnimation`)
|
||||
- React-RCTBlob (from `../node_modules/react-native/Libraries/Blob`)
|
||||
- React-RCTImage (from `../node_modules/react-native/Libraries/Image`)
|
||||
- React-RCTLinking (from `../node_modules/react-native/Libraries/LinkingIOS`)
|
||||
- React-RCTNetwork (from `../node_modules/react-native/Libraries/Network`)
|
||||
- React-RCTSettings (from `../node_modules/react-native/Libraries/Settings`)
|
||||
- React-RCTText (from `../node_modules/react-native/Libraries/Text`)
|
||||
- React-RCTVibration (from `../node_modules/react-native/Libraries/Vibration`)
|
||||
- React-RCTWebSocket (from `../node_modules/react-native/Libraries/WebSocket`)
|
||||
- RNGestureHandler (from `../node_modules/react-native-gesture-handler`)
|
||||
- RNReanimated (from `../node_modules/react-native-reanimated`)
|
||||
- RNScreens (from `../node_modules/react-native-screens`)
|
||||
- yoga (from `../node_modules/react-native/ReactCommon/yoga`)
|
||||
|
||||
SPEC REPOS:
|
||||
https://github.com/cocoapods/specs.git:
|
||||
- boost-for-react-native
|
||||
|
||||
EXTERNAL SOURCES:
|
||||
DoubleConversion:
|
||||
:podspec: "../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec"
|
||||
Folly:
|
||||
:podspec: "../node_modules/react-native/third-party-podspecs/Folly.podspec"
|
||||
glog:
|
||||
:podspec: "../node_modules/react-native/third-party-podspecs/glog.podspec"
|
||||
React:
|
||||
:path: "../node_modules/react-native/"
|
||||
React-Core:
|
||||
:path: "../node_modules/react-native/React"
|
||||
React-cxxreact:
|
||||
:path: "../node_modules/react-native/ReactCommon/cxxreact"
|
||||
React-DevSupport:
|
||||
:path: "../node_modules/react-native/React"
|
||||
React-jsi:
|
||||
:path: "../node_modules/react-native/ReactCommon/jsi"
|
||||
React-jsiexecutor:
|
||||
:path: "../node_modules/react-native/ReactCommon/jsiexecutor"
|
||||
React-jsinspector:
|
||||
:path: "../node_modules/react-native/ReactCommon/jsinspector"
|
||||
React-RCTActionSheet:
|
||||
:path: "../node_modules/react-native/Libraries/ActionSheetIOS"
|
||||
React-RCTAnimation:
|
||||
:path: "../node_modules/react-native/Libraries/NativeAnimation"
|
||||
React-RCTBlob:
|
||||
:path: "../node_modules/react-native/Libraries/Blob"
|
||||
React-RCTImage:
|
||||
:path: "../node_modules/react-native/Libraries/Image"
|
||||
React-RCTLinking:
|
||||
:path: "../node_modules/react-native/Libraries/LinkingIOS"
|
||||
React-RCTNetwork:
|
||||
:path: "../node_modules/react-native/Libraries/Network"
|
||||
React-RCTSettings:
|
||||
:path: "../node_modules/react-native/Libraries/Settings"
|
||||
React-RCTText:
|
||||
:path: "../node_modules/react-native/Libraries/Text"
|
||||
React-RCTVibration:
|
||||
:path: "../node_modules/react-native/Libraries/Vibration"
|
||||
React-RCTWebSocket:
|
||||
:path: "../node_modules/react-native/Libraries/WebSocket"
|
||||
RNGestureHandler:
|
||||
:path: "../node_modules/react-native-gesture-handler"
|
||||
RNReanimated:
|
||||
:path: "../node_modules/react-native-reanimated"
|
||||
RNScreens:
|
||||
:path: "../node_modules/react-native-screens"
|
||||
yoga:
|
||||
:path: "../node_modules/react-native/ReactCommon/yoga"
|
||||
|
||||
SPEC CHECKSUMS:
|
||||
boost-for-react-native: 39c7adb57c4e60d6c5479dd8623128eb5b3f0f2c
|
||||
DoubleConversion: 5805e889d232975c086db112ece9ed034df7a0b2
|
||||
Folly: 30e7936e1c45c08d884aa59369ed951a8e68cf51
|
||||
glog: 1f3da668190260b06b429bb211bfbee5cd790c28
|
||||
React: 53c53c4d99097af47cf60594b8706b4e3321e722
|
||||
React-Core: ba421f6b4f4cbe2fb17c0b6fc675f87622e78a64
|
||||
React-cxxreact: 8384287780c4999351ad9b6e7a149d9ed10a2395
|
||||
React-DevSupport: 197fb409737cff2c4f9986e77c220d7452cb9f9f
|
||||
React-jsi: 4d8c9efb6312a9725b18d6fc818ffc103f60fec2
|
||||
React-jsiexecutor: 90ad2f9db09513fc763bc757fdc3c4ff8bde2a30
|
||||
React-jsinspector: e08662d1bf5b129a3d556eb9ea343a3f40353ae4
|
||||
React-RCTActionSheet: b0f1ea83f4bf75fb966eae9bfc47b78c8d3efd90
|
||||
React-RCTAnimation: 359ba1b5690b1e87cc173558a78e82d35919333e
|
||||
React-RCTBlob: 5e2b55f76e9a1c7ae52b826923502ddc3238df24
|
||||
React-RCTImage: f5f1c50922164e89bdda67bcd0153952a5cfe719
|
||||
React-RCTLinking: d0ecbd791e9ddddc41fa1f66b0255de90e8ee1e9
|
||||
React-RCTNetwork: e26946300b0ab7bb6c4a6348090e93fa21f33a9d
|
||||
React-RCTSettings: d0d37cb521b7470c998595a44f05847777cc3f42
|
||||
React-RCTText: b074d89033583d4f2eb5faf7ea2db3a13c7553a2
|
||||
React-RCTVibration: 2105b2e0e2b66a6408fc69a46c8a7fb5b2fdade0
|
||||
React-RCTWebSocket: cd932a16b7214898b6b7f788c8bddb3637246ac4
|
||||
RNGestureHandler: 4cb47a93019c1a201df2644413a0a1569a51c8aa
|
||||
RNReanimated: 6abbbae2e5e72609d85aabd92a982a94566885f1
|
||||
RNScreens: f28b48b8345f2f5f39ed6195518291515032a788
|
||||
yoga: 312528f5bbbba37b4dcea5ef00e8b4033fdd9411
|
||||
|
||||
PODFILE CHECKSUM: a3a53e6abc12f076194e8f2e182cc122fa168741
|
||||
|
||||
COCOAPODS: 1.7.5
|
||||
@ -7,7 +7,7 @@
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>$(EXECUTABLE_NAME)</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)</string>
|
||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
@ -22,6 +22,19 @@
|
||||
<string>1</string>
|
||||
<key>LSRequiresIPhoneOS</key>
|
||||
<true/>
|
||||
<key>NSAppTransportSecurity</key>
|
||||
<dict>
|
||||
<key>NSExceptionDomains</key>
|
||||
<dict>
|
||||
<key>localhost</key>
|
||||
<dict>
|
||||
<key>NSExceptionAllowsInsecureHTTPLoads</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>NSLocationWhenInUseUsageDescription</key>
|
||||
<string></string>
|
||||
<key>UILaunchStoryboardName</key>
|
||||
<string>LaunchScreen</string>
|
||||
<key>UIRequiredDeviceCapabilities</key>
|
||||
@ -36,19 +49,5 @@
|
||||
</array>
|
||||
<key>UIViewControllerBasedStatusBarAppearance</key>
|
||||
<false/>
|
||||
<key>NSLocationWhenInUseUsageDescription</key>
|
||||
<string></string>
|
||||
<key>NSAppTransportSecurity</key>
|
||||
<!--See http://ste.vn/2015/06/10/configuring-app-transport-security-ios-9-osx-10-11/ -->
|
||||
<dict>
|
||||
<key>NSExceptionDomains</key>
|
||||
<dict>
|
||||
<key>localhost</key>
|
||||
<dict>
|
||||
<key>NSExceptionAllowsInsecureHTTPLoads</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</dict>
|
||||
</dict>
|
||||
</dict>
|
||||
</plist>
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0820"
|
||||
LastUpgradeVersion = "0940"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "NO"
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0620"
|
||||
LastUpgradeVersion = "0940"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "NO"
|
||||
|
||||
10
examples/ios/examples.xcworkspace/contents.xcworkspacedata
generated
Normal file
@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Workspace
|
||||
version = "1.0">
|
||||
<FileRef
|
||||
location = "group:examples.xcodeproj">
|
||||
</FileRef>
|
||||
<FileRef
|
||||
location = "group:Pods/Pods.xcodeproj">
|
||||
</FileRef>
|
||||
</Workspace>
|
||||
@ -1,15 +1,14 @@
|
||||
/**
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import <React/RCTBridgeDelegate.h>
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@interface AppDelegate : UIResponder <UIApplicationDelegate>
|
||||
@interface AppDelegate : UIResponder <UIApplicationDelegate, RCTBridgeDelegate>
|
||||
|
||||
@property (nonatomic, strong) UIWindow *window;
|
||||
|
||||
|
||||
@ -1,14 +1,13 @@
|
||||
/**
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import "AppDelegate.h"
|
||||
|
||||
#import <React/RCTBridge.h>
|
||||
#import <React/RCTBundleURLProvider.h>
|
||||
#import <React/RCTRootView.h>
|
||||
|
||||
@ -16,14 +15,11 @@
|
||||
|
||||
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
|
||||
{
|
||||
NSURL *jsCodeLocation;
|
||||
RCTBridge *bridge = [[RCTBridge alloc] initWithDelegate:self launchOptions:launchOptions];
|
||||
RCTRootView *rootView = [[RCTRootView alloc] initWithBridge:bridge
|
||||
moduleName:@"examples"
|
||||
initialProperties:nil];
|
||||
|
||||
jsCodeLocation = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index.ios" fallbackResource:nil];
|
||||
|
||||
RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation
|
||||
moduleName:@"examples"
|
||||
initialProperties:nil
|
||||
launchOptions:launchOptions];
|
||||
rootView.backgroundColor = [[UIColor alloc] initWithRed:1.0f green:1.0f blue:1.0f alpha:1];
|
||||
|
||||
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
|
||||
@ -34,4 +30,13 @@
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (NSURL *)sourceURLForBridge:(RCTBridge *)bridge
|
||||
{
|
||||
#if DEBUG
|
||||
return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" fallbackResource:nil];
|
||||
#else
|
||||
return [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];
|
||||
#endif
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
6
examples/ios/examples/Images.xcassets/Contents.json
Normal file
@ -0,0 +1,6 @@
|
||||
{
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
||||
@ -9,7 +9,7 @@
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>$(EXECUTABLE_NAME)</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)</string>
|
||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
@ -24,6 +24,21 @@
|
||||
<string>1</string>
|
||||
<key>LSRequiresIPhoneOS</key>
|
||||
<true/>
|
||||
<key>NSAppTransportSecurity</key>
|
||||
<dict>
|
||||
<key>NSAllowsArbitraryLoads</key>
|
||||
<true/>
|
||||
<key>NSExceptionDomains</key>
|
||||
<dict>
|
||||
<key>localhost</key>
|
||||
<dict>
|
||||
<key>NSExceptionAllowsInsecureHTTPLoads</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>NSLocationWhenInUseUsageDescription</key>
|
||||
<string></string>
|
||||
<key>UILaunchStoryboardName</key>
|
||||
<string>LaunchScreen</string>
|
||||
<key>UIRequiredDeviceCapabilities</key>
|
||||
@ -38,19 +53,5 @@
|
||||
</array>
|
||||
<key>UIViewControllerBasedStatusBarAppearance</key>
|
||||
<false/>
|
||||
<key>NSLocationWhenInUseUsageDescription</key>
|
||||
<string></string>
|
||||
<key>NSAppTransportSecurity</key>
|
||||
<!--See http://ste.vn/2015/06/10/configuring-app-transport-security-ios-9-osx-10-11/ -->
|
||||
<dict>
|
||||
<key>NSExceptionDomains</key>
|
||||
<dict>
|
||||
<key>localhost</key>
|
||||
<dict>
|
||||
<key>NSExceptionAllowsInsecureHTTPLoads</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</dict>
|
||||
</dict>
|
||||
</dict>
|
||||
</plist>
|
||||
|
||||
@ -1,10 +1,8 @@
|
||||
/**
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@ -7,7 +7,7 @@
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>$(EXECUTABLE_NAME)</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)</string>
|
||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
|
||||
@ -1,10 +1,8 @@
|
||||
/**
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
17
examples/metro.config.js
Normal file
@ -0,0 +1,17 @@
|
||||
/**
|
||||
* Metro configuration for React Native
|
||||
* https://github.com/facebook/react-native
|
||||
*
|
||||
* @format
|
||||
*/
|
||||
|
||||
module.exports = {
|
||||
transformer: {
|
||||
getTransformOptions: async () => ({
|
||||
transform: {
|
||||
experimentalImportSupport: false,
|
||||
inlineRequires: false,
|
||||
},
|
||||
}),
|
||||
},
|
||||
};
|
||||
@ -1,31 +1,48 @@
|
||||
{
|
||||
"name": "examples",
|
||||
"version": "0.0.1",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"start": "node node_modules/react-native/local-cli/cli.js start",
|
||||
"watch": "node ./scripts/watch-and-copy-src.js",
|
||||
"packager": "sh ./node_modules/react-native/packager/packager.sh --root ./node_modules/react-native-swiper",
|
||||
"dev": "concurrently 'npm run watch' 'npm run packager'",
|
||||
"test": "jest"
|
||||
},
|
||||
"dependencies": {
|
||||
"react": "16.0.0-alpha.12",
|
||||
"react-native": "0.48.4",
|
||||
"react-native-swiper": "../"
|
||||
},
|
||||
"devDependencies": {
|
||||
"babel-jest": "20.0.3",
|
||||
"babel-preset-react-native": "2.1.0",
|
||||
"concurrently": "^2.2.0",
|
||||
"fs-extra": "^0.30.0",
|
||||
"jest": "20.0.4",
|
||||
"minimatch": "^3.0.2",
|
||||
"node-watch": "^0.4.0",
|
||||
"react-test-renderer": "16.0.0-alpha.12",
|
||||
"rimraf": "^2.5.4"
|
||||
},
|
||||
"jest": {
|
||||
"preset": "react-native"
|
||||
}
|
||||
"name": "examples",
|
||||
"version": "0.0.1",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"start": "rm -rf node_modules/react-native-swiper/examples && react-native start || react-native start",
|
||||
"test": "jest",
|
||||
"lint": "eslint ."
|
||||
},
|
||||
"dependencies": {
|
||||
"react": "16.8.6",
|
||||
"react-model": "^3.0.0",
|
||||
"react-native": "0.60.5",
|
||||
"react-native-gesture-handler": "^1.4.1",
|
||||
"react-native-reanimated": "^1.3.0",
|
||||
"react-native-screens": "^1.0.0-alpha.23",
|
||||
"react-native-swiper": "../",
|
||||
"react-navigation": "^4.0.10",
|
||||
"react-navigation-stack": "^1.9.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.6.0",
|
||||
"@babel/runtime": "^7.6.0",
|
||||
"@react-native-community/eslint-config": "^0.0.5",
|
||||
"@types/react": "^16.9.2",
|
||||
"@types/react-native": "^0.60.15",
|
||||
"babel-jest": "^24.9.0",
|
||||
"detox": "^14.3.4",
|
||||
"eslint": "^6.4.0",
|
||||
"jest": "^24.9.0",
|
||||
"metro-react-native-babel-preset": "^0.56.0",
|
||||
"react-test-renderer": "16.8.6"
|
||||
},
|
||||
"jest": {
|
||||
"preset": "react-native"
|
||||
},
|
||||
"detox": {
|
||||
"test-runner": "jest",
|
||||
"configurations": {
|
||||
"ios.sim.debug": {
|
||||
"binaryPath": "ios/build/examples/Build/Products/Debug-iphonesimulator/examples.app",
|
||||
"build": "xcodebuild -workspace ios/examples.xcworkspace -scheme examples -configuration Debug -sdk iphonesimulator -derivedDataPath ios/build",
|
||||
"type": "ios.simulator",
|
||||
"name": "iPhone 7"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,37 +0,0 @@
|
||||
const path = require('path')
|
||||
const fs = require('fs-extra')
|
||||
const watch = require('node-watch')
|
||||
const rimraf = require('rimraf')
|
||||
const minimatch = require('minimatch')
|
||||
|
||||
function copyAndWatch (source, destination, fileGlob) {
|
||||
console.log(`Cleaning "${destination}"`)
|
||||
rimraf(destination, () => {
|
||||
console.log(`Copying "${source}" to "${destination}"`)
|
||||
fs.copy(source, destination, (err) => {
|
||||
if (err) console.error(err)
|
||||
})
|
||||
|
||||
console.log(`Watching "${source}"`)
|
||||
watch(source, (filename) => {
|
||||
const localPath = filename.split(source).pop()
|
||||
if (matchesFile(localPath, fileGlob)) {
|
||||
const destinationPath = `${destination}${localPath}`
|
||||
console.log(`Copying "${filename}" to "${destinationPath}"`)
|
||||
fs.copy(filename, destinationPath, (err) => {
|
||||
if (err) console.error(err)
|
||||
})
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
function matchesFile (filename, fileGlob) {
|
||||
if (fileGlob == null) return true
|
||||
return minimatch(path.basename(filename), fileGlob)
|
||||
}
|
||||
|
||||
copyAndWatch(
|
||||
'../src',
|
||||
'node_modules/react-native-swiper/src'
|
||||
)
|
||||
8317
examples/yarn.lock
245
index.d.ts
vendored
@ -1,106 +1,147 @@
|
||||
import {
|
||||
ViewStyle,
|
||||
StyleProp,
|
||||
NativeSyntheticEvent,
|
||||
NativeScrollEvent,
|
||||
ScrollViewProps
|
||||
} from 'react-native'
|
||||
import { Component } from 'react'
|
||||
|
||||
declare module 'react-native-swiper' {
|
||||
import { ViewStyle } from 'react-native'
|
||||
import { Component } from 'react'
|
||||
|
||||
interface SwiperProps {
|
||||
// Basic
|
||||
// If true, the scroll view's children are arranged horizontally in a row instead of vertically in a column.
|
||||
horizontal?: boolean
|
||||
// If no specify default enable fullscreen mode by flex: 1.
|
||||
loop?: boolean
|
||||
// Index number of initial slide.
|
||||
index?: number
|
||||
// Set to true make control buttons visible.
|
||||
showsButtons?: boolean
|
||||
// Set to false to disable continuous loop mode.
|
||||
autoplay?: boolean
|
||||
// Called with the new index when the user swiped
|
||||
onIndexChanged?: any
|
||||
|
||||
// Custom basic style & content
|
||||
// Set to true enable auto play mode.
|
||||
width?: number
|
||||
// If no specify default fullscreen mode by flex: 1.
|
||||
height?: number
|
||||
// See default style in source.
|
||||
style?: ViewStyle
|
||||
// Only load current index slide , loadMinimalSize slides before and after.
|
||||
loadMinimal?: boolean
|
||||
// see loadMinimal
|
||||
loadMinimalSize?: boolean
|
||||
// Custom loader to display when slides aren't loaded
|
||||
loadMinimalLoader?: boolean
|
||||
|
||||
// Pagination
|
||||
// Set to true make pagination visible.
|
||||
showsPagination?: boolean
|
||||
// Custom styles will merge with the default styles.
|
||||
paginationStyle?: ViewStyle
|
||||
// Complete control how to render pagination with three params (index, total, context) ref to this.state.index / this.state.total / this, For example: show numbers instead of dots.
|
||||
renderPagination?: (index: number, total: number, swiper: Swiper) => JSX.Element
|
||||
// Allow custom the dot element.
|
||||
dot?: any
|
||||
// Allow custom the active-dot element.
|
||||
activeDot?: any
|
||||
// Allow custom the active-dot element.
|
||||
dotStyle?: ViewStyle
|
||||
// Allow custom the active-dot element.
|
||||
dotColor?: string
|
||||
// Allow custom the active-dot element.
|
||||
activeDotColor?: string
|
||||
// Allow custom the active-dot element.
|
||||
activeDotStyle?: ViewStyle
|
||||
|
||||
// Autoplay
|
||||
// Delay between auto play transitions (in second).
|
||||
autoplayTimeout?: boolean
|
||||
// Cycle direction control.
|
||||
autoplayDirection?: boolean
|
||||
|
||||
// Control buttons
|
||||
// Set to true make control buttons visible.
|
||||
buttonWrapperStyle?: any
|
||||
// Allow custom the next button.
|
||||
nextButton?: JSX.Element
|
||||
// Allow custom the prev button.
|
||||
prevButton?: JSX.Element
|
||||
|
||||
// Supported ScrollResponder
|
||||
// When animation begins after letting up
|
||||
onScrollBeginDrag?: any
|
||||
// Makes no sense why this occurs first during bounce
|
||||
onMomentumScrollEnd?: any
|
||||
// Immediately after onMomentumScrollEnd
|
||||
onTouchStartCapture?: any
|
||||
// Same, but bubble phase
|
||||
onTouchStart?: any
|
||||
// You could hold the touch start for a long time
|
||||
onTouchEnd?: any
|
||||
// When lifting up - you could pause forever before * lifting
|
||||
onResponderRelease?: any
|
||||
|
||||
// If true, the scroll view stops on multiples of the scroll view's size when scrolling. This can be used for
|
||||
// horizontal pagination.
|
||||
pagingEnabled?: boolean
|
||||
// Set to true if you want to show horizontal scroll bar.
|
||||
showsHorizontalScrollIndicator?: boolean
|
||||
// Set to true if you want to show vertical scroll bar.
|
||||
showsVerticalScrollIndicator?: boolean
|
||||
// If true, the scroll view bounces when it reaches the end of the content if the content is larger then the
|
||||
// scroll view along the axis of the scroll direction. If false, it disables all bouncing even if the
|
||||
// alwaysBounce* props are true.
|
||||
bounces?: boolean
|
||||
// If true, the scroll view scrolls to top when the status bar is tapped.
|
||||
scrollsToTop?: boolean
|
||||
// If true, offscreen child views (whose overflow value is hidden) are removed from their native backing
|
||||
// superview when offscreen. This canimprove scrolling performance on long lists.
|
||||
removeClippedSubviews?: boolean
|
||||
// Set to true if you need adjust content insets automation.
|
||||
automaticallyAdjustContentInsets?: boolean
|
||||
// Enables/Disables swiping
|
||||
scrollEnabled?: boolean
|
||||
interface SwiperStates {
|
||||
autoplayEnd: false
|
||||
loopJump: false
|
||||
width: number
|
||||
height: number
|
||||
offset: {
|
||||
x: number
|
||||
y: number
|
||||
}
|
||||
total: number
|
||||
index: number
|
||||
dir: 'x' | 'y'
|
||||
}
|
||||
|
||||
export default class Swiper extends Component<SwiperProps, any> {
|
||||
}
|
||||
interface SwiperInternals extends SwiperStates {
|
||||
isScrolling: boolean
|
||||
}
|
||||
|
||||
interface SwiperProps
|
||||
extends Omit<ScrollViewProps, 'onScrollBeginDrag' | 'onMomentumScrollEnd'> {
|
||||
// Basic
|
||||
// If true, the scroll view's children are arranged horizontally in a row instead of vertically in a column.
|
||||
horizontal?: boolean
|
||||
// If no specify default enable fullscreen mode by flex: 1.
|
||||
loop?: boolean
|
||||
// Index number of initial slide.
|
||||
index?: number
|
||||
// Set to true make control buttons visible.
|
||||
showsButtons?: boolean
|
||||
// Set to false to disable continuous loop mode.
|
||||
autoplay?: boolean
|
||||
// Called with the new index when the user swiped
|
||||
onIndexChanged?: (index: number) => void
|
||||
|
||||
// Custom basic style & content
|
||||
// Set to true enable auto play mode.
|
||||
width?: number
|
||||
// If no specify default fullscreen mode by flex: 1.
|
||||
height?: number
|
||||
// See default style in source.
|
||||
style?: StyleProp<ViewStyle>
|
||||
// Customize the View container.
|
||||
containerStyle?: StyleProp<ViewStyle>
|
||||
// Only load current index slide , loadMinimalSize slides before and after.
|
||||
loadMinimal?: boolean
|
||||
// see loadMinimal
|
||||
loadMinimalSize?: number
|
||||
// Custom loader to display when slides aren't loaded
|
||||
loadMinimalLoader?: React.ReactNode
|
||||
|
||||
// Pagination
|
||||
// Set to true make pagination visible.
|
||||
showsPagination?: boolean
|
||||
// Custom styles will merge with the default styles.
|
||||
paginationStyle?: StyleProp<ViewStyle>
|
||||
// Complete control how to render pagination with three params (index, total, context) ref to this.state.index / this.state.total / this, For example: show numbers instead of dots.
|
||||
renderPagination?: (
|
||||
index: number,
|
||||
total: number,
|
||||
swiper: Swiper
|
||||
) => React.ReactNode
|
||||
// Allow custom the dot element.
|
||||
dot?: React.ReactNode
|
||||
// Allow custom the active-dot element.
|
||||
activeDot?: React.ReactNode
|
||||
// Allow custom the active-dot element.
|
||||
dotStyle?: StyleProp<ViewStyle>
|
||||
// Allow custom the active-dot element.
|
||||
dotColor?: string
|
||||
// Allow custom the active-dot element.
|
||||
activeDotColor?: string
|
||||
// Allow custom the active-dot element.
|
||||
activeDotStyle?: StyleProp<ViewStyle>
|
||||
|
||||
// Autoplay
|
||||
// Delay between auto play transitions (in second).
|
||||
autoplayTimeout?: number
|
||||
// Cycle direction control.
|
||||
autoplayDirection?: boolean
|
||||
|
||||
// Control buttons
|
||||
// Set to true make control buttons visible.
|
||||
buttonWrapperStyle?: StyleProp<ViewStyle>
|
||||
// Allow custom the next button.
|
||||
nextButton?: React.ReactNode
|
||||
// Allow custom the prev button.
|
||||
prevButton?: React.ReactNode
|
||||
|
||||
// Supported ScrollResponder
|
||||
// When animation begins after letting up
|
||||
onScrollBeginDrag?: (
|
||||
e: NativeSyntheticEvent<NativeScrollEvent>,
|
||||
state: SwiperInternals,
|
||||
swiper: Swiper
|
||||
) => void
|
||||
// Makes no sense why this occurs first during bounce
|
||||
onMomentumScrollEnd?: (
|
||||
e: NativeSyntheticEvent<NativeScrollEvent>,
|
||||
state: SwiperInternals,
|
||||
swiper: Swiper
|
||||
) => void
|
||||
// Immediately after onMomentumScrollEnd
|
||||
onTouchStartCapture?: any
|
||||
// Same, but bubble phase
|
||||
onTouchStart?: any
|
||||
// You could hold the touch start for a long time
|
||||
onTouchEnd?: any
|
||||
// When lifting up - you could pause forever before * lifting
|
||||
onResponderRelease?: any
|
||||
|
||||
// If true, the scroll view stops on multiples of the scroll view's size when scrolling. This can be used for
|
||||
// horizontal pagination.
|
||||
pagingEnabled?: boolean
|
||||
// Set to true if you want to show horizontal scroll bar.
|
||||
showsHorizontalScrollIndicator?: boolean
|
||||
// Set to true if you want to show vertical scroll bar.
|
||||
showsVerticalScrollIndicator?: boolean
|
||||
// If true, the scroll view bounces when it reaches the end of the content if the content is larger then the
|
||||
// scroll view along the axis of the scroll direction. If false, it disables all bouncing even if the
|
||||
// alwaysBounce* props are true.
|
||||
bounces?: boolean
|
||||
// If true, the scroll view scrolls to top when the status bar is tapped.
|
||||
scrollsToTop?: boolean
|
||||
// If true, offscreen child views (whose overflow value is hidden) are removed from their native backing
|
||||
// superview when offscreen. This canimprove scrolling performance on long lists.
|
||||
removeClippedSubviews?: boolean
|
||||
// Set to true if you need adjust content insets automation.
|
||||
automaticallyAdjustContentInsets?: boolean
|
||||
// Enables/Disables swiping
|
||||
scrollEnabled?: boolean
|
||||
}
|
||||
|
||||
export default class Swiper extends Component<SwiperProps> {
|
||||
scrollBy: (index?: number, animated?: boolean) => void
|
||||
scrollTo: (index: number, animated?: boolean) => void
|
||||
}
|
||||
}
|
||||
|
||||
10
index.js
@ -1,2 +1,10 @@
|
||||
import Swiper from './src/'
|
||||
module.exports = Swiper
|
||||
/**
|
||||
* Resolve ES6 and CommonJS compatibility issues
|
||||
* 1. CommonJS code
|
||||
* const Swiper = require('react-native-swiper');
|
||||
* 2. ES6 code
|
||||
* import Swiper from 'react-native-swiper';
|
||||
*/
|
||||
module.exports = Swiper;
|
||||
module.exports.default = Swiper;
|
||||
|
||||
111
index.js.flow
Normal file
@ -0,0 +1,111 @@
|
||||
// @flow strict
|
||||
|
||||
// eslint-disable-next-line
|
||||
import { Component, type Node } from 'react';
|
||||
|
||||
declare module 'react-native-swiper' {
|
||||
// eslint-disable-next-line no-undef
|
||||
declare export type SwiperProps = $ReadOnly<{|
|
||||
// Basic
|
||||
// If true, the scroll view's children are arranged horizontally in a row instead of vertically in a column.
|
||||
horizontal?: ?boolean,
|
||||
// If no specify default enable fullscreen mode by flex: 1.
|
||||
loop?: ?boolean,
|
||||
// Index number of initial slide.
|
||||
index?: ?number,
|
||||
// Set to true make control buttons visible.
|
||||
showsButtons?: ?boolean,
|
||||
// Set to false to disable continuous loop mode.
|
||||
autoplay?: ?boolean,
|
||||
// Called with the new index when the user swiped
|
||||
onIndexChanged?: ?(index?: number) => void,
|
||||
|
||||
// Custom basic style & content
|
||||
// Set to true enable auto play mode.
|
||||
width?: ?number,
|
||||
// If no specify default fullscreen mode by flex: 1.
|
||||
height?: ?number,
|
||||
// See default style in source.
|
||||
style?: ?Object,
|
||||
// Only load current index slide , loadMinimalSize slides before and after.
|
||||
loadMinimal?: ?boolean,
|
||||
// see loadMinimal
|
||||
loadMinimalSize?: ?boolean,
|
||||
// Custom loader to display when slides aren't loaded
|
||||
loadMinimalLoader?: ?boolean,
|
||||
|
||||
// Pagination
|
||||
// Set to true make pagination visible.
|
||||
showsPagination?: ?boolean,
|
||||
// Custom styles will merge with the default styles.
|
||||
paginationStyle?: ?Object,
|
||||
// Complete control how to render pagination with three params (index, total, context) ref to this.state.index / this.state.total / this, For example: show numbers instead of dots.
|
||||
renderPagination?: ?(index: number, total: number, context: any) => Node,
|
||||
// Allow custom the dot element.
|
||||
dot?: ?Node,
|
||||
// Allow custom the active-dot element.
|
||||
activeDot?: ?Node,
|
||||
// Allow custom the active-dot element.
|
||||
dotStyle?: ?Object,
|
||||
// Allow custom the active-dot element.
|
||||
dotColor?: ?string,
|
||||
// Allow custom the active-dot element.
|
||||
activeDotColor?: ?string,
|
||||
// Allow custom the active-dot element.
|
||||
activeDotStyle?: ?Object,
|
||||
|
||||
// Autoplay
|
||||
// Delay between auto play transitions (in second).
|
||||
autoplayTimeout?: ?number,
|
||||
// Cycle direction control.
|
||||
autoplayDirection?: ?boolean,
|
||||
|
||||
// Control buttons
|
||||
// Set to true make control buttons visible.
|
||||
buttonWrapperStyle?: ?Object,
|
||||
// Allow custom the next button.
|
||||
nextButton?: ?Node,
|
||||
// Allow custom the prev button.
|
||||
prevButton?: ?Node,
|
||||
|
||||
// Supported ScrollResponder
|
||||
// When animation begins after letting up
|
||||
onScrollBeginDrag?: ?(event?: any, state?: any, context?: any) => void,
|
||||
// Makes no sense why this occurs first during bounce
|
||||
onMomentumScrollEnd?: ?(event?: any, state?: any, context?: any) => void,
|
||||
// Immediately after onMomentumScrollEnd
|
||||
onTouchStartCapture?: ?(event?: any, state?: any, context?: any) => void,
|
||||
// Same, but bubble phase
|
||||
onTouchStart?: ?(event?: any, state?: any, context?: any) => void,
|
||||
// You could hold the touch start for a long time
|
||||
onTouchEnd?: ?(event?: any, state?: any, context?: any) => void,
|
||||
// When lifting up - you could pause forever before * lifting
|
||||
onResponderRelease?: ?(event?: any, state?: any, context?: any) => void,
|
||||
|
||||
// If true, the scroll view stops on multiples of the scroll view's size when scrolling. This can be used for
|
||||
// horizontal pagination.
|
||||
pagingEnabled?: ?boolean,
|
||||
// Set to true if you want to show horizontal scroll bar.
|
||||
showsHorizontalScrollIndicator?: ?boolean,
|
||||
// Set to true if you want to show vertical scroll bar.
|
||||
showsVerticalScrollIndicator?: ?boolean,
|
||||
// If true, the scroll view bounces when it reaches the end of the content if the content is larger then the
|
||||
// scroll view along the axis of the scroll direction. If false, it disables all bouncing even if the
|
||||
// alwaysBounce* props are true.
|
||||
bounces?: ?boolean,
|
||||
// If true, the scroll view scrolls to top when the status bar is tapped.
|
||||
scrollsToTop?: ?boolean,
|
||||
// If true, offscreen child views (whose overflow value is hidden) are removed from their native backing
|
||||
// superview when offscreen. This canimprove scrolling performance on long lists.
|
||||
removeClippedSubviews?: ?boolean,
|
||||
// Set to true if you need adjust content insets automation.
|
||||
automaticallyAdjustContentInsets?: ?boolean,
|
||||
// Enables/Disables swiping
|
||||
scrollEnabled?: ?boolean
|
||||
|}>;
|
||||
|
||||
// eslint-disable-next-line no-undef
|
||||
declare export default class Swiper extends Component<SwiperProps> {
|
||||
scrollBy(index: number, animated?: boolean): void;
|
||||
}
|
||||
}
|
||||
14
package.json
@ -5,10 +5,11 @@
|
||||
"react-native",
|
||||
"ios"
|
||||
],
|
||||
"version": "1.5.13",
|
||||
"version": "1.6.0-rc.2",
|
||||
"description": "Swiper component for React Native.",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"commit": "npx git-cz",
|
||||
"start": "react-native start",
|
||||
"lint": "standard | snazzy",
|
||||
"update": "updtr",
|
||||
@ -46,7 +47,7 @@
|
||||
"url": "git+https://github.com/leecade/react-native-swiper.git"
|
||||
},
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"license": "MIT",
|
||||
"bugs": {
|
||||
"url": "https://github.com/leecade/react-native-swiper/issues"
|
||||
},
|
||||
@ -54,11 +55,16 @@
|
||||
"devDependencies": {
|
||||
"babel-eslint": "^8.0.1",
|
||||
"rimraf": "^2.5.4",
|
||||
"snazzy": "^6.0.0",
|
||||
"standard": "^10.0.3",
|
||||
"snazzy": "^7.1.0",
|
||||
"standard": "^13.0.1",
|
||||
"updtr": "^2.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"prop-types": "^15.5.10"
|
||||
},
|
||||
"config": {
|
||||
"commitizen": {
|
||||
"path": "cz-conventional-changelog"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
464
src/index.js
@ -11,7 +11,6 @@ import {
|
||||
ScrollView,
|
||||
Dimensions,
|
||||
TouchableOpacity,
|
||||
ViewPagerAndroid,
|
||||
Platform,
|
||||
ActivityIndicator
|
||||
} from 'react-native'
|
||||
@ -28,7 +27,7 @@ const styles = {
|
||||
},
|
||||
|
||||
wrapperIOS: {
|
||||
backgroundColor: 'transparent',
|
||||
backgroundColor: 'transparent'
|
||||
},
|
||||
|
||||
wrapperAndroid: {
|
||||
@ -37,7 +36,7 @@ const styles = {
|
||||
},
|
||||
|
||||
slide: {
|
||||
backgroundColor: 'transparent',
|
||||
backgroundColor: 'transparent'
|
||||
},
|
||||
|
||||
pagination_x: {
|
||||
@ -91,8 +90,7 @@ const styles = {
|
||||
|
||||
buttonText: {
|
||||
fontSize: 50,
|
||||
color: '#007aff',
|
||||
fontFamily: 'Arial'
|
||||
color: '#007aff'
|
||||
}
|
||||
}
|
||||
|
||||
@ -106,18 +104,13 @@ export default class extends Component {
|
||||
static propTypes = {
|
||||
horizontal: PropTypes.bool,
|
||||
children: PropTypes.node.isRequired,
|
||||
containerStyle: PropTypes.oneOfType([
|
||||
PropTypes.object,
|
||||
PropTypes.number,
|
||||
]),
|
||||
containerStyle: PropTypes.oneOfType([PropTypes.object, PropTypes.number]),
|
||||
style: PropTypes.oneOfType([
|
||||
PropTypes.object,
|
||||
PropTypes.number,
|
||||
PropTypes.array
|
||||
]),
|
||||
scrollViewStyle: PropTypes.oneOfType([
|
||||
PropTypes.object,
|
||||
PropTypes.number,
|
||||
]),
|
||||
scrollViewStyle: PropTypes.oneOfType([PropTypes.object, PropTypes.number]),
|
||||
pagingEnabled: PropTypes.bool,
|
||||
showsHorizontalScrollIndicator: PropTypes.bool,
|
||||
showsVerticalScrollIndicator: PropTypes.bool,
|
||||
@ -128,6 +121,7 @@ export default class extends Component {
|
||||
showsPagination: PropTypes.bool,
|
||||
showsButtons: PropTypes.bool,
|
||||
disableNextButton: PropTypes.bool,
|
||||
disablePrevButton: PropTypes.bool,
|
||||
loadMinimal: PropTypes.bool,
|
||||
loadMinimalSize: PropTypes.number,
|
||||
loadMinimalLoader: PropTypes.element,
|
||||
@ -137,8 +131,16 @@ export default class extends Component {
|
||||
autoplayDirection: PropTypes.bool,
|
||||
index: PropTypes.number,
|
||||
renderPagination: PropTypes.func,
|
||||
dotStyle: PropTypes.oneOfType([PropTypes.object, PropTypes.number]),
|
||||
activeDotStyle: PropTypes.oneOfType([PropTypes.object, PropTypes.number]),
|
||||
dotStyle: PropTypes.oneOfType([
|
||||
PropTypes.object,
|
||||
PropTypes.number,
|
||||
PropTypes.array
|
||||
]),
|
||||
activeDotStyle: PropTypes.oneOfType([
|
||||
PropTypes.object,
|
||||
PropTypes.number,
|
||||
PropTypes.array
|
||||
]),
|
||||
dotColor: PropTypes.string,
|
||||
activeDotColor: PropTypes.string,
|
||||
/**
|
||||
@ -164,6 +166,7 @@ export default class extends Component {
|
||||
showsPagination: true,
|
||||
showsButtons: false,
|
||||
disableNextButton: false,
|
||||
disablePrevButton: false,
|
||||
loop: true,
|
||||
loadMinimal: false,
|
||||
loadMinimalSize: 1,
|
||||
@ -193,42 +196,70 @@ export default class extends Component {
|
||||
autoplayTimer = null
|
||||
loopJumpTimer = null
|
||||
|
||||
componentWillReceiveProps (nextProps) {
|
||||
if (!nextProps.autoplay && this.autoplayTimer) clearTimeout(this.autoplayTimer)
|
||||
this.setState(this.initState(nextProps, this.props.index !== nextProps.index))
|
||||
UNSAFE_componentWillReceiveProps(nextProps) {
|
||||
if (!nextProps.autoplay && this.autoplayTimer)
|
||||
clearTimeout(this.autoplayTimer)
|
||||
if (nextProps.index === this.props.index) return
|
||||
this.setState(
|
||||
this.initState(nextProps, this.props.index !== nextProps.index)
|
||||
)
|
||||
}
|
||||
|
||||
componentDidMount () {
|
||||
componentDidMount() {
|
||||
this.autoplay()
|
||||
}
|
||||
|
||||
componentWillUnmount () {
|
||||
componentWillUnmount() {
|
||||
this.autoplayTimer && clearTimeout(this.autoplayTimer)
|
||||
this.loopJumpTimer && clearTimeout(this.loopJumpTimer)
|
||||
}
|
||||
|
||||
componentWillUpdate (nextProps, nextState) {
|
||||
UNSAFE_componentWillUpdate(nextProps, nextState) {
|
||||
// If the index has changed, we notify the parent via the onIndexChanged callback
|
||||
if (this.state.index !== nextState.index) this.props.onIndexChanged(nextState.index)
|
||||
if (this.state.index !== nextState.index)
|
||||
this.props.onIndexChanged(nextState.index)
|
||||
}
|
||||
|
||||
initState (props, updateIndex = false) {
|
||||
componentDidUpdate(prevProps) {
|
||||
// If autoplay props updated to true, autoplay immediately
|
||||
if (this.props.autoplay && !prevProps.autoplay) {
|
||||
this.autoplay()
|
||||
}
|
||||
if (this.props.children !== prevProps.children) {
|
||||
if (this.props.loadMinimal && Platform.OS === 'ios') {
|
||||
this.setState({ ...this.props, index: this.state.index })
|
||||
} else {
|
||||
this.setState(
|
||||
this.initState({ ...this.props, index: this.state.index }, true)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
initState(props, updateIndex = false) {
|
||||
// set the current state
|
||||
const state = this.state || { width: 0, height: 0, offset: { x: 0, y: 0 } }
|
||||
|
||||
const initState = {
|
||||
autoplayEnd: false,
|
||||
children: null,
|
||||
loopJump: false,
|
||||
offset: {}
|
||||
}
|
||||
|
||||
initState.total = props.children ? props.children.length || 1 : 0
|
||||
// Support Optional render page
|
||||
initState.children = Array.isArray(props.children)
|
||||
? props.children.filter(child => child)
|
||||
: props.children
|
||||
|
||||
initState.total = initState.children ? initState.children.length || 1 : 0
|
||||
|
||||
if (state.total === initState.total && !updateIndex) {
|
||||
// retain the index
|
||||
initState.index = state.index
|
||||
} else {
|
||||
initState.index = initState.total > 1 ? Math.min(props.index, initState.total - 1) : 0
|
||||
initState.index =
|
||||
initState.total > 1 ? Math.min(props.index, initState.total - 1) : 0
|
||||
}
|
||||
|
||||
// Default: horizontal
|
||||
@ -238,40 +269,38 @@ export default class extends Component {
|
||||
|
||||
if (props.width) {
|
||||
initState.width = props.width
|
||||
} else if (this.state && this.state.width){
|
||||
} else if (this.state && this.state.width) {
|
||||
initState.width = this.state.width
|
||||
} else {
|
||||
initState.width = width;
|
||||
initState.width = width
|
||||
}
|
||||
|
||||
if (props.height) {
|
||||
initState.height = props.height
|
||||
} else if (this.state && this.state.height){
|
||||
} else if (this.state && this.state.height) {
|
||||
initState.height = this.state.height
|
||||
} else {
|
||||
initState.height = height;
|
||||
initState.height = height
|
||||
}
|
||||
|
||||
initState.offset[initState.dir] = initState.dir === 'y'
|
||||
? height * props.index
|
||||
: width * props.index
|
||||
|
||||
initState.offset[initState.dir] =
|
||||
initState.dir === 'y' ? height * props.index : width * props.index
|
||||
|
||||
this.internals = {
|
||||
...this.internals,
|
||||
isScrolling: false
|
||||
};
|
||||
}
|
||||
return initState
|
||||
}
|
||||
|
||||
// include internals with state
|
||||
fullState () {
|
||||
fullState() {
|
||||
return Object.assign({}, this.state, this.internals)
|
||||
}
|
||||
|
||||
onLayout = (event) => {
|
||||
onLayout = event => {
|
||||
const { width, height } = event.nativeEvent.layout
|
||||
const offset = this.internals.offset = {}
|
||||
const offset = (this.internals.offset = {})
|
||||
const state = { width, height }
|
||||
|
||||
if (this.state.total > 1) {
|
||||
@ -279,25 +308,22 @@ export default class extends Component {
|
||||
if (this.props.loop) {
|
||||
setup++
|
||||
}
|
||||
offset[this.state.dir] = this.state.dir === 'y'
|
||||
? height * setup
|
||||
: width * setup
|
||||
offset[this.state.dir] =
|
||||
this.state.dir === 'y' ? height * setup : width * setup
|
||||
}
|
||||
|
||||
// only update the offset in state if needed, updating offset while swiping
|
||||
// causes some bad jumping / stuttering
|
||||
if (!this.state.offset || width !== this.state.width || height !== this.state.height) {
|
||||
if (!this.state.offset) {
|
||||
state.offset = offset
|
||||
}
|
||||
|
||||
// related to https://github.com/leecade/react-native-swiper/issues/570
|
||||
// contentOffset is not working in react 0.48.x so we need to use scrollTo
|
||||
// to emulate offset.
|
||||
if (Platform.OS === 'ios') {
|
||||
if (this.initialRender && this.state.total > 1) {
|
||||
this.scrollView.scrollTo({...offset, animated: false})
|
||||
this.initialRender = false;
|
||||
}
|
||||
if (this.initialRender && this.state.total > 1) {
|
||||
this.scrollView.scrollTo({ ...offset, animated: false })
|
||||
this.initialRender = false
|
||||
}
|
||||
|
||||
this.setState(state)
|
||||
@ -307,27 +333,59 @@ export default class extends Component {
|
||||
if (!this.state.loopJump) return
|
||||
const i = this.state.index + (this.props.loop ? 1 : 0)
|
||||
const scrollView = this.scrollView
|
||||
this.loopJumpTimer = setTimeout(() => scrollView.setPageWithoutAnimation &&
|
||||
scrollView.setPageWithoutAnimation(i), 50)
|
||||
this.loopJumpTimer = setTimeout(
|
||||
() => {
|
||||
if (scrollView.setPageWithoutAnimation) {
|
||||
scrollView.setPageWithoutAnimation(i)
|
||||
} else {
|
||||
if (this.state.index === 0) {
|
||||
scrollView.scrollTo(
|
||||
this.props.horizontal === false
|
||||
? { x: 0, y: this.state.height, animated: false }
|
||||
: { x: this.state.width, y: 0, animated: false }
|
||||
)
|
||||
} else if (this.state.index === this.state.total - 1) {
|
||||
this.props.horizontal === false
|
||||
? this.scrollView.scrollTo({
|
||||
x: 0,
|
||||
y: this.state.height * this.state.total,
|
||||
animated: false
|
||||
})
|
||||
: this.scrollView.scrollTo({
|
||||
x: this.state.width * this.state.total,
|
||||
y: 0,
|
||||
animated: false
|
||||
})
|
||||
}
|
||||
}
|
||||
},
|
||||
// Important Parameter
|
||||
// ViewPager 50ms, ScrollView 300ms
|
||||
scrollView.setPageWithoutAnimation ? 50 : 300
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Automatic rolling
|
||||
*/
|
||||
autoplay = () => {
|
||||
if (!Array.isArray(this.props.children) ||
|
||||
if (
|
||||
!Array.isArray(this.state.children) ||
|
||||
!this.props.autoplay ||
|
||||
this.internals.isScrolling ||
|
||||
this.state.autoplayEnd) return
|
||||
this.state.autoplayEnd
|
||||
)
|
||||
return
|
||||
|
||||
this.autoplayTimer && clearTimeout(this.autoplayTimer)
|
||||
this.autoplayTimer = setTimeout(() => {
|
||||
if (!this.props.loop && (
|
||||
this.props.autoplayDirection
|
||||
? this.state.index === this.state.total - 1
|
||||
: this.state.index === 0
|
||||
)
|
||||
) return this.setState({ autoplayEnd: true })
|
||||
if (
|
||||
!this.props.loop &&
|
||||
(this.props.autoplayDirection
|
||||
? this.state.index === this.state.total - 1
|
||||
: this.state.index === 0)
|
||||
)
|
||||
return this.setState({ autoplayEnd: true })
|
||||
|
||||
this.scrollBy(this.props.autoplayDirection ? 1 : -1)
|
||||
}, this.props.autoplayTimeout * 1000)
|
||||
@ -340,7 +398,8 @@ export default class extends Component {
|
||||
onScrollBegin = e => {
|
||||
// update scroll state
|
||||
this.internals.isScrolling = true
|
||||
this.props.onScrollBeginDrag && this.props.onScrollBeginDrag(e, this.fullState(), this)
|
||||
this.props.onScrollBeginDrag &&
|
||||
this.props.onScrollBeginDrag(e, this.fullState(), this)
|
||||
}
|
||||
|
||||
/**
|
||||
@ -354,19 +413,23 @@ export default class extends Component {
|
||||
// making our events coming from android compatible to updateIndex logic
|
||||
if (!e.nativeEvent.contentOffset) {
|
||||
if (this.state.dir === 'x') {
|
||||
e.nativeEvent.contentOffset = {x: e.nativeEvent.position * this.state.width}
|
||||
e.nativeEvent.contentOffset = {
|
||||
x: e.nativeEvent.position * this.state.width
|
||||
}
|
||||
} else {
|
||||
e.nativeEvent.contentOffset = {y: e.nativeEvent.position * this.state.height}
|
||||
e.nativeEvent.contentOffset = {
|
||||
y: e.nativeEvent.position * this.state.height
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.updateIndex(e.nativeEvent.contentOffset, this.state.dir, () => {
|
||||
this.autoplay()
|
||||
this.loopJump()
|
||||
|
||||
// if `onMomentumScrollEnd` registered will be called here
|
||||
this.props.onMomentumScrollEnd && this.props.onMomentumScrollEnd(e, this.fullState(), this)
|
||||
})
|
||||
// if `onMomentumScrollEnd` registered will be called here
|
||||
this.props.onMomentumScrollEnd &&
|
||||
this.props.onMomentumScrollEnd(e, this.fullState(), this)
|
||||
}
|
||||
|
||||
/*
|
||||
@ -375,14 +438,16 @@ export default class extends Component {
|
||||
*/
|
||||
onScrollEndDrag = e => {
|
||||
const { contentOffset } = e.nativeEvent
|
||||
const { horizontal, children } = this.props
|
||||
const { index } = this.state
|
||||
const { horizontal } = this.props
|
||||
const { children, index } = this.state
|
||||
const { offset } = this.internals
|
||||
const previousOffset = horizontal ? offset.x : offset.y
|
||||
const newOffset = horizontal ? contentOffset.x : contentOffset.y
|
||||
|
||||
if (previousOffset === newOffset &&
|
||||
(index === 0 || index === children.length - 1)) {
|
||||
if (
|
||||
previousOffset === newOffset &&
|
||||
(index === 0 || index === children.length - 1)
|
||||
) {
|
||||
this.internals.isScrolling = false
|
||||
}
|
||||
}
|
||||
@ -394,7 +459,11 @@ export default class extends Component {
|
||||
*/
|
||||
updateIndex = (offset, dir, cb) => {
|
||||
const state = this.state
|
||||
// Android ScrollView will not scrollTo certain offset when props change
|
||||
let index = state.index
|
||||
if (!this.internals.offset)
|
||||
// Android not setting this onLayout first? https://github.com/leecade/react-native-swiper/issues/582
|
||||
this.internals.offset = {}
|
||||
const diff = offset[dir] - this.internals.offset[dir]
|
||||
const step = dir === 'x' ? state.width : state.height
|
||||
let loopJump = false
|
||||
@ -462,11 +531,49 @@ export default class extends Component {
|
||||
if (state.dir === 'x') x = diff * state.width
|
||||
if (state.dir === 'y') y = diff * state.height
|
||||
|
||||
if (Platform.OS !== 'ios') {
|
||||
this.scrollView && this.scrollView[animated ? 'setPage' : 'setPageWithoutAnimation'](diff)
|
||||
} else {
|
||||
this.scrollView && this.scrollView.scrollTo({ x, y, animated })
|
||||
this.scrollView && this.scrollView.scrollTo({ x, y, animated })
|
||||
|
||||
// update scroll state
|
||||
this.internals.isScrolling = true
|
||||
this.setState({
|
||||
autoplayEnd: false
|
||||
})
|
||||
|
||||
// trigger onScrollEnd manually in android
|
||||
if (!animated || Platform.OS !== 'ios') {
|
||||
setImmediate(() => {
|
||||
this.onScrollEnd({
|
||||
nativeEvent: {
|
||||
position: diff
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Scroll to index
|
||||
* @param {number} index page
|
||||
* @param {bool} animated
|
||||
*/
|
||||
|
||||
scrollTo = (index, animated = true) => {
|
||||
if (
|
||||
this.internals.isScrolling ||
|
||||
this.state.total < 2 ||
|
||||
index == this.state.index
|
||||
)
|
||||
return
|
||||
|
||||
const state = this.state
|
||||
const diff = this.state.index + (index - this.state.index)
|
||||
|
||||
let x = 0
|
||||
let y = 0
|
||||
if (state.dir === 'x') x = diff * state.width
|
||||
if (state.dir === 'y') y = diff * state.height
|
||||
|
||||
this.scrollView && this.scrollView.scrollTo({ x, y, animated })
|
||||
|
||||
// update scroll state
|
||||
this.internals.isScrolling = true
|
||||
@ -502,13 +609,14 @@ export default class extends Component {
|
||||
|
||||
for (let prop in props) {
|
||||
// if(~scrollResponders.indexOf(prop)
|
||||
if (typeof props[prop] === 'function' &&
|
||||
if (
|
||||
typeof props[prop] === 'function' &&
|
||||
prop !== 'onMomentumScrollEnd' &&
|
||||
prop !== 'renderPagination' &&
|
||||
prop !== 'onScrollBeginDrag'
|
||||
) {
|
||||
let originResponder = props[prop]
|
||||
overrides[prop] = (e) => originResponder(e, this.fullState(), this)
|
||||
overrides[prop] = e => originResponder(e, this.fullState(), this)
|
||||
}
|
||||
}
|
||||
|
||||
@ -520,59 +628,79 @@ export default class extends Component {
|
||||
* @return {object} react-dom
|
||||
*/
|
||||
renderPagination = () => {
|
||||
// By default, dots only show when `total` >= 2
|
||||
// By default, dots only show when `total` >= 2
|
||||
if (this.state.total <= 1) return null
|
||||
|
||||
let dots = []
|
||||
const ActiveDot = this.props.activeDot || <View style={[{
|
||||
backgroundColor: this.props.activeDotColor || '#007aff',
|
||||
width: 8,
|
||||
height: 8,
|
||||
borderRadius: 4,
|
||||
marginLeft: 3,
|
||||
marginRight: 3,
|
||||
marginTop: 3,
|
||||
marginBottom: 3
|
||||
}, this.props.activeDotStyle]} />
|
||||
const Dot = this.props.dot || <View style={[{
|
||||
backgroundColor: this.props.dotColor || 'rgba(0,0,0,.2)',
|
||||
width: 8,
|
||||
height: 8,
|
||||
borderRadius: 4,
|
||||
marginLeft: 3,
|
||||
marginRight: 3,
|
||||
marginTop: 3,
|
||||
marginBottom: 3
|
||||
}, this.props.dotStyle ]} />
|
||||
const ActiveDot = this.props.activeDot || (
|
||||
<View
|
||||
style={[
|
||||
{
|
||||
backgroundColor: this.props.activeDotColor || '#007aff',
|
||||
width: 8,
|
||||
height: 8,
|
||||
borderRadius: 4,
|
||||
marginLeft: 3,
|
||||
marginRight: 3,
|
||||
marginTop: 3,
|
||||
marginBottom: 3
|
||||
},
|
||||
this.props.activeDotStyle
|
||||
]}
|
||||
/>
|
||||
)
|
||||
const Dot = this.props.dot || (
|
||||
<View
|
||||
style={[
|
||||
{
|
||||
backgroundColor: this.props.dotColor || 'rgba(0,0,0,.2)',
|
||||
width: 8,
|
||||
height: 8,
|
||||
borderRadius: 4,
|
||||
marginLeft: 3,
|
||||
marginRight: 3,
|
||||
marginTop: 3,
|
||||
marginBottom: 3
|
||||
},
|
||||
this.props.dotStyle
|
||||
]}
|
||||
/>
|
||||
)
|
||||
for (let i = 0; i < this.state.total; i++) {
|
||||
dots.push(i === this.state.index
|
||||
? React.cloneElement(ActiveDot, {key: i})
|
||||
: React.cloneElement(Dot, {key: i})
|
||||
dots.push(
|
||||
i === this.state.index
|
||||
? React.cloneElement(ActiveDot, { key: i })
|
||||
: React.cloneElement(Dot, { key: i })
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<View pointerEvents='none' style={[styles['pagination_' + this.state.dir], this.props.paginationStyle]}>
|
||||
<View
|
||||
pointerEvents="none"
|
||||
style={[
|
||||
styles['pagination_' + this.state.dir],
|
||||
this.props.paginationStyle
|
||||
]}
|
||||
>
|
||||
{dots}
|
||||
</View>
|
||||
)
|
||||
}
|
||||
|
||||
renderTitle = () => {
|
||||
const child = this.props.children[this.state.index]
|
||||
const child = this.state.children[this.state.index]
|
||||
const title = child && child.props && child.props.title
|
||||
return title
|
||||
? (<View style={styles.title}>
|
||||
{this.props.children[this.state.index].props.title}
|
||||
</View>)
|
||||
: null
|
||||
return title ? (
|
||||
<View style={styles.title}>
|
||||
{this.state.children[this.state.index].props.title}
|
||||
</View>
|
||||
) : null
|
||||
}
|
||||
|
||||
renderNextButton = () => {
|
||||
let button = null
|
||||
|
||||
if (this.props.loop ||
|
||||
this.state.index !== this.state.total - 1) {
|
||||
if (this.props.loop || this.state.index !== this.state.total - 1) {
|
||||
button = this.props.nextButton || <Text style={styles.buttonText}>›</Text>
|
||||
}
|
||||
|
||||
@ -581,9 +709,7 @@ export default class extends Component {
|
||||
onPress={() => button !== null && this.scrollBy(1)}
|
||||
disabled={this.props.disableNextButton}
|
||||
>
|
||||
<View>
|
||||
{button}
|
||||
</View>
|
||||
<View>{button}</View>
|
||||
</TouchableOpacity>
|
||||
)
|
||||
}
|
||||
@ -596,20 +722,28 @@ export default class extends Component {
|
||||
}
|
||||
|
||||
return (
|
||||
<TouchableOpacity onPress={() => button !== null && this.scrollBy(-1)}>
|
||||
<View>
|
||||
{button}
|
||||
</View>
|
||||
<TouchableOpacity
|
||||
onPress={() => button !== null && this.scrollBy(-1)}
|
||||
disabled={this.props.disablePrevButton}
|
||||
>
|
||||
<View>{button}</View>
|
||||
</TouchableOpacity>
|
||||
)
|
||||
}
|
||||
|
||||
renderButtons = () => {
|
||||
return (
|
||||
<View pointerEvents='box-none' style={[styles.buttonWrapper, {
|
||||
width: this.state.width,
|
||||
height: this.state.height
|
||||
}, this.props.buttonWrapperStyle]}>
|
||||
<View
|
||||
pointerEvents="box-none"
|
||||
style={[
|
||||
styles.buttonWrapper,
|
||||
{
|
||||
width: this.state.width,
|
||||
height: this.state.height
|
||||
},
|
||||
this.props.buttonWrapperStyle
|
||||
]}
|
||||
>
|
||||
{this.renderPrevButton()}
|
||||
{this.renderNextButton()}
|
||||
</View>
|
||||
@ -617,34 +751,35 @@ export default class extends Component {
|
||||
}
|
||||
|
||||
refScrollView = view => {
|
||||
this.scrollView = view;
|
||||
this.scrollView = view
|
||||
}
|
||||
|
||||
onPageScrollStateChanged = state => {
|
||||
switch (state) {
|
||||
case 'dragging':
|
||||
return this.onScrollBegin()
|
||||
|
||||
case 'idle':
|
||||
case 'settling':
|
||||
if (this.props.onTouchEnd) this.props.onTouchEnd()
|
||||
}
|
||||
}
|
||||
|
||||
renderScrollView = pages => {
|
||||
if (Platform.OS === 'ios') {
|
||||
return (
|
||||
<ScrollView ref={this.refScrollView}
|
||||
{...this.props}
|
||||
{...this.scrollViewPropOverrides()}
|
||||
contentContainerStyle={[styles.wrapperIOS, this.props.style]}
|
||||
contentOffset={this.state.offset}
|
||||
onScrollBeginDrag={this.onScrollBegin}
|
||||
onMomentumScrollEnd={this.onScrollEnd}
|
||||
onScrollEndDrag={this.onScrollEndDrag}
|
||||
style={this.props.scrollViewStyle}>
|
||||
{pages}
|
||||
</ScrollView>
|
||||
)
|
||||
}
|
||||
return (
|
||||
<ViewPagerAndroid ref={this.refScrollView}
|
||||
<ScrollView
|
||||
ref={this.refScrollView}
|
||||
{...this.props}
|
||||
initialPage={this.props.loop ? this.state.index + 1 : this.state.index}
|
||||
onPageSelected={this.onScrollEnd}
|
||||
key={pages.length}
|
||||
style={[styles.wrapperAndroid, this.props.style]}>
|
||||
{...this.scrollViewPropOverrides()}
|
||||
contentContainerStyle={[styles.wrapperIOS, this.props.style]}
|
||||
contentOffset={this.state.offset}
|
||||
onScrollBeginDrag={this.onScrollBegin}
|
||||
onMomentumScrollEnd={this.onScrollEnd}
|
||||
onScrollEndDrag={this.onScrollEndDrag}
|
||||
style={this.props.scrollViewStyle}
|
||||
>
|
||||
{pages}
|
||||
</ViewPagerAndroid>
|
||||
</ScrollView>
|
||||
)
|
||||
}
|
||||
|
||||
@ -652,17 +787,9 @@ export default class extends Component {
|
||||
* Default render
|
||||
* @return {object} react-dom
|
||||
*/
|
||||
render () {
|
||||
const state = this.state
|
||||
const props = this.props
|
||||
render() {
|
||||
const { index, total, width, height, children } = this.state
|
||||
const {
|
||||
index,
|
||||
total,
|
||||
width,
|
||||
height
|
||||
} = this.state;
|
||||
const {
|
||||
children,
|
||||
containerStyle,
|
||||
loop,
|
||||
loadMinimal,
|
||||
@ -670,14 +797,14 @@ export default class extends Component {
|
||||
loadMinimalLoader,
|
||||
renderPagination,
|
||||
showsButtons,
|
||||
showsPagination,
|
||||
} = this.props;
|
||||
showsPagination
|
||||
} = this.props
|
||||
// let dir = state.dir
|
||||
// let key = 0
|
||||
const loopVal = loop ? 1 : 0
|
||||
let pages = []
|
||||
|
||||
const pageStyle = [{width: width, height: height}, styles.slide]
|
||||
const pageStyle = [{ width: width, height: height }, styles.slide]
|
||||
const pageStyleLoading = {
|
||||
width,
|
||||
height,
|
||||
@ -697,9 +824,19 @@ export default class extends Component {
|
||||
|
||||
pages = pages.map((page, i) => {
|
||||
if (loadMinimal) {
|
||||
if (i >= (index + loopVal - loadMinimalSize) &&
|
||||
i <= (index + loopVal + loadMinimalSize)) {
|
||||
return <View style={pageStyle} key={i}>{children[page]}</View>
|
||||
if (
|
||||
(i >= index + loopVal - loadMinimalSize &&
|
||||
i <= index + loopVal + loadMinimalSize) ||
|
||||
// The real first swiper should be keep
|
||||
(loop && i === 1) ||
|
||||
// The real last swiper should be keep
|
||||
(loop && i === total - 1)
|
||||
) {
|
||||
return (
|
||||
<View style={pageStyle} key={i}>
|
||||
{children[page]}
|
||||
</View>
|
||||
)
|
||||
} else {
|
||||
return (
|
||||
<View style={pageStyleLoading} key={i}>
|
||||
@ -708,19 +845,28 @@ export default class extends Component {
|
||||
)
|
||||
}
|
||||
} else {
|
||||
return <View style={pageStyle} key={i}>{children[page]}</View>
|
||||
return (
|
||||
<View style={pageStyle} key={i}>
|
||||
{children[page]}
|
||||
</View>
|
||||
)
|
||||
}
|
||||
})
|
||||
} else {
|
||||
pages = <View style={pageStyle} key={0}>{children}</View>
|
||||
pages = (
|
||||
<View style={pageStyle} key={0}>
|
||||
{children}
|
||||
</View>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<View style={[styles.container, containerStyle]} onLayout={this.onLayout}>
|
||||
{this.renderScrollView(pages)}
|
||||
{showsPagination && (renderPagination
|
||||
? renderPagination(index, total, this)
|
||||
: this.renderPagination())}
|
||||
{showsPagination &&
|
||||
(renderPagination
|
||||
? renderPagination(index, total, this)
|
||||
: this.renderPagination())}
|
||||
{this.renderTitle()}
|
||||
{showsButtons && this.renderButtons()}
|
||||
</View>
|
||||
|
||||