Skip to content

Commit 11cf9a2

Browse files
authored
fix:修复使用react-native-largelist数据列表懒加载展示不全问题 (#27)
Signed-off-by: wupingyuan <wupingyuan2@h-partners.com>
1 parent 539ddb2 commit 11cf9a2

File tree

7 files changed

+125
-81
lines changed

7 files changed

+125
-81
lines changed

harmony/spring_scrollview/src/main/cpp/SpringScrollViewComponentInstance.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,4 +239,24 @@ void SpringScrollViewComponentInstance::finalizeUpdates() {
239239
this->getLocalRootArkUINode().init();
240240
}
241241

242+
void SpringScrollViewComponentInstance::sendEventAnimationsOnScroll(
243+
facebook::react::RNCSpringScrollViewEventEmitter::OnScroll onScroll) {
244+
auto nativeAnimatedTurboModule = m_springNativeAnimatedTurboModule.lock();
245+
if (nativeAnimatedTurboModule == nullptr) {
246+
auto instance = m_deps->rnInstance.lock();
247+
if (instance == nullptr) {
248+
return;
249+
}
250+
nativeAnimatedTurboModule =
251+
instance->getTurboModule<NativeAnimatedTurboModule>("NativeAnimatedTurboModule");
252+
m_springNativeAnimatedTurboModule = nativeAnimatedTurboModule;
253+
}
254+
if (nativeAnimatedTurboModule != nullptr) {
255+
using folly::dynamic;
256+
dynamic payload = dynamic::object("contentOffset",dynamic::object("x",onScroll.contentOffset.x)("y",onScroll.contentOffset.y)("refreshStatus",onScroll.refreshStatus)("loadingStatus",onScroll.loadingStatus));
257+
nativeAnimatedTurboModule->handleComponentEvent(m_tag, "onScroll",payload);
258+
DLOG(INFO) << "SpringScrollViewComponentInstance::sendEventAnimationsOnScroll y " << onScroll.contentOffset.y;
259+
}
260+
}
261+
242262
} // namespace rnoh

harmony/spring_scrollview/src/main/cpp/SpringScrollViewComponentInstance.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
#include "ShadowNodes.h"
3232
#include "Types.h"
3333
#include <react/renderer/core/LayoutContext.h>
34+
#include "RNOHCorePackage/TurboModules/Animated/NativeAnimatedTurboModule.h"
3435

3536
namespace rnoh {
3637
class SpringScrollViewComponentInstance : public CppComponentInstance<facebook::react::RNCSpringScrollViewShadowNode>,
@@ -54,6 +55,7 @@ class SpringScrollViewComponentInstance : public CppComponentInstance<facebook::
5455
bool swiperStatus = false;
5556
facebook::react::Size m_containerSize;
5657
facebook::react::Size m_contentSize;
58+
std::weak_ptr<NativeAnimatedTurboModule> m_springNativeAnimatedTurboModule{};
5759
public:
5860
SpringScrollViewComponentInstance(Context context);
5961
void onChildInserted(ComponentInstance::Shared const &childComponentInstance, std::size_t index) override;
@@ -81,6 +83,7 @@ class SpringScrollViewComponentInstance : public CppComponentInstance<facebook::
8183
void callArkTSReboundStart(float f, float t, long d,bool isVertical) override;
8284
facebook::react::Point getCurrentOffset() const override;
8385
bool isHandlingTouches() const override;
86+
void sendEventAnimationsOnScroll(facebook::react::RNCSpringScrollViewEventEmitter::OnScroll onScroll) override;
8487
};
8588
} // namespace rnoh
8689
#endif // HARMONY_SpringScrollViewCOMPONENTINSTANCE_H

harmony/spring_scrollview/src/main/cpp/SpringScrollViewNode.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -401,8 +401,9 @@ void SpringScrollViewNode ::setContentOffset(float x, float y) {
401401
ArkUI_AttributeItem translateItem = {translateValue.data(), translateValue.size()};
402402
NativeNodeApi::getInstance()->setAttribute(m_stackArkUINodeHandle, NODE_TRANSLATE, &translateItem);
403403
facebook::react::RNCSpringScrollViewEventEmitter::OnScroll onScroll = {
404-
{contentOffset.x / 2, contentOffset.y / 2}, refreshStatus, loadingStatus};
404+
{contentOffset.x , contentOffset.y }, refreshStatus, loadingStatus};
405405
m_scrollNodeDelegate->onScroll(onScroll);
406+
m_scrollNodeDelegate->sendEventAnimationsOnScroll(onScroll);
406407
DLOG(INFO) << "SpringScrollViewNode setContentOffset loadingStatus:" << loadingStatus
407408
<< " refreshStatus:" << refreshStatus << " contentOffset.y " << contentOffset.y << " contentOffset.x "
408409
<< contentOffset.x;

