ReactNative ViewPageAndroid组件详解

源码传送门

在我们开发Android的时候,ViewPage这个控件的使用频率还是很高的,最简单的就是制作引导页,应用程序的主界面等,在ReactNative开发中实现该功能的组件是ViewPageAndroid,当你看到该组件是以Android结尾,你就明白该组件只对Android平台有效,如果使用就要考虑适配iOS(目前学习到的ScrollView组件可以实现此效果,具体实现不在本篇文章介绍),今天就通过下面示例图,介绍ViewPageAndroid的API以及使用。
viewpage.gif

基本用法

对于该组件内部可以嵌套View,每一个子View就相当于一个Page,每一个单独的页面显示时它会拉伸填满ViewPageAndroid。

        return (
            <ViewPagerAndroid style={{backgroundColor: 'red', flex: 1}}>
                <View ><Text>1</Text></View>
                <View><Text>2</Text></View>
                <View><Text>3 </Text></View>
            </ViewPagerAndroid>
        )

在上面我么给出了一个最简单的展示ViewPagerAndroid的例子。我们在其内部加入了3个View,那么也将显示3页,虽然View没有设置样式,如宽和高,,但是它会填充ViewPagerAndroid ,其实设置了宽和高也没有用,不管设置宽高多少都是填满ViewPageAndroid。如果不信你可以尝试给第一个View添加样式

style={{backgroundColor:'green'}}

设置后,发现第一页显示的背景是绿色。然后再给第一个View增加宽高属性,都设置为100.如下

style={{backgroundColor:'green',width:100,height:100}}

设置后发现第一页的背景仍然全部是绿色,设置宽高属性并没有产生什么作用。对于文章开始的示例图展示,我们就是在VewPageAndroid组件中添加了5个子View,每一个View中有一个Image用于显示图片,和一个可点击的组件并且显示点击次数。

const styles = StyleSheet.create({
    button: {
        backgroundColor: '#2196f3',
        borderRadius: 5,
        marginHorizontal: 20,
        marginTop: 10,
        padding: 10,
    },
    buttonText: {
        color: 'white',
    },
    container: {
        flex: 1,
        backgroundColor: 'white',
    },
    image: {
        width: 300,
        height: 200,
        padding: 20,
    },
    viewPager: {
        flex: 1,
    },
});

由于ViewPageAndroid 5页显示的内容只是图片,背景不一样,其他都是通用的,我们就按如下创建


    render() {
        var pages = []
        for (var i = 0; i < PAGES; i++) {
            var pageStyle = {
                backgroundColor: BGCOLOR[i % BGCOLOR.length],
                alignItems: 'center',
                padding: 20,
            }
            pages.push(
                <View key={i} style={pageStyle} collapsable={false}>
                    <Image
                        style={styles.image}
                        resizeMode={Image.resizeMode.contain}
                        source={IMAGE_URIS[i % BGCOLOR.length]}
                    />
                    <CustomCount/>
                </View>
            )
        }
        return (
            <View style={styles.container}>
                <ViewPagerAndroid
                    style={styles.viewPager}
                    ref={(viewPage) => {
                        this.viewPage = viewPage;
                    }}>
                    {pages}
                </ViewPagerAndroid>
            </View>
        )
    }

用到的图片资源常量以及背景常量和页数常量如下

const PAGES = 5;
const BGCOLOR = ['#fdc08e', '#fff6b9', '#99d1b7', '#dde5fe', '#f79273'];
const IMAGE_URIS = [
    require('./Thumbnails/cat.png'),
    require('./Thumbnails/monkey.png'),
    require('./Thumbnails/rabbit.png'),
    require('./Thumbnails/tiger.png'),
    require('./Thumbnails/duck.png'),
];

对于Image组件通过source指定要显示的图片,其它属性使用可以参考之前的文章ReactNative Image组件详解,CustomCount是定义的一个组件,

class CustomCount extends Component {
    state = {
        count: 1,
    }
    render() {
        return (
            <View>
                <TouchableOpacity
                    activeOpacity={0.5}
                    onPress={() => this.setState({count: this.state.count + 1})}
                    style={{backgroundColor: '#38adff', borderRadius: 5, marginTop: 20, padding: 10}}
                >
                    <Text>我是可点击的 {this.state.count}</Text>
                </TouchableOpacity>
            </View>)
    }
}

在定义的点击组件中设置一个状态count,用于显示点击次数。这样我们就可以实现看到大致效果了。

设置初始化时显示页数

在默认的时候,总是显示第一页,很多时候,我们需要显示指定的页数,例如我们实现了一个日历,有12页(12个月),那我们点击打开日历时,要显示当前月的信息。如果当前是8月,那么就要默认显示第八页,不需要再我们一页一页的翻到该页,这时候就要使用initialPage 属性,它可以指定第一个显示的页数,该值从0开始。如设置默认显示第二页,如下

 initialPage={1}

