RN 使用RecyclerListView实现公用列表组件-记录

import React, { useState, useEffect, useRef } from "react";
import { View, Text, RefreshControl, StyleSheet } from "react-native";
import { RecyclerListView, DataProvider, LayoutProvider } from "recyclerlistview";
import { APIManager, NetCode, ReqType } from "../../api/APIManager";
import { Toast } from "@ant-design/react-native";
import StickyContainer from "recyclerlistview/dist/web/core/StickyContainer";

/**
 * item类型
 * @type {{Item: number, Header: number}}
 */
const RecycleItemType = {
  Header: 0,
  Item: 1,
};

/**
 * 头部模块参数
 * @constructor
 */
function ListHeaderFunc() {
  this.width = 0;
  this.height = 0;
  this.component = null;
}

/**
 * 吸顶模块参数
 * @constructor
 */
function StickyHeaderFunc() {
  this.stickyHeaderIndices = [];
  this.stickyFooterIndices = [];
  this.component = null;
}

const CustomRecyclerListView = ({
                                  apiName,
                                  params,
                                  width,
                                  height,
                                  requestType,
                                  ListHeader = new ListHeaderFunc(),
                                  ListItem,
                                  ListFooter,
                                  StickyHeader = new StickyHeaderFunc(),
                                  ...props
                                }) => {
  /*-------------------------生命周期----------------------------*/
  useEffect(() => {
    onRefresh();
  }, []);
  /*-------------------------数据----------------------------*/
  const recyclerRef = useRef(null);
  const [dataProvider] = useState(new DataProvider((r1, r2) => r1 !== r2));
  const [listData, setListData] = useState({
    page: 1,
    size: 10,
    list: [],
  });
  const [loadFinish, setLoadFinish] = useState(true);//是否加载完所有数据
  const [refresh, setRefresh] = useState(true);//是否再刷新
  /*-------------------------API----------------------------*/
  /**
   * api请求
   * @param api_name
   * @param params
   */
  const fetchData = (api_name, params) => {
    new APIManager().netFetch(api_name, params, requestType)
      .done(result => {
        setRefresh(false);
        if (result.code === NetCode.NET_SUCCESS) {
          const { data } = result;
          fetchSuccess(params, data);
        } else {
          Toast.info(result.msg);
        }
      }, error => {
        setRefresh(false);
        console.log(error);
      });
  };
  /*-------------------------事件----------------------------*/
  /**
   * 解析请求成功
   * @param params
   * @param data
   */
  const fetchSuccess = (params, data) => {
    const { total } = data;
    let newList = [...listData.list];
    if (params.page === 1) {
      newList = data.data;
    } else {
      newList = newList.concat(data.data);
    }
    setLoadFinish(newList.length >= total);
    setListData({
      list: newList,
    });
  };

  /**
   * 下拉刷新
   */
  const onRefresh = () => {
    setRefresh(true);
    setListData({
      page: 1,
    });
    getData();
  };

  /**
   * 下拉加载
   */
  const onLoadMore = () => {
    setRefresh(true);
    setListData({
      page: listData.page + 1,
    });
    getData();
  };

  /**
   * 请求数据
   */
  const getData = () => {
    let param = {
      ...params,
      page: listData.page,
      size: listData.size,
    };
    fetchData(apiName, param);
  };
  /*-------------------------事件----------------------------*/

  /**
   * 设置布局
   * @type {LayoutProvider}
   */
  const layoutProvider = new LayoutProvider(
    (index) => {
      if (index === 0) {
        return RecycleItemType.Header;
      } else {
        return RecycleItemType.Item;
      }
    },
    (type, dim) => {
      if (type === RecycleItemType.Header) {
        dim.width = ListHeader.width; // 头部项的宽度
        dim.height = ListHeader.height + height; // 头部项的高度
      } else {
        dim.width = width; // 项的宽度
        dim.height = height; // 项的高度
      }
    },
  );

  /**
   * 返回列表项
   * @param type
   * @param data
   * @param index
   * @returns {JSX.Element}
   */
  const renderRow = (type, data, index) => {
    if (index === 0 && ListHeader.component) {
      return (
        <>
          {ListHeader.component}
          <ListItem item={data} />
        </>
      );
    }
    return (
      <ListItem item={data} />
    );
  };

  /**
   * 列表尾部视图
   * @returns {JSX.Element}
   */
  const renderFooter = () => {
    const { showFooter = true, ListFooter } = props;
    if (ListFooter !== undefined) {
      return (<ListFooter />);
    }
    if (!showFooter || !loadFinish) {
      return <View />;
    }
    return (
      <View
        style={styles.footerStyle}
      >
        <Text>没有更多了</Text>
      </View>
    );
  };

  const overrideRowRenderer = (type, data, index) => {
    const view = renderRow(type, data, index);
    switch (index) {
      case 7:
        const color = "cyan";
        return (
          <View style={{ height: 100, backgroundColor: color, alignItems: "center", justifyContent: "center" }}>
            <Text style={{ fontSize: 32 }}>Overridden sticky</Text>
          </View>
        );
      default:
        return view;
    }
  };

  /**
   * 列表
   * @returns {JSX.Element}
   * @constructor
   */
  const ListView = () => {
    return (
      <RecyclerListView
        ref={recyclerRef}
        scrollViewProps={{
          refreshControl: (
            <RefreshControl
              refreshing={refresh}
              onRefresh={onRefresh}
            />
          ),
        }}
        onEndReached={onLoadMore}
        layoutProvider={layoutProvider}
        dataProvider={dataProvider.cloneWithRows(listData.list)}
        rowRenderer={renderRow}
        renderFooter={renderFooter}
      />
    );
  };
  /*-------------------------主视图----------------------------*/
  if (StickyHeader) {
    return (
      <StickyContainer
        stickyHeaderIndices={StickyHeader.stickyHeaderIndices}
        stickyFooterIndices={StickyHeader.stickyFooterIndices}
        overrideRowRenderer={overrideRowRenderer}>
        <ListView />
      </StickyContainer>
    );
  }
  return (
    <ListView />
  );
};

