You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@weex.apache.org by gu...@apache.org on 2017/10/18 04:17:18 UTC
[40/50] [abbrv] incubator-weex git commit: sticky offset supported,
keep position lost when insert data fix
sticky offset supported, keep position lost when insert data fix
Project: http://git-wip-us.apache.org/repos/asf/incubator-weex/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-weex/commit/37d62f99
Tree: http://git-wip-us.apache.org/repos/asf/incubator-weex/tree/37d62f99
Diff: http://git-wip-us.apache.org/repos/asf/incubator-weex/diff/37d62f99
Branch: refs/heads/master
Commit: 37d62f99882c1f6eec491ab6e2527923bf2c0b78
Parents: 0ed86c7
Author: jianbai.gbj <ji...@alibaba-inc.com>
Authored: Mon Oct 16 13:59:17 2017 +0800
Committer: gurisxie <27...@qq.com>
Committed: Tue Oct 17 15:37:02 2017 +0800
----------------------------------------------------------------------
.../java/com/taobao/weex/common/Constants.java | 3 +
.../ui/component/list/BasicListComponent.java | 114 ++++++++++++++-----
.../ui/component/list/StickyHeaderHelper.java | 43 ++++++-
.../taobao/weex/ui/component/list/WXCell.java | 92 +++++++--------
.../list/template/WXRecyclerTemplateList.java | 2 +-
5 files changed, 178 insertions(+), 76 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/37d62f99/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 e74e083..730ce84 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
@@ -182,6 +182,9 @@ public class Constants {
String ARIA_LABEL = "ariaLabel";
String ARIA_HIDDEN = "ariaHidden";
+ String STICKY_OFFSET = "stickyOffset";
+ String HAS_FIXED_SIZE = "hasFixedSize";
+ String KEEP_POSITION_LAYOUT_DELAY = "keepPositionLayoutDelay";
interface Recycler{
String LIST_DATA = "listData";
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/37d62f99/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 640a17e..5649832 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
@@ -150,6 +150,15 @@ public abstract class BasicListComponent<T extends ViewGroup & ListComponentView
private WXStickyHelper stickyHelper;
+
+ /**
+ * keep positon
+ * */
+ private WXComponent keepPositionCell = null;
+ private Runnable keepPositionCellRunnable = null;
+ private long keepPositionLayoutDelay = 150;
+
+
public BasicListComponent(WXSDKInstance instance, WXDomObject node, WXVContainer parent) {
super(instance, node, parent);
stickyHelper = new WXStickyHelper(this);
@@ -236,6 +245,9 @@ public abstract class BasicListComponent<T extends ViewGroup & ListComponentView
if (transforms != null) {
bounceRecyclerView.getInnerView().addItemDecoration(RecyclerTransform.parseTransforms(getOrientation(), transforms));
}
+ if(getDomObject().getAttrs().get(Constants.Name.KEEP_POSITION_LAYOUT_DELAY) != null){
+ keepPositionLayoutDelay = WXUtils.getNumberInt(getDomObject().getAttrs().get(Constants.Name.KEEP_POSITION_LAYOUT_DELAY), (int)keepPositionLayoutDelay);
+ }
mItemAnimator=bounceRecyclerView.getInnerView().getItemAnimator();
@@ -245,6 +257,10 @@ public abstract class BasicListComponent<T extends ViewGroup & ListComponentView
bounceRecyclerView.setOverScrollMode(View.OVER_SCROLL_NEVER);
bounceRecyclerView.getInnerView().clearOnScrollListeners();
bounceRecyclerView.getInnerView().addOnScrollListener(mViewOnScrollListener);
+ if(getDomObject().getAttrs().get(Constants.Name.HAS_FIXED_SIZE) != null){
+ boolean hasFixedSize = WXUtils.getBoolean(getDomObject().getAttrs().get(Constants.Name.HAS_FIXED_SIZE), false);
+ bounceRecyclerView.getInnerView().setHasFixedSize(hasFixedSize);
+ }
bounceRecyclerView.getInnerView().addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
@@ -485,53 +501,54 @@ public abstract class BasicListComponent<T extends ViewGroup & ListComponentView
if (stickyComponent != null && stickyComponent.getDomObject() != null
&& stickyComponent instanceof WXCell) {
- WXCell cell = (WXCell) stickyComponent;
- if (cell.getHostView() == null) {
- return;
- }
+ WXCell cell = (WXCell) stickyComponent;
+ if (cell.getHostView() == null) {
+ return;
+ }
+
+ int[] location = new int[2];
+ stickyComponent.getHostView().getLocationOnScreen(location);
+ int[] parentLocation = new int[2];
+ stickyComponent.getParentScroller().getView().getLocationOnScreen(parentLocation);
+ int top = location[1] - parentLocation[1];
+
RecyclerView.LayoutManager layoutManager;
boolean beforeFirstVisibleItem = false;
boolean removeOldSticky = false;
layoutManager = getHostView().getInnerView().getLayoutManager();
if (layoutManager instanceof LinearLayoutManager || layoutManager instanceof GridLayoutManager) {
- int fVisible = ((LinearLayoutManager) layoutManager).findFirstVisibleItemPosition();
+ int firstVisiblePosition = ((LinearLayoutManager) layoutManager).findFirstVisibleItemPosition();
+ int lastVisiblePosition = ((LinearLayoutManager) layoutManager).findLastVisibleItemPosition();
int pos = mChildren.indexOf(cell);
cell.setScrollPositon(pos);
-
- if (pos <= fVisible) {
+ if (pos <= firstVisiblePosition
+ || (cell.getStickyOffset() > 0 && firstVisiblePosition < pos && pos <= lastVisiblePosition &&
+ top <= cell.getStickyOffset())) {
beforeFirstVisibleItem = true;
if(pos > currentStickyPos) {
currentStickyPos = pos;
}
- }
-
- if(pos > fVisible){
+ }else{
removeOldSticky = true;
}
} else if(layoutManager instanceof StaggeredGridLayoutManager){
int [] firstItems= new int[3];
- int fVisible = ((StaggeredGridLayoutManager) layoutManager).findFirstVisibleItemPositions(firstItems)[0];
+ int firstVisiblePosition = ((StaggeredGridLayoutManager) layoutManager).findFirstVisibleItemPositions(firstItems)[0];
+ int lastVisiblePosition = ((StaggeredGridLayoutManager) layoutManager).findLastVisibleItemPositions(firstItems)[0];
int pos = mChildren.indexOf(cell);
- if (pos <= fVisible) {
+ if (pos <= firstVisiblePosition || (cell.getStickyOffset() > 0 && firstVisiblePosition < pos && pos <= lastVisiblePosition &&
+ top <= cell.getStickyOffset())) {
beforeFirstVisibleItem = true;
- }
-
- if(pos > fVisible){
+ }else{
removeOldSticky = true;
}
}
- int[] location = new int[2];
- stickyComponent.getHostView().getLocationOnScreen(location);
- int[] parentLocation = new int[2];
- stickyComponent.getParentScroller().getView().getLocationOnScreen(parentLocation);
-
- int top = location[1] - parentLocation[1];
- boolean showSticky = beforeFirstVisibleItem && cell.getLocationFromStart() >= 0 && top <= 0 && dy >= 0;
- boolean removeSticky = cell.getLocationFromStart() <= 0 && top > 0 && dy <= 0;
+ boolean showSticky = beforeFirstVisibleItem && cell.getLocationFromStart() >= 0 && top <= cell.getStickyOffset() && dy >= 0;
+ boolean removeSticky = cell.getLocationFromStart() <= cell.getStickyOffset() && top > cell.getStickyOffset() && dy <= 0;
if (showSticky) {
bounceRecyclerView.notifyStickyShow(cell);
} else if (removeSticky || removeOldSticky) {
@@ -584,7 +601,6 @@ public abstract class BasicListComponent<T extends ViewGroup & ListComponentView
@Override
public void addChild(WXComponent child, int index) {
super.addChild(child, index);
-
if (child == null || index < -1) {
return;
}
@@ -593,7 +609,7 @@ public abstract class BasicListComponent<T extends ViewGroup & ListComponentView
bindViewType(child);
int adapterPosition = index == -1 ? mChildren.size() - 1 : index;
- T view = getHostView();
+ final T view = getHostView();
if (view != null) {
boolean isAddAnimation = false;
ImmutableDomObject domObject = child.getDomObject();
@@ -616,9 +632,52 @@ public abstract class BasicListComponent<T extends ViewGroup & ListComponentView
}
}
if (isKeepScrollPosition) {
- int last=((LinearLayoutManager)view.getInnerView().getLayoutManager()).findLastVisibleItemPosition();
- view.getInnerView().getLayoutManager().scrollToPosition(last);
+ if(view.getInnerView().getLayoutManager() instanceof LinearLayoutManager){
+ if(!view.getInnerView().isLayoutFrozen()){ //frozen, prevent layout when scroll
+ view.getInnerView().setLayoutFrozen(true);
+ }
+ if(keepPositionCell == null){
+ int last=((LinearLayoutManager)view.getInnerView().getLayoutManager()).findLastCompletelyVisibleItemPosition();
+ ListBaseViewHolder holder = (ListBaseViewHolder) view.getInnerView().findViewHolderForAdapterPosition(last);
+ if(holder != null){
+ keepPositionCell = holder.getComponent();
+ }
+ if(keepPositionCell != null) {
+ if(keepPositionCellRunnable != null){
+ view.removeCallbacks(keepPositionCellRunnable);
+ }
+ keepPositionCellRunnable = new Runnable() {
+ @Override
+ public void run() {
+ if(keepPositionCell != null){
+ int keepPosition = indexOf(keepPositionCell);
+ int offset = 0;
+ if(keepPositionCell.getHostView() != null){
+ offset = keepPositionCell.getHostView().getTop();
+ }
+ if(offset > 0) {
+ ((LinearLayoutManager) view.getInnerView().getLayoutManager()).scrollToPositionWithOffset(keepPosition, offset);
+ }else{
+ view.getInnerView().getLayoutManager().scrollToPosition(keepPosition);
+
+ }
+ view.getInnerView().setLayoutFrozen(false);
+ keepPositionCell = null;
+ keepPositionCellRunnable = null;
+ }
+ }
+ };
+ }
+ }
+ if(keepPositionCellRunnable == null){
+ view.getInnerView().scrollToPosition(((LinearLayoutManager)view.getInnerView().getLayoutManager()).findLastVisibleItemPosition());
+ }
+ }
view.getRecyclerViewBaseAdapter().notifyItemInserted(adapterPosition);
+ if(keepPositionCellRunnable != null){
+ view.removeCallbacks(keepPositionCellRunnable);
+ view.postDelayed(keepPositionCellRunnable, keepPositionLayoutDelay);
+ }
} else {
view.getRecyclerViewBaseAdapter().notifyItemChanged(adapterPosition);
}
@@ -628,6 +687,7 @@ public abstract class BasicListComponent<T extends ViewGroup & ListComponentView
+
private void relocateAppearanceHelper() {
Iterator<Map.Entry<String, AppearanceHelper>> iterator = mAppearComponents.entrySet().iterator();
while (iterator.hasNext()) {
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/37d62f99/android/sdk/src/main/java/com/taobao/weex/ui/component/list/StickyHeaderHelper.java
----------------------------------------------------------------------
diff --git a/android/sdk/src/main/java/com/taobao/weex/ui/component/list/StickyHeaderHelper.java b/android/sdk/src/main/java/com/taobao/weex/ui/component/list/StickyHeaderHelper.java
index 1534013..cedd86c 100644
--- a/android/sdk/src/main/java/com/taobao/weex/ui/component/list/StickyHeaderHelper.java
+++ b/android/sdk/src/main/java/com/taobao/weex/ui/component/list/StickyHeaderHelper.java
@@ -21,6 +21,7 @@ package com.taobao.weex.ui.component.list;
import android.view.View;
import android.view.ViewGroup;
+import com.taobao.weex.WXEnvironment;
import com.taobao.weex.common.WXThread;
import com.taobao.weex.utils.WXLogUtils;
@@ -87,12 +88,20 @@ public class StickyHeaderHelper {
if ((existedParent = (ViewGroup) headerView.getParent()) != null) {
existedParent.removeView(headerView);
}
+ headerView.setTag(headComponent.getRef());
mParent.addView(headerView);
+ headerView.setTag(this);
+ if(headComponent.getStickyOffset() > 0) {
+ ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) headerView.getLayoutParams();
+ if(headComponent.getStickyOffset() != params.topMargin) {
+ params.topMargin = headComponent.getStickyOffset();
+ }
+ }
//recover translation, sometimes it will be changed on fling
headerView.setTranslationX(translationX);
headerView.setTranslationY(translationY);
-
}
+ changeFrontStickyVisible();
if (headComponent.getDomObject().getEvents().contains("sticky")) {
headComponent.fireEvent("sticky");
}
@@ -108,7 +117,8 @@ public class StickyHeaderHelper {
if(component == null || headerView == null){
- WXLogUtils.e(" sticky header to remove not found."+compToRemove.getRef());
+ if(WXEnvironment.isApkDebugable()) {
+ }
return;
}
if(mCurrentStickyRef != null && mCurrentStickyRef.equals(compToRemove.getRef())){
@@ -118,7 +128,12 @@ public class StickyHeaderHelper {
@Override
public void run() {
mParent.removeView(headerView);
+ if(headerView.getVisibility() != View.VISIBLE){
+ headerView.setVisibility(View.VISIBLE);
+ }
component.recoverySticky();
+ changeFrontStickyVisible();
+
}
}));
if (component.getDomObject().getEvents().contains("unsticky")) {
@@ -141,6 +156,7 @@ public class StickyHeaderHelper {
View view = mHeaderViews.get(cell.getRef());
if(view != null){
view.bringToFront();
+ changeFrontStickyVisible();
}
}
}
@@ -148,4 +164,27 @@ public class StickyHeaderHelper {
notifyStickyRemove(cell);
}
}
+
+
+ private void changeFrontStickyVisible(){
+ if(mHeaderViews.size() <= 0){
+ return;
+ }
+ boolean fontVisible = false;
+ for(int i=mParent.getChildCount()-1; i>=0; i--){
+ View view = mParent.getChildAt(i);
+ if(fontVisible && view.getTag() instanceof StickyHeaderHelper){
+ if(view.getVisibility() != View.GONE){
+ view.setVisibility(View.GONE);
+ }
+ }else{
+ if(view.getTag() instanceof StickyHeaderHelper){
+ fontVisible = true;
+ if(view != null && view.getVisibility() != View.VISIBLE){
+ view.setVisibility(View.VISIBLE);
+ }
+ }
+ }
+ }
+ }
}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/37d62f99/android/sdk/src/main/java/com/taobao/weex/ui/component/list/WXCell.java
----------------------------------------------------------------------
diff --git a/android/sdk/src/main/java/com/taobao/weex/ui/component/list/WXCell.java b/android/sdk/src/main/java/com/taobao/weex/ui/component/list/WXCell.java
index c329e99..ebf81b4 100644
--- a/android/sdk/src/main/java/com/taobao/weex/ui/component/list/WXCell.java
+++ b/android/sdk/src/main/java/com/taobao/weex/ui/component/list/WXCell.java
@@ -37,6 +37,9 @@ import com.taobao.weex.ui.flat.WidgetContainer;
import com.taobao.weex.ui.view.WXFrameLayout;
import com.taobao.weex.utils.WXLogUtils;
import com.taobao.weex.utils.WXUtils;
+import com.taobao.weex.utils.WXViewUtils;
+
+import static com.taobao.weex.common.Constants.Name.STICKY_OFFSET;
/**
* Root component for components in {@link WXListComponent}
@@ -55,17 +58,14 @@ public class WXCell extends WidgetContainer<WXFrameLayout> {
private int mScrollPositon = -1;
private boolean mFlatUIEnabled = false;
+
private Object renderData;
private boolean isSourceUsed = false;
private boolean hasLayout = false;
- private Object renderData;
- private boolean isSourceUsed = false;
-
- private boolean hasLayout = false;
@Deprecated
@@ -149,28 +149,41 @@ public class WXCell extends WidgetContainer<WXFrameLayout> {
}
public void removeSticky() {
- mHeadView = getHostView().getChildAt(0);
- int[] location = new int[2];
- int[] parentLocation = new int[2];
- getHostView().getLocationOnScreen(location);
- getParentScroller().getView().getLocationOnScreen(parentLocation);
- int headerViewOffsetX = location[0] - parentLocation[0];
- int headerViewOffsetY = getParent().getHostView().getTop();
- getHostView().removeView(mHeadView);
- mRealView = (ViewGroup) mHeadView;
- mTempStickyView = new FrameLayout(getContext());
- FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams((int) getDomObject().getLayoutWidth(),
- (int) getDomObject().getLayoutHeight());
- getHostView().addView(mTempStickyView, lp);
- mHeadView.setTranslationX(headerViewOffsetX);
- mHeadView.setTranslationY(headerViewOffsetY);
+ if(getHostView().getChildCount() > 0) {
+ mHeadView = getHostView().getChildAt(0);
+ int[] location = new int[2];
+ int[] parentLocation = new int[2];
+ getHostView().getLocationOnScreen(location);
+ getParentScroller().getView().getLocationOnScreen(parentLocation);
+ int headerViewOffsetX = location[0] - parentLocation[0];
+ int headerViewOffsetY = getParent().getHostView().getTop();
+ getHostView().removeView(mHeadView);
+ mRealView = (ViewGroup) mHeadView;
+ mTempStickyView = new FrameLayout(getContext());
+ FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams((int) getDomObject().getLayoutWidth(),
+ (int) getDomObject().getLayoutHeight());
+ getHostView().addView(mTempStickyView, lp);
+ mHeadView.setTranslationX(headerViewOffsetX);
+ mHeadView.setTranslationY(headerViewOffsetY);
+ }
}
public void recoverySticky() {
- getHostView().removeView(mTempStickyView);
- getHostView().addView(mHeadView);
- mHeadView.setTranslationX(0);
- mHeadView.setTranslationY(0);
+ if(mHeadView != null){
+ if(mHeadView.getLayoutParams() != null){
+ ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) mHeadView.getLayoutParams();
+ if(params.topMargin > 0){
+ params.topMargin = 0;
+ }
+ }
+ if(mHeadView.getVisibility() != View.VISIBLE){
+ mHeadView.setVisibility(View.VISIBLE);
+ }
+ getHostView().removeView(mTempStickyView);
+ getHostView().addView(mHeadView);
+ mHeadView.setTranslationX(0);
+ mHeadView.setTranslationY(0);
+ }
}
@Override
@@ -192,28 +205,16 @@ public class WXCell extends WidgetContainer<WXFrameLayout> {
return getInstance().getFlatUIContext().isFlatUIEnabled(this) && WXCell.class.equals(getClass()) && !isSticky();
}
- public Object getRenderData() {
- return renderData;
- }
-
- public void setRenderData(Object renderData) {
- this.renderData = renderData;
- }
-
- public boolean isSourceUsed() {
- return isSourceUsed;
- }
-
- public void setSourceUsed(boolean sourceUsed) {
- isSourceUsed = sourceUsed;
- }
-
- public boolean isHasLayout() {
- return hasLayout;
- }
-
- public void setHasLayout(boolean hasLayout) {
- this.hasLayout = hasLayout;
+ public int getStickyOffset(){
+ if(getDomObject() == null){
+ return 0;
+ }
+ WXDomObject domObject = (WXDomObject) getDomObject();
+ if(domObject.getAttrs().get(STICKY_OFFSET) == null){
+ return 0;
+ }
+ float offset = WXUtils.getFloat(domObject.getAttrs().get(STICKY_OFFSET));
+ return (int)(WXViewUtils.getRealPxByWidth(offset,domObject.getViewPortWidth()));
}
public Object getRenderData() {
@@ -239,5 +240,4 @@ public class WXCell extends WidgetContainer<WXFrameLayout> {
public void setHasLayout(boolean hasLayout) {
this.hasLayout = hasLayout;
}
-
}
http://git-wip-us.apache.org/repos/asf/incubator-weex/blob/37d62f99/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 7e0746b..1918517 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
@@ -1306,7 +1306,7 @@ public class WXRecyclerTemplateList extends WXVContainer<BounceRecyclerView> imp
continue;
}
TemplateViewHolder itemHolder = (TemplateViewHolder) recyclerView.findViewHolderForAdapterPosition(position);
- if(itemHolder == null){
+ if(itemHolder == null || itemHolder.getComponent() == null){
break;
}
List<WXComponent> childListeners = findChildListByRef(itemHolder.getComponent(), helper.getAwareChild().getRef());