Skip to content
This repository has been archived by the owner on Jun 3, 2021. It is now read-only.

Commit

Permalink
[iOS][Android] fix scrollToElement performance incorrect offset (#2198)
Browse files Browse the repository at this point in the history
* [iOS][Android] fix scrollToElement performance incorrect  offset

Nuke DEMO: https://jsplayground.taobao.org/raxplayground/5bf4b469-8eb1-4f5d-91df-912cd085ab7b
Direction chang DEMO:http://dotwe.org/vue/09cb6e35412f96c25c423fd50a929597
  • Loading branch information
win80540 authored and YorkShen committed Mar 13, 2019
1 parent 4ec37d4 commit c6f65a2
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 43 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ public class WXScroller extends WXVContainer<ViewGroup> implements WXScrollViewL
private int mOffsetAccuracy = 10;
private Point mLastReport = new Point(-1, -1);
private boolean mHasAddScrollEvent = false;
private Boolean mIslastDirectionRTL;

private static final int SWIPE_MIN_DISTANCE = 5;
private static final int SWIPE_THRESHOLD_VELOCITY = 300;
Expand All @@ -102,6 +103,8 @@ public class WXScroller extends WXVContainer<ViewGroup> implements WXScrollViewL
private boolean mIsHostAttachedToWindow = false;
private View.OnAttachStateChangeListener mOnAttachStateChangeListener;

private boolean mlastDirectionRTL = false;

public static class Creator implements ComponentCreator {
@Override
public WXComponent createInstance(WXSDKInstance instance, WXVContainer parent, BasicComponentData basicComponentData) throws IllegalAccessException, InvocationTargetException, InstantiationException {
Expand Down Expand Up @@ -482,44 +485,45 @@ public void onScrollChanged(WXHorizontalScrollView scrollView, int x, int y, int
scrollView.addView(mRealView, layoutParams);
scrollView.setHorizontalScrollBarEnabled(false);
mScrollerView = scrollView;
final WXScroller component = this;
final View.OnLayoutChangeListener listener = new View.OnLayoutChangeListener() {
@Override
public void onLayoutChange(View view, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
final View frameLayout = view;
scrollView.post(new Runnable() {
@Override
public void run() {
if (isLayoutRTL()) {
int mw = frameLayout.getMeasuredWidth();
scrollView.scrollTo(mw, component.getScrollY());
} else {
boolean scrollToBegin = true;
Object scrollToBeginOnLTR = getAttrs().get("scrollToBegin");
if (scrollToBeginOnLTR instanceof String){
if("false".equalsIgnoreCase((String)scrollToBeginOnLTR)){
scrollToBegin = false;
}
}
if (scrollToBegin){
scrollView.scrollTo(0, component.getScrollY());
}
final WXScroller component = this;
final View.OnLayoutChangeListener listener = new View.OnLayoutChangeListener() {
@Override
public void onLayoutChange(View view, final int left, int top, final int right, int bottom, final int oldLeft, int oldTop, final int oldRight, int oldBottom) {
final View frameLayout = view;
scrollView.post(new Runnable() {
@Override
public void run() {
if (mIslastDirectionRTL != null && isLayoutRTL() != mIslastDirectionRTL.booleanValue()) {
// when layout direction changed we need convert x to RTL x for scroll to the same item
int currentX = getScrollX();
int totalWidth = getInnerView().getChildAt(0).getWidth();
int displayWidth = getInnerView().getMeasuredWidth();
scrollView.scrollTo(totalWidth - currentX - displayWidth, component.getScrollY());
} else if (isLayoutRTL()) {
// if layout direction not changed, but width changede, we need keep RTL offset
int oldWidth = oldRight - oldLeft;
int width = right - left;
int changedWidth = width - oldWidth;
if (changedWidth != 0) {
scrollView.scrollBy(changedWidth, component.getScrollY());
}
}
});
}
};
mRealView.addOnAttachStateChangeListener(new View.OnAttachStateChangeListener() {
@Override
public void onViewAttachedToWindow(View view) {
view.addOnLayoutChangeListener(listener);
}
mIslastDirectionRTL = new Boolean(isLayoutRTL());
}
});
}
};
mRealView.addOnAttachStateChangeListener(new View.OnAttachStateChangeListener() {
@Override
public void onViewAttachedToWindow(View view) {
view.addOnLayoutChangeListener(listener);
}

@Override
public void onViewDetachedFromWindow(View view) {
view.removeOnLayoutChangeListener(listener);
}
});
@Override
public void onViewDetachedFromWindow(View view) {
view.removeOnLayoutChangeListener(listener);
}
});


if(pageEnable) {
Expand Down Expand Up @@ -798,19 +802,24 @@ public void scrollTo(WXComponent component, Map<String, Object> options) {
int viewXInScroller = 0;
if (this.isLayoutRTL()) {
// if layout direction is rtl, we need calculate rtl scroll x;
if (getInnerView().getChildCount() > 0) {
int totalWidth = getInnerView().getChildAt(0).getWidth();
int displayWidth = getInnerView().getMeasuredWidth();
viewXInScroller = totalWidth - (component.getAbsoluteX() - getAbsoluteX()) - displayWidth;
if (component.getParent() != null && component.getParent() == this) {
if (getInnerView().getChildCount() > 0) {
int totalWidth = getInnerView().getChildAt(0).getWidth();
int displayWidth = getInnerView().getMeasuredWidth();
viewXInScroller = totalWidth - (component.getAbsoluteX() - getAbsoluteX()) - displayWidth;
} else {
viewXInScroller = component.getAbsoluteX() - getAbsoluteX();
}
} else {
viewXInScroller = component.getAbsoluteX() - getAbsoluteX();
int displayWidth = getInnerView().getMeasuredWidth();
viewXInScroller = component.getAbsoluteX() - getAbsoluteX() - displayWidth + (int)component.getLayoutWidth();
}
offsetFloat = - offsetFloat;
offsetFloat = -offsetFloat;
} else {
viewXInScroller = component.getAbsoluteX() - getAbsoluteX();
}

scrollBy(viewXInScroller - getScrollX() + (int) offsetFloat, viewYInScroller - getScrollY() + (int) offsetFloat, smooth);

}

/**
Expand Down
7 changes: 6 additions & 1 deletion ios/sdk/WeexSDK/Sources/Component/WXScrollerComponent.mm
Original file line number Diff line number Diff line change
Expand Up @@ -567,7 +567,12 @@ - (void)scrollToComponent:(WXComponent *)component withOffset:(CGFloat)offset an
CGFloat scaleFactor = self.weexInstance.pixelScaleFactor;

if (_scrollDirection == WXScrollDirectionHorizontal) {
CGFloat contentOffetX = [component.supercomponent.view convertPoint:component.view.frame.origin toView:self.view].x;
CGFloat contentOffetX = 0;
if (self.isDirectionRTL && component.supercomponent != self) {
contentOffetX = [component.supercomponent.view convertPoint:CGPointMake(CGRectGetMaxX(component.view.frame), component.view.frame.origin.y) toView:self.view].x;
} else {
contentOffetX = [component.supercomponent.view convertPoint:component.view.frame.origin toView:self.view].x;
}
contentOffetX += offset * scaleFactor;

if (scrollView.contentSize.width >= scrollView.frame.size.width && contentOffetX > scrollView.contentSize.width - scrollView.frame.size.width) {
Expand Down

0 comments on commit c6f65a2

Please sign in to comment.