export default CustomRecyclerListView;

const styles = StyleSheet.create({
  footerStyle: {
    alignItems: "center",
    justifyContent: "center",
    height: 40,
  },
  footerTextStyle: {
    fontSize: 14,
    color: "#999999",
  },
});

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,关于React Native图片多选,我们可以使用第三方库react-native-image-picker来实现。以下是具体的实现步骤: 1. 安装react-native-image-picker库 使用npm或yarn命令进行安装: ``` npm install react-native-image-picker --save ``` 或者 ``` yarn add react-native-image-picker ``` 2. 导入库 在需要使用图片选择器的组件文件中导入库: ``` import ImagePicker from 'react-native-image-picker'; ``` 3. 添加图片选择器按钮 在需要添加图片选择器的地方添加一个按钮,点击该按钮会触发图片选择器的弹出: ``` <Button title="选择图片" onPress={this.selectImage} /> ``` 4. 实现图片选择器方法 定义一个selectImage方法,该方法将调用图片选择器,并且将选择的图片传递给回调函数: ``` selectImage = () => { const options = { title: '选择图片', cancelButtonTitle: '取消', takePhotoButtonTitle: '拍照', chooseFromLibraryButtonTitle: '从相册中选择', storageOptions: { skipBackup: true, path: 'images', }, allowsMultipleSelection: true, }; ImagePicker.showImagePicker(options, (response) => { if (response.didCancel) { console.log('用户取消了图片选择'); } else if (response.error) { console.log('图片选择器出错:', response.error); } else if (response.customButton) { console.log('自定义按钮被点击:', response.customButton); } else { console.log('选择的图片信息:', response); const { uri, fileName, type, fileSize } = response; // 将选择的图片传递给其他组件处理 this.props.onImageSelected({ uri, fileName, type, fileSize }); } }); } ``` 在该方法中,我们定义了图片选择器的参数options,其中allowsMultipleSelection为true表示可以选择多张图片。 然后调用ImagePicker.showImagePicker方法弹出图片选择器,选择的结果将传递给回调函数response,我们可以从response中获取选择的图片的信息,然后将其传递给其他组件进行处理。 以上就是使用react-native-image-picker实现React Native图片多选的步骤。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值