模板版本:v0.4.0

react-native-pull

Supported platforms License

本项目基于react-native-pull 开发

该第三方库支持直接从 npm 下载,新的包名为:@react-native-ohos/react-native-pull 版本所属关系如下

三方库名称 三方库版本 发布信息 支持RN版本 Autolink 编译API版本 社区基线版本 npm地址
@react-native-ohos/react-native-pull ~2.1.0 Gitcode Releases 0.77.* / 0.82.* API12+ 2.0.2 Npm Address
@react-native-oh-tpl/react-native-pull 2.0.4-0.0.1 Github Releases 0.72.* API12+ 2.0.2 Npm Address

1. 安装与使用

进入到工程目录并输入以下命令:

npm

# 0.72
npm install @react-native-oh-tpl/react-native-pull
# 0.77/0.82
npm install @react-native-ohos/react-native-pull

yarn

# 0.72
yarn add @react-native-oh-tpl/react-native-pull
# 0.77/0.82
yarn add @react-native-ohos/react-native-pull

下面的demo代码展示了这个库的基本使用场景:

使用时 import 的库名不变。

PullViewDemo

代码示例

import React, { Component, useState } from 'react';
import {
  StyleSheet,
  Text,
  View,
  ActivityIndicator,
  Dimensions,
} from 'react-native';

import { PullView } from 'react-native-pull';

interface testObjType {
  pulling: String,
  pullok: String,
  pullrelease: String,
  pushing: String,
  refresh: String,
  isPullEnd: String
}

const PullViewDemo = () => {

  const [count, setCount] = useState<string | number>(0);
  let testObj: testObjType = {
    pulling: '',
    pullok: '',
    pullrelease: '',
    pushing: '',
    refresh: '',
    isPullEnd: ''
  };
  const [data, setData] = useState(testObj);
  const onPulling = () => {
    testObj.pulling = 'pulling--------->'
    setData(testObj)
  };
  const onPullOk = () => {
    testObj.pullok = 'pullok--------->'
    setData(testObj)
  };
  const onPullRelease = (resolve: any) => {
    //do something
    testObj.pullrelease = 'pullrelease--------->'
    setData(testObj)
    setTimeout(() => {
      resolve();
    }, 3000);
  };
  const onPushing = (gesturePosition: any) => {
    testObj.pushing = 'x:' + gesturePosition.x + '------' + 'y:' + gesturePosition.y
    setData(testObj)
  };
  const topIndicatorRender = (pulling: any, pullok: any, pullrelease: any) => {
    if (pulling) {
      setCount('下拉刷新pulling...')
    } else if (pullok) {
      setCount('松开刷新pullok......')
    } else if (pullrelease) {
      setCount('玩命刷新中pullrelease......')
    }
    return (
      <View style={{ flexDirection: 'row', justifyContent: 'center', alignItems: 'center', height: 60 }}>
        <ActivityIndicator size="small" color="gray" />
        {pulling ? <Text>{count}</Text> : null}
        {pullok ? <Text>{count}</Text> : null}
        {pullrelease ? <Text>{count}</Text> : null}
      </View>
    );
  };

  return (
    <View style={[styles.container]}>
      <PullView style={{ width: Dimensions.get('window').width }}
        onPulling={onPulling}
        onPullOk={onPullOk}
        isPullEnd={true}
        onPullRelease={onPullRelease}
        onPushing={onPushing}
        topIndicatorRender={topIndicatorRender}
        topIndicatorHeight={60}>
        <View style={{ backgroundColor: '#eeeeee' }}>
          <Text>1***************</Text>
          <Text>onPulling:{testObj.pulling}</Text>
          <Text>3</Text>
          <Text>onPullOk:{testObj.pullok}</Text>
          <Text>5</Text>
          <Text>onPullRelease:{testObj.pullrelease}</Text>
          <Text>7</Text>
          <Text>onPushing:{testObj.pushing}</Text>
          <Text>9</Text>
        </View>
      </PullView>
    </View>
  );
};
export default PullViewDemo;
const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#F5FCFF',
  },
});

PullListDemo

代码示例

import React, { useState } from 'react';
import {
  StyleSheet,
  Text,
  View,
  ActivityIndicator,
  Dimensions,
  RefreshControl
} from 'react-native';
import {PullList} from 'react-native-pull';

interface testObjType {
  pulling: String,
  pullok: String,
  pullrelease: String,
  pushing: String,
  refresh: String,
  isPullEnd: String
}

