Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(ios): waterfall component support footer view #4098

Merged
merged 1 commit into from
Oct 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion docs/api/hippy-react/components.md
Original file line number Diff line number Diff line change
Expand Up @@ -550,7 +550,8 @@ import icon from './qb_icon_new.png';
| interItemSpacing | item 间的垂直间距 | `number` | `Android、iOS、Voltron` |
| contentInset | 内容缩进 ,默认值 `{ top:0, left:0, bottom:0, right:0 }` | `Object` | `Android、iOS、Voltron` |
| renderItem | 这里的入参是当前 item 的 index,在这里可以凭借 index 获取到瀑布流一个具体单元格的数据,从而决定如何渲染这个单元格。 | `(index: number) => React.ReactElement` | `Android、iOS、Voltron` |
| renderBanner | 如何渲染 Banner。 | `() => React.ReactElement` | `Android、iOS、Voltron`
| renderBanner | 如何渲染 Banner (即Header,显示在内容顶部) | `() => React.ReactElement` | `Android、iOS、Voltron` |
| renderFooter | 如何渲染 Footer(与renderBanner对应,Footer显示在内容底部) | `() => React.ReactElement` | `iOS`(3.3.2版本起支持) |
| getItemStyle | 设置`WaterfallItem`容器的样式。 | `(index: number) => styleObject` | `Android、iOS、Voltron` |
| getItemType | 指定一个函数,在其中返回对应条目的类型(返回Number类型的自然数,默认是0),List 将对同类型条目进行复用,所以合理的类型拆分,可以很好地提升list 性能。 | `(index: number) => number` | `Android、iOS、Voltron` |
| getItemKey | 指定一个函数,在其中返回对应条目的 Key 值,详见 [React 官文](//reactjs.org/docs/lists-and-keys.html) | `(index: number) => any` | `Android、iOS、Voltron` |
Expand Down
4 changes: 3 additions & 1 deletion docs/api/hippy-vue/external-components.md
Original file line number Diff line number Diff line change
Expand Up @@ -280,7 +280,7 @@ export default {
| columnSpacing | 瀑布流每列之前的水平间距 | `number` | `Android、iOS、Voltron` |
| interItemSpacing | item 间的垂直间距 | `number` | `Android、iOS、Voltron` |
| contentInset | 内容缩进 ,默认值 `{ top:0, left:0, bottom:0, right:0 }` | `Object` | `Android、iOS、Voltron` |
| containBannerView | 是否包含`bannerView`,只能有一个bannerView,`Android` 暂不支持 | `boolean` | `iOS、Voltron` |
| containBannerView | 是否包含`bannerView`,只能有一个bannerView, (`Android` 暂不支持,`iOS` 3.3.2版本起已废弃该属性,请使用`waterfall-item`组件`isHeader/isFooter`属性代替) | `boolean` | `iOS、Voltron` |
| containPullHeader | 是否包含`pull-header`;`Android` 暂不支持,可以用 `ul-refresh` 组件替代 | `boolean` | `iOS、Voltron` |
| containPullFooter | 是否包含 `pull-footer` | `boolean` | `Android、iOS、Voltron` |
| numberOfColumns | 瀑布流列数量,Default: 2 | `number` | `Android、iOS、Voltron` |
Expand Down Expand Up @@ -323,3 +323,5 @@ export default {
| --------------------- | ------------------------------------------------------------ | ----------------------------------------------------------- | -------- |
| type | 指定一个函数,在其中返回对应条目的类型(返回Number类型的自然数,默认是0),List 将对同类型条目进行复用,所以合理的类型拆分,可以很好地提升 List 性能。 | `number` | `Android、iOS、Voltron` |
| key | 指定一个函数,在其中返回对应条目的 Key 值,详见 [Vue 官网](//vuejs.org/v2/guide/list.html) | `string` | `Android、iOS、Voltron` |
| isHeader | 指定该Item是否为Header(即bannerView,显示在内容区顶部) | `boolean` | `iOS`(3.3.2版本起支持) |
| isFooter | 指定该Item是否为Footer(显示在内容区底部) | `boolean` | `iOS`(3.3.2版本起支持) |
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ export default class ListExample extends React.Component {
this.onHeaderPulling = this.onHeaderPulling.bind(this);
this.onFooterPulling = this.onFooterPulling.bind(this);
this.renderBanner = this.renderBanner.bind(this);
this.renderFooter = this.renderFooter.bind(this);
this.getItemStyle = this.getItemStyle.bind(this);
this.getHeaderStyle = this.getHeaderStyle.bind(this);
this.onScroll = this.onScroll.bind(this);
Expand Down Expand Up @@ -236,10 +237,10 @@ export default class ListExample extends React.Component {
}

onScroll(obj) {

console.log('onScroll', obj);
}

// render banner(it is not supported on Android yet)
// render banner
renderBanner() {
if (this.state.dataSource.length === 0) return null;
return (<View style={{
Expand All @@ -257,6 +258,24 @@ export default class ListExample extends React.Component {
</View>);
}

// render footer (currently only iOS support)
renderFooter() {
if (this.state.dataSource.length === 0) return null;
return (<View style={{
backgroundColor: 'grey',
height: 100,
justifyContent: 'center',
alignItems: 'center',
}}>
<Text style={{
fontSize: 20,
color: 'white',
lineHeight: 100,
height: 100,
}}>Footer View</Text>
</View>);
}

renderItem(index) {
const { dataSource } = this.state;
let styleUI = null;
Expand Down Expand Up @@ -362,7 +381,9 @@ export default class ListExample extends React.Component {
style={{ flex: 1 }}
onScroll={this.onScroll}
renderBanner={this.renderBanner}
renderFooter={this.renderFooter}
renderPullHeader={this.renderPullHeader}
renderPullFooter={this.renderPullFooter}
onEndReached={this.onEndReached}
onFooterReleased={this.onEndReached}
onHeaderReleased={this.onHeaderReleased}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,17 +25,18 @@
</p>
</pull-header>
<div
v-if="!isAndroid"
v-if="!isAndroid && !isiOS"
class="banner-view"
>
<span>BannerView</span>
</div>
</div>
<waterfall-item
v-else
v-else
:fullSpan="true",
:isHeader="true",
class="banner-view"
>

Check failure on line 38 in driver/js/examples/hippy-vue-demo/src/components/native-demos/demo-waterfall.vue

View workflow job for this annotation

GitHub Actions / frontend_build_tests (16.x)

Parsing error: duplicate-attribute

Check failure on line 38 in driver/js/examples/hippy-vue-demo/src/components/native-demos/demo-waterfall.vue

View workflow job for this annotation

GitHub Actions / frontend_build_tests (16.x)

Duplicate attribute ','

Check failure on line 38 in driver/js/examples/hippy-vue-demo/src/components/native-demos/demo-waterfall.vue

View workflow job for this annotation

GitHub Actions / frontend_build_tests (17.x)

Parsing error: duplicate-attribute

Check failure on line 38 in driver/js/examples/hippy-vue-demo/src/components/native-demos/demo-waterfall.vue

View workflow job for this annotation

GitHub Actions / frontend_build_tests (17.x)

Duplicate attribute ','
<span>BannerView</span>
<span>Banner View</span>
</waterfall-item>
<waterfall-item
v-for="(ui, index) in dataSource"
Expand All @@ -57,6 +58,13 @@
:item-bean="ui.itemBean"
/>
</waterfall-item>
<waterfall-item
:fullSpan="true",
:isFooter="true",
class="banner-view"
>
<span>Footer View</span>
</waterfall-item>

Check failure on line 67 in driver/js/examples/hippy-vue-demo/src/components/native-demos/demo-waterfall.vue

View workflow job for this annotation

GitHub Actions / frontend_build_tests (16.x)

Parsing error: duplicate-attribute

Check failure on line 67 in driver/js/examples/hippy-vue-demo/src/components/native-demos/demo-waterfall.vue

View workflow job for this annotation

GitHub Actions / frontend_build_tests (16.x)

Duplicate attribute ','

Check failure on line 67 in driver/js/examples/hippy-vue-demo/src/components/native-demos/demo-waterfall.vue

View workflow job for this annotation

GitHub Actions / frontend_build_tests (17.x)

Parsing error: duplicate-attribute

Check failure on line 67 in driver/js/examples/hippy-vue-demo/src/components/native-demos/demo-waterfall.vue

View workflow job for this annotation

GitHub Actions / frontend_build_tests (17.x)

Duplicate attribute ','
<pull-footer
ref="pullFooter"
class="pull-footer"
Expand Down Expand Up @@ -91,6 +99,7 @@
footerRefreshText: '正在加载...',
isLoading: false,
isAndroid: Vue.Native.Platform === 'android',
isiOS: Vue.Native.Platform === 'android',
};
},
mounted() {
Expand Down Expand Up @@ -172,7 +181,7 @@
this.fetchingDataFlag = false;
this.headerRefreshText = '2秒后收起';
// 要主动调用collapsePullHeader关闭pullHeader,否则可能会导致released事件不能再次触发
this.$refs.pullHeader.collapsePullHeader({ time: 2000 });

Check failure on line 184 in driver/js/examples/hippy-vue-demo/src/components/native-demos/demo-waterfall.vue

View workflow job for this annotation

GitHub Actions / frontend_build_tests (16.x)

'dataSource' is assigned a value but never used. Allowed unused vars must match /^_.+/u

Check failure on line 184 in driver/js/examples/hippy-vue-demo/src/components/native-demos/demo-waterfall.vue

View workflow job for this annotation

GitHub Actions / frontend_build_tests (17.x)

'dataSource' is assigned a value but never used. Allowed unused vars must match /^_.+/u
},
async onRefresh() {
// 重新获取数据
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
ref="gridView"
:content-inset="contentInset"
:column-spacing="columnSpacing"
:contain-banner-view="!isAndroid"
:contain-pull-footer="true"
:inter-item-spacing="interItemSpacing"
:number-of-columns="numberOfColumns"
Expand All @@ -25,17 +24,18 @@
</p>
</pull-header>
<div
v-if="!isAndroid"
v-if="!isAndroid && !isiOS"
class="banner-view"
>
<span>BannerView</span>
</div>
<waterfall-item
v-else
:full-span="true"
:isHeader="true"
class="banner-view"
>
<span>BannerView</span>
<span>Banner View</span>
</waterfall-item>
<waterfall-item
v-for="(ui, index) in dataSource"
Expand All @@ -57,6 +57,12 @@
:item-bean="ui.itemBean"
/>
</waterfall-item>
<waterfall-item
:isFooter="true"
class="banner-view"
>
<span>Footer View</span>
</waterfall-item>
<pull-footer
ref="pullFooter"
class="pull-footer"
Expand Down Expand Up @@ -95,6 +101,7 @@ const numberOfColumns = 2;
// inner content padding
const contentInset = { top: 0, left: 5, bottom: 0, right: 5 };
const isAndroid = Native.Platform === 'android';
const isiOS = Native.Platform === 'ios';

const mockFetchData = async (): Promise<any> => new Promise((resolve) => {
setTimeout(() => {
Expand Down Expand Up @@ -249,6 +256,7 @@ export default defineComponent({
onEndReached,
onClickItem,
isAndroid,
isiOS,
onHeaderPulling,
onFooterPulling,
onHeaderIdle,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,12 @@ interface WaterfallViewProps {
// Declare whether banner view exists
containBannerView?: boolean

// Return banner view element
// Return banner view element (header)
renderBanner?: () => React.ReactElement;

// Return footer banner view element
renderFooter?: () => React.ReactElement;

/**
* Passing the data and returns the row component.
*
Expand Down Expand Up @@ -253,6 +256,7 @@ class WaterfallView extends React.Component<WaterfallViewProps> {
const {
style = {},
renderBanner,
renderFooter,
numberOfColumns = 2,
columnSpacing = 0,
interItemSpacing = 0,
Expand Down Expand Up @@ -293,17 +297,18 @@ class WaterfallView extends React.Component<WaterfallViewProps> {
if (typeof renderBanner === 'function') {
const banner = renderBanner();
if (banner) {
if (Device.platform.OS === 'ios' || Device.platform.OS === 'ohos') {
if (Device.platform.OS === 'ohos') {
itemList.push((
<View key="bannerView">
{React.cloneElement(banner)}
</View>
));
nativeProps.containBannerView = true;
} else if (Device.platform.OS === 'android') {
} else {
const itemProps = {
key: 'bannerView',
fullSpan: true,
isHeader: true,
fullSpan: true, // only for android
style: {},
};
itemList.push((
Expand Down Expand Up @@ -357,6 +362,23 @@ class WaterfallView extends React.Component<WaterfallViewProps> {
warn('Waterfall attribute [renderItem] is not Function');
}

// only ios support currently
if (typeof renderFooter === 'function') {
const footer = renderFooter();
if (footer) {
const itemProps = {
key: 'WaterfallFooterView',
isFooter: true,
style: {},
};
itemList.push((
<WaterfallViewItem{...itemProps}>
{React.cloneElement(footer)}
</WaterfallViewItem>
));
}
}

return (
// @ts-ignore
<ul
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,12 @@ NS_ASSUME_NONNULL_BEGIN
/// Waterfall item's shadowView
@interface HippyShadowWaterfallItem : HippyShadowView

/// Whether is header view
@property (nonatomic, assign) BOOL isHeader;

/// Whether is footer view
@property (nonatomic, assign) BOOL isFooter;

/// frame change observer, usually is shadowListView
@property (nonatomic, weak) id<HippyShadowWaterfallItemFrameChangedProtocol> observer;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ @implementation HippyWaterfallItemViewManager

HIPPY_EXPORT_MODULE(WaterfallItem)

HIPPY_EXPORT_SHADOW_PROPERTY(isHeader, BOOL)
HIPPY_EXPORT_SHADOW_PROPERTY(isFooter, BOOL)

- (UIView *)view {
return [HippyWaterfallItemView new];
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,10 +56,14 @@ typedef NS_ENUM(NSInteger, NativeRenderScrollState) {
BOOL _allowNextScrollNoMatterWhat;
}

/**
* Content inset for HippyWaterfallView
*/
@property(nonatomic, assign) UIEdgeInsets contentInset;
/// inset for items
@property (nonatomic, assign) UIEdgeInsets contentInset;

/// inset for Header
@property (nonatomic, assign) UIEdgeInsets headerInset;

/// inset for Footer
@property (nonatomic, assign) UIEdgeInsets footerInset;

/**
* Number of columns for HippyWaterfallView
Expand Down
Loading
Loading