keyboardDismissMode

如果我们使用了用于输入的组件,就会弹出软键盘,那么在拖动翻页时需要隐藏软键盘,就需要使用此属性,它有两个值分别是none(默认值,拖拽不会让键盘消失)和on-drag(当拖拽开始的时候会让键盘消失)。如果我们设置滑动时隐藏软键盘,如下

 keyboardDismissMode="on-drag"

设置每相邻页之间的间距

在上面的展示图中,我们看到每两个相邻页显示有10像素的白色间距,这个效果是通过pageMargin属性设置的,颜色对于间距显示的的颜色,是ViewPagerAndroid中样式设置的背景色,如果没有设置,从它父视图继承。如我们设置间距10像素

pageMargin={10}

scrollEnabled

该属性是用来设置是否可以滚动支持,当设置true时表示可以滚动翻页,默认值也是true,如果设置false的话,就表示不可滚动翻页,如此此时想实现翻页效果,那就需要使用setPage方法,稍后再介绍其使用。

显示页数指示器

在图例中,我们看到有一个显示当前页数以及总页数的指示器,要实现此功能,我们我们需要用到onPageSelected属性函数,每当页面切换完成后,该函数会调用,该函数有一个参数event,可以通过event.nativeEvent.position 获取当前页面的下标。

//增加属性
 onPageSelected={this._onPageSelected}

_onPageSelected = (event) => {
        console.log('_onPageSelected')
        this.setState({page: event.nativeEvent.position});
    }

我们增加了一个状态值page用于标示当前页面的下标。然后在ViewPageAndroid下面添加组件Text,用于显示当前页面指示器。

<Text style={[style, {textAlign: 'center'}]}>{this.state.page + 1}/{pages.length}</Text>

由于页面下标从0开始,我们显示时对其加1。通过上面我们实现了页面指示器显示。

很多时候,我们需要在需要在翻页时实现一些动画,例如翻页时Tab的颜色变化动画,在RN中,我们也可以实现效果,实现此效果时通过onPageScroll属性函数,当我们拖动页面时这个函数会一直回调,该函数有一个参数,我们可以通过event.nativeEvent获取我们需要的数据。

  • position 从左数起第一个当前可见的页面的下标。(经过测试这个数据的用处不大,切记这个position和onPageSelected携带的position值不一样,不是当前页面下标)
  • offset 一个在[0,1)(大于等于0,小于1)之间的范围,代表当前页面切换的状态。值x表示现在”position”所表示的页有(1 - x)的部分可见,而下一页有x的部分可见。
    看到了把offset 变化时0到1之间的数值,当向左滑动翻页时(相当于下一页)该值时0到1变化,向右滑动翻页(相当于上一页)是1到0变化。我们就可以通过该值进行一些类似微信那种透明读,或者颜色深浅,等我们任何想要实现的动画。

onPageScrollStateChanged

该函数用于监测ViewPageAndroid的状态,它有三个值

  • idle 空闲,意味着当前没有交互。
  • dragging 拖动中,意味着当前页面正在被拖动。
  • settling 处理中,意味着当前页面发生过交互,且正在结束开头或收尾的动画。

我们增加一个状态scrollState。然后如图例一样,将状态显示。

 onPageScrollStateChanged={this._onPageScrollStateChanged}

_onPageScrollStateChanged = (state: ViewPagerScrollState) => {
        console.log('_onPageScrollStateChanged')
        this.setState({scrollState: state});
    };

使用按钮实现上下翻页

在图例中我们有上一页和下一页两个按钮。实现此功能可以通过ViewPagerAndroid的setPage方法

    _onPress = (offset) => {
        var goPage = (this.state.page + offset + PAGES) % PAGES
        if (this.state.animationsAreEnabled) {
            this.viewPage.setPage(goPage)
        } else {
            this.viewPage.setPageWithoutAnimation(goPage)
        }
        this.setState({page: goPage})
    }

我将上一页和下一页点击事件统一处理了,当点击下一页时参数传1,当点击上一页时参数传-1。goPage 即使我们对将要跳转的页面下标做计算。如果当前是第一页,再点击上一页时将跳转到最后一页,计算到要跳转的页面下标后,调用setPage或者setPageWithoutAnimation都可以实现,区别通过名字页显而易见。当使用setPage时最后一页和第一页相互切换时会有个过度动画。如果使用setPageWithoutAnimation就没有动画。

好了,ViewPageAndroid的相关介绍就到此为止了,想查看全部源码,可前往GitHub,今天的这篇文章就到此结束了,若文中有错误的地方欢迎指出,共同进步,谢谢。Have a wonderful day.

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值