const PullListDemo = () => {
  let testObj: testObjType = {
    pulling:'',
    pullok:'',
    pullrelease:'',
    pushing:'',
    refresh:'',
    isPullEnd:''
   };

   const [count, setCount] = useState<string | number>(0);
   const [data, setData] = useState(testObj);
    const [stateList, setStateList] = useState(
         [
                 {
                   id: 1,
                   title: '------>Item1',
                 },
                 {
                   id: 2,
                   title: '------>Item2',
                 },
                 {
                   id: 3,
                   title: '------>Item3',
                 },
                 {
                   id: 4,
                   title: '------>Item4',
                 },
                 {
                   id: 5,
                   title: '------>Item5',
                 },
                 {
                   id: 6,
                   title: '------>Item6',
                 },
                 {
                   id: 7,
                   title: '------>Item7',
                 },
                 {
                   id: 8,
                   title: '------>Item8',
                 },
                 {
                   id: 9,
                   title: '------>Item9',
                 },
                  {
                    id: 10,
                    title: '------>Item10',
                  },
                  {
                    id: 11,
                    title: '------>Item11',
                  },
                  {
                    id: 12,
                    title: '------>Item12',
                  },
               ]
    );

   const onPulling = () => {
      testObj.pulling='pulling--------->'
      setData(testObj)
   };

   const onPullOk = () => {
      testObj.pullok='pullok--------->'
      setData(testObj)
   };

   const onPullRelease = (resolve: any) => {
        //do something
        testObj.pullrelease='pullrelease--------->'
        setData(testObj)
        setTimeout(() => {
         setStateList([
                                       {
                                         id: 1,
                                         title: '------>Item1',
                                       },
                                       {
                                         id: 2,
                                         title: '------>Item2',
                                       },
                                       {
                                         id: 3,
                                         title: '------>Item3',
                                       },
                                       {
                                         id: 4,
                                         title: '------>Item4',
                                       },
                                       {
                                         id: 5,
                                         title: '------>Item5',
                                       },
                                       {
                                         id: 6,
                                         title: '------>Item6',
                                       },
                                       {
                                         id: 7,
                                         title: '------>Item7',
                                       },
                                       {
                                         id: 8,
                                         title: '------>Item8',
                                       },
                                       {
                                         id: 9,
                                         title: '------>Item9',
                                       },
                                        {
                                          id: 10,
                                          title: '------>Item10',
                                        },
                                        {
                                          id: 11,
                                          title: '------>Item11',
                                        },
                                        {
                                          id: 12,
                                          title: '------>Item12',
                                        },
                                     ]);
            resolve();
        }, 3000);
    };


    const onPushing = (gesturePosition: any) => {
        testObj.pushing= 'x:' + gesturePosition.x + '------' + 'y:' + gesturePosition.y
        setData(testObj)
    };

    const topIndicatorRender = (pulling: any, pullok: any, pullrelease: any) => {
      if (pulling) {
          setCount('当前PullList状态: pulling...')
      } else if (pullok) {
          setCount('当前PullList状态: pullok......')
      } else if (pullrelease) {
          setCount('当前PullList状态: pullrelease......')
      }

  return (
      <View style={{flexDirection: 'row', justifyContent: 'center', alignItems: 'center', height: 60}}>
          <ActivityIndicator size="small" color="gray" />
          {pulling ? <Text>{count}</Text> : null}
          {pullok ? <Text>{count}</Text> : null}
          {pullrelease ? <Text>{count}</Text> : null}
      </View>
  );
};


    const renderHeader = () => {
      return (
          <View style={{height: 50, backgroundColor: '#eeeeee', alignItems: 'center', justifyContent: 'center'}}>
              <Text style={{fontWeight: 'bold'}}>This is header</Text>
          </View>
      );
    }

   const renderRow = ({item}: any) => {
      return (
          <View style={{height: 50, backgroundColor: '#fafafa', alignItems: 'center', justifyContent: 'center'}}>
              <Text>{item.title}</Text>
          </View>
      );
    }

   const renderFooter = () => {
      return (
          <View style={{height: 100}}>
              <ActivityIndicator />
          </View>
      );
    }

   const loadMore = () => {
      const list: { id: number; title: string }[] = []
      const num = stateList.length
        for(var i = 0; i < 5; i++) {
            list.push({
                id: (i + 1 + num),
                title: `------>Item${(i+num+1)}`,
            })
        }
       setTimeout(() => {
          setStateList([...stateList,...list]);
        }, 1000);
    }

    const [refreshing, setRefreshing] = useState(false)
    const onRefresh = () => {
      // 加载数据的逻辑
      setRefreshing(true)
      // 数据加载完成后
      setTimeout(() => {
        setRefreshing(false)
      }, 2000); // 假设数据加载需要2秒
    };
    const refreshControl = (
      <RefreshControl
        refreshing={refreshing}
        onRefresh={onRefresh}
        tintColor="#ff0000" // 可选设置刷新指示器的颜色
        title="Loading..." // 可选设置刷新时显示的文本
        colors={['#ff0000', '#00ff00', '#0000ff']} // 可选设置刷新指示器的颜色数组
        progressBackgroundColor="#ffffff" // 可选设置进度背景色
      />
    );

    return (
      <View style={[styles.container]}>
      <PullList style={{width: Dimensions.get('window').width}}
            onPulling={onPulling}
            onPullOk={onPullOk}
            isPullEnd={true}
            onPullRelease={onPullRelease}
            onPushing={onPushing}
            topIndicatorRender={topIndicatorRender}
            topIndicatorHeight={60}
            pageSize={5}
            scrollViewProps={{
                scrollEventThrottle: 16, // 减少滚动事件的延迟提高滚动的响应性
              }}
            initialListSize={5}
            onEndReached={loadMore}
            onEndReachedThreshold={60}
            renderItem={renderRow}
            ListFooterComponent={renderFooter}
            ListHeaderComponent={renderHeader}
            data={stateList}
            keyExtractor={(item:any) => item.id}
          />
      </View>
    );
};

