ReactNative ViewPageAndroid组件详解

Posted Code4Android

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ReactNative ViewPageAndroid组件详解相关的知识,希望对你有一定的参考价值。

源码传送门

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

基本用法

对于该组件内部可以嵌套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.

以上是关于ReactNative ViewPageAndroid组件详解的主要内容,如果未能解决你的问题,请参考以下文章

iOS开发嵌套ReactNative页面

ReactNative: 了解ReactNative框架提供的全部内容

集成ReactNative到现有Ios工程

reactnative关掉小米暗黑模式

如何启动reactnative

带你从零学ReactNative开发跨平台App开发