harmony/spring_scrollview/src/main/cpp/SpringScrollViewNode.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ class SpringScrollViewNodeDelegate {
5858
virtual void callArkTSInnerStart(float f, float v0, float d, float lower, float upper, bool pagingEnabled, float pageSize,bool isVertical){};
5959
virtual void callArkTSOuterStart(float f, float v0, float d,bool isVertical){};
6060
virtual void callArkTSReboundStart(float f, float t, long d,bool isVertical){};
61+
virtual void sendEventAnimationsOnScroll(facebook::react::RNCSpringScrollViewEventEmitter::OnScroll onScroll){};
6162
};
6263

6364
class SpringScrollViewNode : public ArkUINode, public EventBus::EventHandler<SpringScrollViewEvent> {

src/NormalFooter.js

Lines changed: 74 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -43,76 +43,88 @@ export class NormalFooter extends LoadingFooter {
4343

4444
startLoadAnimation = () => {
4545
this.loadingAnimation.setValue(0);
46-
Animated.timing(this.loadingAnimation, {
47-
toValue: 1,
48-
duration: 4000,
49-
easing: Easing.linear,
50-
useNativeDriver:false
51-
}).start(() => this.startLoadAnimation());
46+
Animated.loop(
47+
Animated.timing(this.loadingAnimation, {
48+
toValue: 1,
49+
duration: 1000,
50+
easing: Easing.linear,
51+
useNativeDriver: true
52+
}),
53+
{ iterations: -1 },
54+
).start();
5255
}
5356

5457
_renderIcon() {
5558
const s = this.state.status;
56-
if(Platform.OS === "harmony") {
57-
this.startLoadAnimation();
58-
const rotateValue=this.loadingAnimation.interpolate({
59-
inputRange: [0,1],
60-
outputRange: ["0deg", "360deg"]
61-
})
62-
if (s === "loading" || s === "cancelLoading" || s === "rebound") {
63-
return <Animated.Image
64-
source={require("./Customize/res/icon_load.png")}
65-
style={{
66-
transform: [
67-
{
68-
rotate: rotateValue
69-
}
70-
]
71-
}}
72-
/>;
59+
if (Platform.OS === "harmony") {
60+
this.startLoadAnimation();
61+
const rotateValue = this.loadingAnimation.interpolate({
62+
inputRange: [0, 1],
63+
outputRange: ["0deg", "360deg"]
64+
})
65+
if (s === "loading" || s === "cancelLoading" || s === "rebound") {
66+
return <Animated.Image
67+
source={require("./Customize/res/icon_load.png")}
68+
style={{
69+
transform: [
70+
{
71+
rotate: rotateValue
72+
}
73+
]
74+
}}
75+
/>;
76+
}
77+
const { maxHeight, offset, bottomOffset } = this.props;
78+
return (
79+
<Animated.Image
80+
source={require("./Customize/res/arrow.png")}
81+
style={{
82+
transform: [
83+
{
84+
rotate: offset.interpolate({
85+
inputRange: [
86+
bottomOffset - 1 + 45,
87+
bottomOffset + 45,
88+
bottomOffset + maxHeight,
89+
bottomOffset + maxHeight + 1
90+
],
91+
outputRange: ["180deg", "180deg", "0deg", "0deg"]
92+
})
93+
}
94+
]
95+
}}
96+
/>
97+
);
7398
}
74-
return (
75-
<Animated.Image
76-
source={require("./Customize/res/arrow.png")}
77-
style={{
78-
transform: [
79-
{
80-
rotate: 180-this.state.rotateY * 2.5 + "deg"
81-
}
82-
]
83-
}}
84-
/>
85-
);
86-
}
87-
else {
88-
if (s === "loading" || s === "cancelLoading" || s === "rebound") {
89-
return <ActivityIndicator color={"gray"}/>;
99+
else {
100+
if (s === "loading" || s === "cancelLoading" || s === "rebound") {
101+
return <ActivityIndicator color={"gray"} />;
102+
}
103+
const { maxHeight, offset, bottomOffset } = this.props;
104+
return (
105+
<Animated.Image
106+
source={require("./Customize/res/arrow.png")}
107+
style={{
108+
transform: [
109+
{
110+
rotate: offset.interpolate({
111+
inputRange: [
112+
bottomOffset - 1 + 45,
113+
bottomOffset + 45,
114+
bottomOffset + maxHeight,
115+
bottomOffset + maxHeight + 1
116+
],
117+
outputRange: ["180deg", "180deg", "0deg", "0deg"]
118+
})
119+
}
120+
]
121+
}}
122+
/>
123+
);
90124
}
91-
const { maxHeight, offset, bottomOffset } = this.props;
92-
return (
93-
<Animated.Image
94-
source={require("./Customize/res/arrow.png")}
95-
style={{
96-
transform: [
97-
{
98-
rotate: offset.interpolate({
99-
inputRange: [
100-
bottomOffset - 1 + 45,
101-
bottomOffset + 45,
102-
bottomOffset + maxHeight,
103-
bottomOffset + maxHeight + 1
104-
],
105-
outputRange: ["180deg", "180deg", "0deg", "0deg"]
106-
})
107-
}
108-
]
109-
}}
110-
/>
111-
);
112-
}
113125
}
114126

115-
renderContent(){
127+
renderContent() {
116128
return null;
117129
}
118130

src/NormalHeader.js

Lines changed: 24 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -39,24 +39,27 @@ export class NormalHeader extends RefreshHeader {
3939

4040
startLoadAnimation = () => {
4141
this.loadingAnimation.setValue(0);
42-
Animated.timing(this.loadingAnimation, {
43-
toValue: 1,
44-
duration: 4000,
45-
easing: Easing.linear,
46-
useNativeDriver:false
47-
}).start(() => this.startLoadAnimation());
42+
Animated.loop(
43+
Animated.timing(this.loadingAnimation, {
44+
toValue: 1,
45+
duration: 1000,
46+
easing: Easing.linear,
47+
useNativeDriver: true
48+
}),
49+
{ iterations: -1 },
50+
).start();
4851
}
4952

5053
_renderIcon() {
5154
const s = this.state.status;
5255
if(Platform.OS === "harmony"){
53-
this.startLoadAnimation();
54-
const rotateValue=this.loadingAnimation.interpolate({
55-
inputRange: [0,1],
56-
outputRange: ["0deg", "360deg"]
57-
})
58-
if (s === "refreshing" || s === "rebound") {
59-
return <Animated.Image
56+
this.startLoadAnimation();
57+
const rotateValue=this.loadingAnimation.interpolate({
58+
inputRange: [0,1],
59+
outputRange: ["0deg", "360deg"]
60+
})
61+
if (s === "refreshing" || s === "rebound") {
62+
return (<Animated.Image
6063
source={require("./Customize/res/icon_load.png")}
6164
style={{
6265
transform: [
@@ -65,20 +68,26 @@ export class NormalHeader extends RefreshHeader {
6568
}
6669
]
6770
}}
68-
/>;
71+
/>);
6972
}
73+
else{
74+
const { maxHeight, offset } = this.props;
7075
return (
7176
<Animated.Image
7277
source={require("./Customize/res/arrow.png")}
7378
style={{
7479
transform: [
7580
{
76-
rotate: -this.state.rotateY * 2.5 + "deg"
81+
rotate: offset.interpolate({
82+
inputRange: [-maxHeight - 1 - 10, -maxHeight - 10, -50, -49],
83+
outputRange: ["180deg", "180deg", "0deg", "0deg"]
84+
})
7785
}
7886
]
7987
}}
8088
/>
8189
);
90+
}
8291
}
8392
else {
8493
if (s === "refreshing" || s === "rebound") {

src/SpringScrollView.js

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -323,8 +323,6 @@ export class SpringScrollView extends React.PureComponent<SpringScrollViewPropTy
323323
loadingStatus
324324
} = e.nativeEvent;
325325
this._contentOffset = { x, y };
326-
this._refreshHeader?.changeToY(y);
327-
this._loadingFooter?.changeToY(y);
328326
if (this._refreshStatus !== refreshStatus) {
329327
this._toRefreshStatus(refreshStatus);
330328
this.props.onRefresh && refreshStatus === "refreshing" && this.props.onRefresh();
@@ -573,7 +571,7 @@ export class SpringScrollView extends React.PureComponent<SpringScrollViewPropTy
573571
showsHorizontalScrollIndicator: true,
574572
initialContentOffset: { x: 0, y: 0 },
575573
alwaysBounceVertical: true,
576-
pagingEnabled: false,
574+
pagingEnabled: true,
577575
pageSize: { width: 0, height: 0 },
578576
};
579577
}

0 commit comments

Comments
 (0)