From 411ca694e43e70a50be0ee9c1aaaa5c237c53069 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E5=8A=B2=E9=B9=8F?= Date: Thu, 3 Aug 2023 19:11:22 +0800 Subject: [PATCH] Android: impl scroll to item with top offset api --- .../java/pub/doric/shader/list/ListNode.java | 32 ++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/doric-android/doric/src/main/java/pub/doric/shader/list/ListNode.java b/doric-android/doric/src/main/java/pub/doric/shader/list/ListNode.java index ba65184d..11b9638c 100644 --- a/doric-android/doric/src/main/java/pub/doric/shader/list/ListNode.java +++ b/doric-android/doric/src/main/java/pub/doric/shader/list/ListNode.java @@ -44,6 +44,7 @@ import org.json.JSONArray; import java.util.HashMap; import java.util.HashSet; import java.util.Map; +import java.util.Objects; import java.util.Set; import java.util.concurrent.Callable; @@ -472,7 +473,12 @@ public class ListNode extends SuperNode implements IDoricScrollabl animated = params.getProperty("animated").asBoolean().value(); } JSNumber pos = params.getProperty("index").asNumber(); - moveToPosition(pos.toInt(), animated); + JSValue topOffsetValue = params.getProperty("topOffset"); + if (topOffsetValue.isNumber()) { + moveToPositionWithTopOffset(pos.toInt(), animated, topOffsetValue.asNumber().toFloat()); + } else { + moveToPosition(pos.toInt(), animated); + } } @DoricMethod @@ -537,6 +543,11 @@ public class ListNode extends SuperNode implements IDoricScrollabl } } + private void moveToPositionWithTopOffset(int pos, boolean animated, float topOffset) { + RecyclerView.SmoothScroller smoothScroller = new OffsetLinearSmoothScroller(getContext(), DoricUtils.dp2px(-topOffset)); + smoothScroller.setTargetPosition(pos); + Objects.requireNonNull(mView.getLayoutManager()).startSmoothScroll(smoothScroller); + } private void defaultScrollTo(int pos, boolean b) { if (b) { @@ -714,4 +725,23 @@ public class ListNode extends SuperNode implements IDoricScrollabl return calculateDtToFit(top, bottom, start, end, snapPreference); } } + + private static class OffsetLinearSmoothScroller extends LinearSmoothScroller { + private final int offset; + + public OffsetLinearSmoothScroller(Context context, int offset) { + super(context); + this.offset = offset; + } + + @Override + public int calculateDtToFit(int viewStart, int viewEnd, int boxStart, int boxEnd, int snapPreference) { + return boxStart - viewStart + offset; + } + + @Override + protected int getVerticalSnapPreference() { + return LinearSmoothScroller.SNAP_TO_START; + } + } }