Skip to content

Commit c3a64eb

Browse files
author
yandadaFreedom
committed
feat: 支持sectionfooter
1 parent e4471e4 commit c3a64eb

1 file changed

Lines changed: 71 additions & 6 deletions

File tree

packages/webpack-plugin/lib/runtime/components/react/mpx-section-list.tsx

Lines changed: 71 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,17 @@ import useInnerProps, { getCustomEvent } from './getInnerListeners'
55
import { extendObject, useLayout, useTransformStyle, GestureHandler, flatGesture } from './utils'
66
interface ListItem {
77
isSectionHeader?: boolean;
8+
isSectionFooter?: boolean;
89
_originalItemIndex?: number;
910
[key: string]: any;
1011
}
1112

1213
interface Section {
1314
headerData: ListItem | null;
15+
footerData: ListItem | null;
1416
data: ListItem[];
1517
hasSectionHeader?: boolean;
18+
hasSectionFooter?: boolean;
1619
_originalItemIndex?: number;
1720
}
1821

@@ -32,13 +35,15 @@ interface SectionListProps {
3235
style?: Record<string, any>;
3336
itemHeight?: ItemHeightType;
3437
sectionHeaderHeight?: ItemHeightType;
38+
sectionFooterHeight?: ItemHeightType;
3539
listHeaderData?: any;
3640
listHeaderHeight?: ItemHeightType;
3741
useListHeader?: boolean;
3842
listFooterData?: any;
3943
useListFooter?: boolean;
4044
'genericrecycle-item'?: string;
4145
'genericsection-header'?: string;
46+
'genericsection-footer'?: string;
4247
'genericlist-header'?: string;
4348
'genericlist-footer'?: string;
4449
'enable-var'?: boolean;
@@ -91,13 +96,15 @@ const _SectionList = forwardRef<any, SectionListProps>((props = {}, ref) => {
9196
style = {},
9297
itemHeight = {},
9398
sectionHeaderHeight = {},
99+
sectionFooterHeight = {},
94100
listHeaderHeight = {},
95101
listHeaderData = null,
96102
useListHeader = false,
97103
listFooterData = null,
98104
useListFooter = false,
99105
'genericrecycle-item': genericrecycleItem,
100106
'genericsection-header': genericsectionHeader,
107+
'genericsection-footer': genericsectionFooter,
101108
'genericlist-header': genericListHeader,
102109
'genericlist-footer': genericListFooter,
103110
'enable-var': enableVar,
@@ -120,7 +127,6 @@ const _SectionList = forwardRef<any, SectionListProps>((props = {}, ref) => {
120127
const scrollViewRef = useRef<any>(null)
121128
const sectionListGestureRef = useRef<any>()
122129

123-
124130
const indexMap = useRef<{ [key: string]: string | number }>({})
125131

126132
const reverseIndexMap = useRef<{ [key: string]: number }>({})
@@ -164,7 +170,7 @@ const _SectionList = forwardRef<any, SectionListProps>((props = {}, ref) => {
164170
}
165171

166172
// 通过sectionIndex和rowIndex获取原始索引
167-
const getOriginalIndex = (sectionIndex: number, rowIndex: number | 'header'): number => {
173+
const getOriginalIndex = (sectionIndex: number, rowIndex: number | 'header' | 'footer'): number => {
168174
const key = `${sectionIndex}_${rowIndex}`
169175
return reverseIndexMap.current[key] ?? -1 // 如果找不到,返回-1
170176
}
@@ -174,9 +180,15 @@ const _SectionList = forwardRef<any, SectionListProps>((props = {}, ref) => {
174180
// 通过索引映射表快速定位位置
175181
const position = indexMap.current[index]
176182
const [sectionIndex, itemIndex] = (position as string).split('_')
183+
const targetSectionIndex = Number(sectionIndex) || 0
184+
const targetItemIndex = itemIndex === 'header'
185+
? 0
186+
: itemIndex === 'footer'
187+
? convertedListData[targetSectionIndex].data.length + 1
188+
: Number(itemIndex) + 1
177189
scrollViewRef.current.scrollToLocation?.({
178-
itemIndex: itemIndex === 'header' ? 0 : Number(itemIndex) + 1,
179-
sectionIndex: Number(sectionIndex) || 0,
190+
itemIndex: targetItemIndex,
191+
sectionIndex: targetSectionIndex,
180192
animated,
181193
viewOffset,
182194
viewPosition
@@ -211,6 +223,19 @@ const _SectionList = forwardRef<any, SectionListProps>((props = {}, ref) => {
211223
}
212224
}
213225

226+
const getSectionFooterHeight = ({ sectionIndex }: { sectionIndex: number }) => {
227+
const item = convertedListData[sectionIndex]
228+
const { hasSectionFooter } = item
229+
// 使用getOriginalIndex获取原始索引
230+
const originalIndex = getOriginalIndex(sectionIndex, 'footer')
231+
if (!hasSectionFooter) return 0
232+
if ((sectionFooterHeight as ItemHeightType).getter) {
233+
return (sectionFooterHeight as ItemHeightType).getter?.(item, originalIndex) || 0
234+
} else {
235+
return (sectionFooterHeight as ItemHeightType).value || 0
236+
}
237+
}
238+
214239
const convertedListData = useMemo(() => {
215240
const sections: Section[] = []
216241
let currentSection: Section | null = null
@@ -233,23 +258,48 @@ const _SectionList = forwardRef<any, SectionListProps>((props = {}, ref) => {
233258
// 创建新的 section
234259
currentSection = {
235260
headerData: item,
261+
footerData: null,
236262
data: [],
237263
hasSectionHeader: true,
264+
hasSectionFooter: false,
238265
_originalItemIndex: index
239266
}
240267
// 为 section header 添加索引映射
241268
const sectionIndex = sections.length
242269
indexMap.current[index] = `${sectionIndex}_header`
243270
// 添加反向索引映射
244271
reverseIndexMap.current[`${sectionIndex}_header`] = index
272+
} else if (item.isSectionFooter) {
273+
// 如果没有当前 section,创建一个默认的
274+
if (!currentSection) {
275+
// 创建默认section (无header的section)
276+
currentSection = {
277+
headerData: null,
278+
footerData: null,
279+
data: [],
280+
hasSectionHeader: false,
281+
hasSectionFooter: false,
282+
_originalItemIndex: -1
283+
}
284+
}
285+
const sectionIndex = sections.length
286+
currentSection.footerData = item
287+
currentSection.hasSectionFooter = true
288+
indexMap.current[index] = `${sectionIndex}_footer`
289+
// 添加反向索引映射
290+
reverseIndexMap.current[`${sectionIndex}_footer`] = index
291+
sections.push(currentSection)
292+
currentSection = null
245293
} else {
246294
// 如果没有当前 section,创建一个默认的
247295
if (!currentSection) {
248296
// 创建默认section (无header的section)
249297
currentSection = {
250298
headerData: null,
299+
footerData: null,
251300
data: [],
252301
hasSectionHeader: false,
302+
hasSectionFooter: false,
253303
_originalItemIndex: -1
254304
}
255305
}
@@ -313,17 +363,19 @@ const _SectionList = forwardRef<any, SectionListProps>((props = {}, ref) => {
313363

314364
// 添加该 section 尾部位置信息
315365
// 因为即使 sectionList 没传 renderSectionFooter,getItemLayout 中的 index 的计算也会包含尾部节点
366+
const footerHeight = getSectionFooterHeight({ sectionIndex })
316367
layouts.push({
317-
length: 0,
368+
length: footerHeight,
318369
offset,
319370
index: layouts.length
320371
})
372+
offset += footerHeight
321373
})
322374
return {
323375
itemLayouts: layouts,
324376
getItemLayout: (data: any, index: number) => layouts[index]
325377
}
326-
}, [convertedListData, useListHeader, itemHeight.value, itemHeight.getter, sectionHeaderHeight.value, sectionHeaderHeight.getter, listHeaderHeight.value, listHeaderHeight.getter])
378+
}, [convertedListData, useListHeader, itemHeight.value, itemHeight.getter, sectionHeaderHeight.value, sectionHeaderHeight.getter, sectionFooterHeight.value, sectionFooterHeight.getter, listHeaderHeight.value, listHeaderHeight.getter])
327379

328380
const scrollAdditionalProps = extendObject(
329381
{
@@ -413,6 +465,18 @@ const _SectionList = forwardRef<any, SectionListProps>((props = {}, ref) => {
413465
[generichash, genericsectionHeader]
414466
)
415467

468+
const renderSectionFooter = useMemo(
469+
() => {
470+
const SectionFooterComponent = getGeneric(generichash, genericsectionFooter)
471+
if (!SectionFooterComponent) return undefined
472+
return (sectionData: { section: Section }) => {
473+
if (!sectionData.section.hasSectionFooter) return null
474+
return createElement(SectionFooterComponent, { itemData: sectionData.section.footerData })
475+
}
476+
},
477+
[generichash, genericsectionFooter]
478+
)
479+
416480
const ListHeaderComponent = useMemo(
417481
() => {
418482
if (!useListHeader) return null
@@ -447,6 +511,7 @@ const _SectionList = forwardRef<any, SectionListProps>((props = {}, ref) => {
447511
ListHeaderComponent: useListHeader ? ListHeaderComponent : null,
448512
ListFooterComponent: useListFooter ? ListFooterComponent : null,
449513
renderSectionHeader: renderSectionHeader,
514+
renderSectionFooter: renderSectionFooter,
450515
refreshControl: refresherEnabled
451516
? createElement(RefreshControl, {
452517
onRefresh: onRefresh,

0 commit comments

Comments
 (0)