Repository: incubator-weex Updated Branches: refs/heads/master 00a4cd654 -> 4747acc95
[WEEX-109][android] support scroll start scroll end event on scroller list template list Project: http://git-wip-us.apache.org/repos/asf/incubator-weex/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-weex/commit/40de9402 Tree: http://git-wip-us.apache.org/repos/asf/incubator-weex/tree/40de9402 Diff: http://git-wip-us.apache.org/repos/asf/incubator-weex/diff/40de9402 Branch: refs/heads/master Commit: 40de94021c0d5e139f8c8696d19ce493f252b772 Parents: 8a19b9b Author: jianbai.gbj <jianbai....@alibaba-inc.com> Authored: Mon Nov 13 18:09:08 2017 +0800 Committer: jianbai.gbj <jianbai....@alibaba-inc.com> Committed: Mon Nov 13 18:09:08 2017 +0800 ---------------------------------------------------------------------- .../java/com/taobao/weex/common/Constants.java | 2 + .../taobao/weex/ui/component/WXScroller.java | 43 ++++++- .../component/helper/ScrollStartEndHelper.java | 116 +++++++++++++++++++ .../ui/component/list/BasicListComponent.java | 35 +++++- .../list/template/WXRecyclerTemplateList.java | 39 +++++-- 5 files changed, 219 insertions(+), 16 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/40de9402/android/sdk/src/main/java/com/taobao/weex/common/Constants.java ---------------------------------------------------------------------- diff --git a/android/sdk/src/main/java/com/taobao/weex/common/Constants.java b/android/sdk/src/main/java/com/taobao/weex/common/Constants.java index 32c91ba..5145f9e 100644 --- a/android/sdk/src/main/java/com/taobao/weex/common/Constants.java +++ b/android/sdk/src/main/java/com/taobao/weex/common/Constants.java @@ -278,6 +278,8 @@ public class Constants { String ONPULLING_DOWN = "pullingdown"; String ONPULLING_UP = "pullingup"; String SCROLL = "scroll"; + String SCROLL_START = "scrollstart"; + String SCROLL_END = "scrollend"; String CLICKBACKITEM = "clickbackitem"; String RESUME_EVENT = "WXApplicationDidBecomeActiveEvent"; String PAUSE_EVENT = "WXApplicationWillResignActiveEvent"; http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/40de9402/android/sdk/src/main/java/com/taobao/weex/ui/component/WXScroller.java ---------------------------------------------------------------------- diff --git a/android/sdk/src/main/java/com/taobao/weex/ui/component/WXScroller.java b/android/sdk/src/main/java/com/taobao/weex/ui/component/WXScroller.java index 9e56259..9885d62 100644 --- a/android/sdk/src/main/java/com/taobao/weex/ui/component/WXScroller.java +++ b/android/sdk/src/main/java/com/taobao/weex/ui/component/WXScroller.java @@ -42,6 +42,7 @@ import com.taobao.weex.common.OnWXScrollListener; import com.taobao.weex.common.WXThread; import com.taobao.weex.dom.WXDomObject; import com.taobao.weex.ui.ComponentCreator; +import com.taobao.weex.ui.component.helper.ScrollStartEndHelper; import com.taobao.weex.ui.component.helper.WXStickyHelper; import com.taobao.weex.ui.view.IWXScroller; import com.taobao.weex.ui.view.WXBaseRefreshLayout; @@ -78,6 +79,14 @@ public class WXScroller extends WXVContainer<ViewGroup> implements WXScrollViewL private boolean mForceLoadmoreNextTime = false; private int mOffsetAccuracy = 10; private Point mLastReport = new Point(-1, -1); + private boolean mHasAddScrollEvent = false; + + /** + * scroll start and scroll end event + * */ + private ScrollStartEndHelper mScrollStartEndHelper; + + public static class Creator implements ComponentCreator { public WXComponent createInstance(WXSDKInstance instance, WXDomObject node, WXVContainer parent) throws IllegalAccessException, InvocationTargetException, InstantiationException { @@ -102,6 +111,7 @@ public class WXScroller extends WXVContainer<ViewGroup> implements WXScrollViewL private boolean isScrollable = true; + @Deprecated public WXScroller(WXSDKInstance instance, WXDomObject dom, WXVContainer parent, String instanceId, boolean isLazy) { this(instance,dom,parent); @@ -148,11 +158,17 @@ public class WXScroller extends WXVContainer<ViewGroup> implements WXScrollViewL @Override public void addEvent(String type) { super.addEvent(type); - if (Constants.Event.SCROLL.equals(type) && getInnerView() != null) { + if (ScrollStartEndHelper.isScrollEvent(type) + && getInnerView() != null && !mHasAddScrollEvent) { + mHasAddScrollEvent = true; if (getInnerView() instanceof WXScrollView) { ((WXScrollView) getInnerView()).addScrollViewListener(new WXScrollViewListener() { @Override public void onScrollChanged(WXScrollView scrollView, int x, int y, int oldx, int oldy) { + getScrollStartEndHelper().onScrolled(x, y); + if(!getDomObject().getEvents().contains(Constants.Event.SCROLL)){ + return; + } if (shouldReport(x, y)) { fireScrollEvent(scrollView.getContentFrame(), x, y, oldx, oldy); } @@ -177,6 +193,10 @@ public class WXScroller extends WXVContainer<ViewGroup> implements WXScrollViewL ((WXHorizontalScrollView) getInnerView()).addScrollViewListener(new WXHorizontalScrollView.ScrollViewListener() { @Override public void onScrollChanged(WXHorizontalScrollView scrollView, int x, int y, int oldx, int oldy) { + getScrollStartEndHelper().onScrolled(x, y); + if(!getDomObject().getEvents().contains(Constants.Event.SCROLL)){ + return; + } if (shouldReport(x, y)) { fireScrollEvent(scrollView.getContentFrame(), x, y, oldx, oldy); } @@ -187,6 +207,16 @@ public class WXScroller extends WXVContainer<ViewGroup> implements WXScrollViewL } private void fireScrollEvent(Rect contentFrame, int x, int y, int oldx, int oldy) { + fireEvent(Constants.Event.SCROLL, getScrollEvent(x, y)); + } + + public Map<String, Object> getScrollEvent(int x, int y){ + Rect contentFrame = new Rect(); + if (getInnerView() instanceof WXScrollView) { + contentFrame = ((WXScrollView) getInnerView()).getContentFrame(); + }else if (getInnerView() instanceof WXHorizontalScrollView) { + contentFrame = ((WXHorizontalScrollView) getInnerView()).getContentFrame(); + } Map<String, Object> event = new HashMap<>(2); Map<String, Object> contentSize = new HashMap<>(2); Map<String, Object> contentOffset = new HashMap<>(2); @@ -201,8 +231,7 @@ public class WXScroller extends WXVContainer<ViewGroup> implements WXScrollViewL event.put(Constants.Name.CONTENT_SIZE, contentSize); event.put(Constants.Name.CONTENT_OFFSET, contentOffset); - - fireEvent(Constants.Event.SCROLL, event); + return event; } private boolean shouldReport(int x, int y) { @@ -719,4 +748,12 @@ public class WXScroller extends WXVContainer<ViewGroup> implements WXScrollViewL public void resetLoadmore() { mForceLoadmoreNextTime = true; } + + + public ScrollStartEndHelper getScrollStartEndHelper() { + if(mScrollStartEndHelper == null){ + mScrollStartEndHelper = new ScrollStartEndHelper(this); + } + return mScrollStartEndHelper; + } } http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/40de9402/android/sdk/src/main/java/com/taobao/weex/ui/component/helper/ScrollStartEndHelper.java ---------------------------------------------------------------------- diff --git a/android/sdk/src/main/java/com/taobao/weex/ui/component/helper/ScrollStartEndHelper.java b/android/sdk/src/main/java/com/taobao/weex/ui/component/helper/ScrollStartEndHelper.java new file mode 100644 index 0000000..15163e1 --- /dev/null +++ b/android/sdk/src/main/java/com/taobao/weex/ui/component/helper/ScrollStartEndHelper.java @@ -0,0 +1,116 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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.taobao.weex.ui.component.helper; + +import android.os.Handler; +import android.os.Looper; +import com.taobao.weex.common.Constants; +import com.taobao.weex.ui.component.WXComponent; +import com.taobao.weex.ui.component.WXScroller; +import com.taobao.weex.ui.component.list.BasicListComponent; +import com.taobao.weex.ui.component.list.ListComponentView; +import com.taobao.weex.ui.component.list.template.WXRecyclerTemplateList; +import com.taobao.weex.utils.WXUtils; + +import java.util.Map; + + +/** + * Created by furture on 2017/11/13. + */ + +public class ScrollStartEndHelper implements Runnable{ + + private Handler handler; + private WXComponent component; + private boolean hasStart; + private long minInterval; + + private int x; + private int y; + + public ScrollStartEndHelper(WXComponent component) { + this.component = component; + this.handler = new Handler(Looper.getMainLooper()); + this.minInterval = WXUtils.getNumberInt(component.getDomObject().getAttrs().get("minscrolldelayinterval"), 32); + } + + /** + * @param x scroll offset or dx, which is not accurate + * @param y scroll offset or dy, which is not accurate + * */ + public void onScrolled(int x, int y){ + if((component.getDomObject().getEvents().contains(Constants.Event.SCROLL_START) + || component.getDomObject().getEvents().contains(Constants.Event.SCROLL_END))){ + this.x = x; + this.y = y; + if(!hasStart){ + if(component.getDomObject().getEvents().contains(Constants.Event.SCROLL_START)){ + component.fireEvent(Constants.Event.SCROLL_START, getScrollEvent(x, y)); + } + hasStart = true; + } + handler.removeCallbacks(this); + handler.postDelayed(this, minInterval); + } + } + + + @Override + public void run() { + if(component.isDestoryed()){ + return; + } + if(component.getDomObject().getEvents().contains(Constants.Event.SCROLL_END)){ + component.fireEvent(Constants.Event.SCROLL_END, getScrollEvent(this.x, this.y)); + } + hasStart = false; + } + + private Map<String, Object> getScrollEvent(int offsetX, int offsetY){ + if(component instanceof BasicListComponent){ + BasicListComponent basicListComponent = (BasicListComponent) component; + if(basicListComponent.getHostView() instanceof ListComponentView){ + ListComponentView componentView = (ListComponentView) basicListComponent.getHostView(); + if(componentView != null){ + return basicListComponent.getScrollEvent(componentView.getInnerView(), offsetX, offsetY); + } + } + }else if(component instanceof WXRecyclerTemplateList){ + WXRecyclerTemplateList templateList = (WXRecyclerTemplateList) component; + return templateList.getScrollEvent(templateList.getHostView().getInnerView(), offsetX, offsetY); + }else if(component instanceof WXScroller){ + WXScroller scroller = (WXScroller) component; + return scroller.getScrollEvent(offsetX, offsetY); + } + return null; + } + + + public static boolean isScrollEvent(String type){ + if(Constants.Event.SCROLL.equals(type)){ + return true; + }else if(Constants.Event.SCROLL_START.equals(type)){ + return true; + }else if(Constants.Event.SCROLL_END.equals(type)){ + return true; + } + return false; + } +} http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/40de9402/android/sdk/src/main/java/com/taobao/weex/ui/component/list/BasicListComponent.java ---------------------------------------------------------------------- diff --git a/android/sdk/src/main/java/com/taobao/weex/ui/component/list/BasicListComponent.java b/android/sdk/src/main/java/com/taobao/weex/ui/component/list/BasicListComponent.java index bf51870..e8920d3 100644 --- a/android/sdk/src/main/java/com/taobao/weex/ui/component/list/BasicListComponent.java +++ b/android/sdk/src/main/java/com/taobao/weex/ui/component/list/BasicListComponent.java @@ -58,13 +58,13 @@ import com.taobao.weex.ui.component.WXComponentProp; import com.taobao.weex.ui.component.WXLoading; import com.taobao.weex.ui.component.WXRefresh; import com.taobao.weex.ui.component.WXVContainer; +import com.taobao.weex.ui.component.helper.ScrollStartEndHelper; import com.taobao.weex.ui.component.helper.WXStickyHelper; import com.taobao.weex.ui.view.listview.WXRecyclerView; import com.taobao.weex.ui.view.listview.adapter.IOnLoadMoreListener; import com.taobao.weex.ui.view.listview.adapter.IRecyclerAdapterListener; import com.taobao.weex.ui.view.listview.adapter.ListBaseViewHolder; import com.taobao.weex.ui.view.listview.adapter.RecyclerViewBaseAdapter; -import com.taobao.weex.ui.view.listview.adapter.TransformItemDecoration; import com.taobao.weex.ui.view.listview.adapter.WXRecyclerViewOnScrollListener; import com.taobao.weex.utils.WXLogUtils; import com.taobao.weex.utils.WXResourceUtils; @@ -78,7 +78,6 @@ import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; -import java.util.regex.Matcher; import java.util.regex.Pattern; /** @@ -113,6 +112,7 @@ public abstract class BasicListComponent<T extends ViewGroup & ListComponentView private int mOffsetAccuracy = 10; private Point mLastReport = new Point(-1, -1); + private boolean mHasAddScrollEvent = false; private RecyclerView.ItemAnimator mItemAnimator; @@ -150,6 +150,12 @@ public abstract class BasicListComponent<T extends ViewGroup & ListComponentView private WXStickyHelper stickyHelper; + /** + * scroll start and scroll end event + * */ + private ScrollStartEndHelper mScrollStartEndHelper; + + /** * keep positon @@ -1204,7 +1210,11 @@ public abstract class BasicListComponent<T extends ViewGroup & ListComponentView @Override public void addEvent(String type) { super.addEvent(type); - if (Constants.Event.SCROLL.equals(type) && getHostView() != null && getHostView().getInnerView() != null) { + if (ScrollStartEndHelper.isScrollEvent(type) + && getHostView() != null + && getHostView().getInnerView() != null + && !mHasAddScrollEvent) { + mHasAddScrollEvent = true; WXRecyclerView innerView = getHostView().getInnerView(); innerView.addOnScrollListener(new RecyclerView.OnScrollListener() { private int offsetXCorrection, offsetYCorrection; @@ -1230,7 +1240,10 @@ public abstract class BasicListComponent<T extends ViewGroup & ListComponentView offsetX = offsetX - offsetXCorrection; offsetY = offsetY - offsetYCorrection; } - + getScrollStartEndHelper().onScrolled(offsetX, offsetY); + if(!getDomObject().getEvents().contains(Constants.Event.SCROLL)){ + return; + } if (mFirstEvent) { //skip first event mFirstEvent = false; @@ -1251,6 +1264,10 @@ public abstract class BasicListComponent<T extends ViewGroup & ListComponentView } private void fireScrollEvent(RecyclerView recyclerView, int offsetX, int offsetY) { + fireEvent(Constants.Event.SCROLL, getScrollEvent(recyclerView, offsetX, offsetY)); + } + + public Map<String, Object> getScrollEvent(RecyclerView recyclerView, int offsetX, int offsetY){ if(getOrientation() == Constants.Orientation.VERTICAL){ offsetY = - calcContentOffset(recyclerView); } @@ -1274,8 +1291,7 @@ public abstract class BasicListComponent<T extends ViewGroup & ListComponentView contentOffset.put(Constants.Name.Y, - WXViewUtils.getWebPxByWidth(offsetY, getInstance().getInstanceViewPortWidth())); event.put(Constants.Name.CONTENT_SIZE, contentSize); event.put(Constants.Name.CONTENT_OFFSET, contentOffset); - - fireEvent(Constants.Event.SCROLL, event); + return event; } private boolean shouldReport(int offsetX, int offsetY) { @@ -1356,4 +1372,11 @@ public abstract class BasicListComponent<T extends ViewGroup & ListComponentView //Unhandled LayoutManager type return -1; } + + public ScrollStartEndHelper getScrollStartEndHelper() { + if(mScrollStartEndHelper == null){ + mScrollStartEndHelper = new ScrollStartEndHelper(this); + } + return mScrollStartEndHelper; + } } http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/40de9402/android/sdk/src/main/java/com/taobao/weex/ui/component/list/template/WXRecyclerTemplateList.java ---------------------------------------------------------------------- diff --git a/android/sdk/src/main/java/com/taobao/weex/ui/component/list/template/WXRecyclerTemplateList.java b/android/sdk/src/main/java/com/taobao/weex/ui/component/list/template/WXRecyclerTemplateList.java index 76bcce0..2e2992f 100644 --- a/android/sdk/src/main/java/com/taobao/weex/ui/component/list/template/WXRecyclerTemplateList.java +++ b/android/sdk/src/main/java/com/taobao/weex/ui/component/list/template/WXRecyclerTemplateList.java @@ -44,16 +44,13 @@ import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.taobao.weex.WXEnvironment; import com.taobao.weex.WXSDKInstance; -import com.taobao.weex.WXSDKManager; import com.taobao.weex.annotation.Component; import com.taobao.weex.annotation.JSMethod; -import com.taobao.weex.bridge.WXBridgeManager; import com.taobao.weex.common.Constants; import com.taobao.weex.common.ICheckBindingScroller; import com.taobao.weex.common.OnWXScrollListener; import com.taobao.weex.dom.WXAttr; import com.taobao.weex.dom.WXCellDomObject; -import com.taobao.weex.dom.WXDomHandler; import com.taobao.weex.dom.WXDomObject; import com.taobao.weex.dom.WXEvent; import com.taobao.weex.dom.WXRecyclerDomObject; @@ -70,6 +67,7 @@ import com.taobao.weex.ui.component.WXRefresh; import com.taobao.weex.ui.component.WXVContainer; import com.taobao.weex.ui.component.binding.Layouts; import com.taobao.weex.ui.component.binding.Statements; +import com.taobao.weex.ui.component.helper.ScrollStartEndHelper; import com.taobao.weex.ui.component.list.RecyclerTransform; import com.taobao.weex.ui.component.list.WXCell; import com.taobao.weex.ui.view.listview.WXRecyclerView; @@ -132,6 +130,7 @@ public class WXRecyclerTemplateList extends WXVContainer<BounceRecyclerView> imp private boolean isScrollable = true; private int mOffsetAccuracy = 10; private Point mLastReport = new Point(-1, -1); + private boolean mHasAddScrollEvent = false; private JSONArray listData; private String listDataKey = Constants.Name.Recycler.LIST_DATA; @@ -149,6 +148,13 @@ public class WXRecyclerTemplateList extends WXVContainer<BounceRecyclerView> imp /** + * scroll start and scroll end event + * */ + private ScrollStartEndHelper mScrollStartEndHelper; + + + + /** * sticky helper * */ private TemplateStickyHelper mStickyHelper; @@ -827,7 +833,11 @@ public class WXRecyclerTemplateList extends WXVContainer<BounceRecyclerView> imp @Override public void addEvent(String type) { super.addEvent(type); - if (Constants.Event.SCROLL.equals(type) && getHostView() != null && getHostView().getInnerView() != null) { + if (ScrollStartEndHelper.isScrollEvent(type) + && getHostView() != null + && getHostView().getInnerView() != null + && !mHasAddScrollEvent) { + mHasAddScrollEvent = true; WXRecyclerView innerView = getHostView().getInnerView(); innerView.addOnScrollListener(new RecyclerView.OnScrollListener() { private int offsetXCorrection, offsetYCorrection; @@ -852,7 +862,10 @@ public class WXRecyclerTemplateList extends WXVContainer<BounceRecyclerView> imp offsetX = offsetX - offsetXCorrection; offsetY = offsetY - offsetYCorrection; } - + getScrollStartEndHelper().onScrolled(offsetX, offsetY); + if(!getDomObject().getEvents().contains(Constants.Event.SCROLL)){ + return; + } if (mFirstEvent) { //skip first event mFirstEvent = false; @@ -868,6 +881,10 @@ public class WXRecyclerTemplateList extends WXVContainer<BounceRecyclerView> imp } private void fireScrollEvent(RecyclerView recyclerView, int offsetX, int offsetY) { + fireEvent(Constants.Event.SCROLL, getScrollEvent(recyclerView, offsetX, offsetY)); + } + + public Map<String, Object> getScrollEvent(RecyclerView recyclerView, int offsetX, int offsetY){ offsetY = -calcContentOffset(recyclerView); int contentWidth = recyclerView.getMeasuredWidth() + recyclerView.computeHorizontalScrollRange(); int contentHeight = calcContentSize(); @@ -883,10 +900,11 @@ public class WXRecyclerTemplateList extends WXVContainer<BounceRecyclerView> imp contentOffset.put(Constants.Name.Y, - WXViewUtils.getWebPxByWidth(offsetY, getInstance().getInstanceViewPortWidth())); event.put(Constants.Name.CONTENT_SIZE, contentSize); event.put(Constants.Name.CONTENT_OFFSET, contentOffset); - - fireEvent(Constants.Event.SCROLL, event); + return event; } + + private boolean shouldReport(int offsetX, int offsetY) { if (mLastReport.x == -1 && mLastReport.y == -1) { mLastReport.x = offsetX; @@ -1639,4 +1657,11 @@ public class WXRecyclerTemplateList extends WXVContainer<BounceRecyclerView> imp } } } + + public ScrollStartEndHelper getScrollStartEndHelper() { + if(mScrollStartEndHelper == null){ + mScrollStartEndHelper = new ScrollStartEndHelper(this); + } + return mScrollStartEndHelper; + } }