From aca49e5c86c1eb94b0cc6f0024feb1103c97b49d Mon Sep 17 00:00:00 2001 From: siguangli Date: Thu, 7 Mar 2024 16:07:06 +0800 Subject: [PATCH] fix(android): do scrollTo after scroll range reduce (#3770) Co-authored-by: maxli --- .../mtt/hippy/uimanager/RenderManager.java | 14 +++++++--- .../scroll/HippyHorizontalScrollView.java | 10 ++++++- .../scroll/HippyScrollViewController.java | 26 +++++++++++++++++++ .../views/scroll/HippyVerticalScrollView.java | 9 +++++++ 4 files changed, 54 insertions(+), 5 deletions(-) diff --git a/android/sdk/src/main/java/com/tencent/mtt/hippy/uimanager/RenderManager.java b/android/sdk/src/main/java/com/tencent/mtt/hippy/uimanager/RenderManager.java index 4b233637e83..e98e1cca28e 100644 --- a/android/sdk/src/main/java/com/tencent/mtt/hippy/uimanager/RenderManager.java +++ b/android/sdk/src/main/java/com/tencent/mtt/hippy/uimanager/RenderManager.java @@ -103,10 +103,16 @@ void addNullUINodeIfNeeded(RenderNode renderNode) { public void updateLayout(int id, int x, int y, int w, int h) { LogUtils.d("RenderManager", "updateLayout ID " + id); - RenderNode uiNode = mNodes.get(id); - uiNode.updateLayout(x, y, w, h); - - addUpdateNodeIfNeeded(uiNode); + RenderNode node = mNodes.get(id); + if (node != null) { + node.updateLayout(x, y, w, h); + addUpdateNodeIfNeeded(node); + if (node.getParent() instanceof ScrollViewRenderNode) { + // ScrollView doesn't receive updateLayout when its content changes, + // so we specifically call addUpdateNodeIfNeeded() + addUpdateNodeIfNeeded(node.getParent()); + } + } } public void updateNode(int id, HippyMap map) { diff --git a/android/sdk/src/main/java/com/tencent/mtt/hippy/views/scroll/HippyHorizontalScrollView.java b/android/sdk/src/main/java/com/tencent/mtt/hippy/views/scroll/HippyHorizontalScrollView.java index 62ac13decc3..c347fa91b4b 100644 --- a/android/sdk/src/main/java/com/tencent/mtt/hippy/views/scroll/HippyHorizontalScrollView.java +++ b/android/sdk/src/main/java/com/tencent/mtt/hippy/views/scroll/HippyHorizontalScrollView.java @@ -69,7 +69,7 @@ public class HippyHorizontalScrollView extends HorizontalScrollView implements H protected int mScrollEventThrottle = 10; private long mLastScrollEventTimeStamp = -1; private boolean mHasUnsentScrollEvent; - + private int mScrollRange = 0; protected int mScrollMinOffset = 0; private int startScrollX = 0; private int mLastX = 0; @@ -484,7 +484,15 @@ public void setInitialContentOffset(int offset) { @Override public void scrollToInitContentOffset() { + int scrollRange = mScrollRange; + View firstChild = getChildAt(0); + if (firstChild != null) { + mScrollRange = firstChild.getWidth(); + } if (hasCompleteFirstBatch) { + if (mScrollRange < scrollRange) { + scrollTo(getScrollX(), getScrollY()); + } return; } diff --git a/android/sdk/src/main/java/com/tencent/mtt/hippy/views/scroll/HippyScrollViewController.java b/android/sdk/src/main/java/com/tencent/mtt/hippy/views/scroll/HippyScrollViewController.java index 109b19b9f00..51a0076c050 100644 --- a/android/sdk/src/main/java/com/tencent/mtt/hippy/views/scroll/HippyScrollViewController.java +++ b/android/sdk/src/main/java/com/tencent/mtt/hippy/views/scroll/HippyScrollViewController.java @@ -1,15 +1,36 @@ +/* Tencent is pleased to support the open source community by making Hippy available. + * Copyright (C) 2018 THL A29 Limited, a Tencent company. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package com.tencent.mtt.hippy.views.scroll; import android.content.Context; import android.text.TextUtils; import android.view.View; import android.view.ViewGroup; +import com.tencent.mtt.hippy.HippyRootView; import com.tencent.mtt.hippy.annotation.HippyController; import com.tencent.mtt.hippy.annotation.HippyControllerProps; import com.tencent.mtt.hippy.common.HippyArray; import com.tencent.mtt.hippy.common.HippyMap; import com.tencent.mtt.hippy.dom.node.NodeProps; +import com.tencent.mtt.hippy.uimanager.ControllerManager; import com.tencent.mtt.hippy.uimanager.HippyGroupController; +import com.tencent.mtt.hippy.uimanager.ListItemRenderNode; +import com.tencent.mtt.hippy.uimanager.RenderNode; +import com.tencent.mtt.hippy.uimanager.ScrollViewRenderNode; import com.tencent.mtt.hippy.utils.PixelUtil; import com.tencent.mtt.hippy.views.list.HippyListView; import com.tencent.mtt.hippy.views.view.HippyViewGroup; @@ -26,6 +47,11 @@ public class HippyScrollViewController ex public static final String CLASS_NAME = "ScrollView"; + @Override + public RenderNode createRenderNode(int id, HippyMap props, String className, + HippyRootView hippyRootView, ControllerManager controllerManager, boolean lazy) { + return new ScrollViewRenderNode(id, props, className, hippyRootView, controllerManager, lazy); + } @Override protected View createViewImpl(Context context, HippyMap iniProps) { diff --git a/android/sdk/src/main/java/com/tencent/mtt/hippy/views/scroll/HippyVerticalScrollView.java b/android/sdk/src/main/java/com/tencent/mtt/hippy/views/scroll/HippyVerticalScrollView.java index 91cd4518797..183af17620e 100644 --- a/android/sdk/src/main/java/com/tencent/mtt/hippy/views/scroll/HippyVerticalScrollView.java +++ b/android/sdk/src/main/java/com/tencent/mtt/hippy/views/scroll/HippyVerticalScrollView.java @@ -67,6 +67,7 @@ public class HippyVerticalScrollView extends NestedScrollView implements HippyVi private boolean mHasUnsentScrollEvent; protected int mScrollMinOffset = 0; + private int mScrollRange = 0; private int startScrollY = 0; private int mLastY = 0; private int initialContentOffset = 0; @@ -352,7 +353,15 @@ public void setInitialContentOffset(int offset) { @Override public void scrollToInitContentOffset() { + int scrollRange = mScrollRange; + View firstChild = getChildAt(0); + if (firstChild != null) { + mScrollRange = firstChild.getHeight(); + } if (hasCompleteFirstBatch) { + if (mScrollRange < scrollRange) { + scrollTo(getScrollX(), getScrollY()); + } return; }