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",
},
});