const styles = StyleSheet.create({
 container: {
    flex: 1,
    flexDirection: 'column',
    backgroundColor: '#F5FCFF',
    width:'100%',
    height:'100%',
    overflow: 'scroll'
  },
  welcome: {
    fontSize: 20,
    textAlign: 'center',
    margin: 10,
  },
  instructions: {
    textAlign: 'center',
    color: '#333333',
    marginBottom: 5,
  },
});

export default PullListDemo;

2. 约束与限制

2.1 兼容性

要使用此库,需要使用正确的 React-Native 和 RNOH 版本。另外,还需要使用配套的 DevEco Studio 和 手机 ROM。

在以下版本验证通过:

  1. RNOH: 0.82.1; SDK: HarmonyOS API Version 21 Release SDK; IDE: DevEco Studio 6.0.1.260; ROM: 6.0.0.130;
  2. RNOH: 0.72.38; SDK: HarmonyOS-5.0.0(API12); ROM: 5.0.0.107;
  3. RNOH: 0.77.18; SDK: HarmonyOS 6.0.0 Release SDK; IDE: DevEco Studio 6.0.0.868; ROM: 6.0.0.112;

3. 属性

"Platform"列表示该属性在原三方库上支持的平台。

"HarmonyOS Support"列为 yes 表示 HarmonyOS 平台支持该属性;no 则表示不支持;partially 表示部分支持。使用方法跨平台一致,效果对标 iOS 或 Android 的效果。

PullView & PullList 下拉效果属性

Name Description Type Required Platform HarmonyOS Support
style 设置组件样式,比如可以设置width/height/backgroudColor等 Style no android,ios yes
onPulling 处于pulling状态时执行的方法 function no android,ios yes
onPullOk 处于pullok状态时执行的方法 function no android,ios yes
onPullRelease 处于pullrelease状态时执行的方法,接受一个参数:resolve,最后执行完操作后应该调用resolve() function no android,ios yes
onPushing 当从下往上推时执行的方法,接受一个参数:gesturePosition。gesturePosition是json格式{x, y}对象,当从上往下拉时gesturePosition.y > 0,当从下往上推时gesturePosition.y < 0。 function no android,ios yes
topIndicatorRender 顶部刷新指示组件的渲染方法, 接受4个参数: ispulling, ispullok, ispullreleasegesturePosition,你可以使用gesturePosition定义动画头部 function no android,ios yes
topIndicatorHeight 顶部刷新指示组件的高度, 若定义了topIndicatorRender则同时需要此属性 number no android,ios yes
isPullEnd 是否已经下拉结束,若为true则隐藏顶部刷新指示组件,非必须 boolean no android,ios no
onRefresh 开始刷新时调用的方法 function no android,ios yes
refreshing 指示是否正在刷新 function no android,ios yes
pullOkMargin 触发"松开刷新"状态的下拉距离阈值 number no android,ios no
duration 下拉指示器收回时动画的持续时长,单位毫秒,默认 300 number no android,ios no
resolveHandler 刷新数据加载完成后调用一下它,下拉指示器就会自动收起;只在松手刷新阶段调用才有效 function no android,ios no
scrollTo 通过 ref 调用,让内部列表滚动到指定位置 function no android,ios no
scrollToEnd 通过 ref 调用,让内部列表直接滚动到底部 function no android,ios no

PullList 下拉效果属性

Name Description Type Required Platform HarmonyOS Support
getMetrics 获取当前列表的滚动信息,返回 { contentLength, visibleLength, offset },分别表示列表内容总高度、可视区域高度、当前已滚动的距离 function no android,ios yes

4. 遗留问题

5. 其他

6. 开源协议

本项目基于 The MIT License (MIT) ,请自由地享受和参与开源。