Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@
import com.facebook.react.views.progressbar.ReactProgressBarViewManager;
import com.facebook.react.views.scroll.ReactHorizontalScrollViewManager;
import com.facebook.react.views.scroll.ReactScrollViewManager;
import com.facebook.react.views.scroll.ScrollViewManager;
import com.facebook.react.views.slider.ReactSliderManager;
import com.facebook.react.views.swiperefresh.SwipeRefreshLayoutManager;
import com.facebook.react.views.switchview.ReactSwitchManager;
Expand Down Expand Up @@ -211,6 +212,12 @@ public NativeModule get() {
return new PermissionsModule(context);
}
}),
new ModuleSpec(ScrollViewManager.class, new Provider<NativeModule>() {
@Override
public NativeModule get() {
return new ScrollViewManager(context);
}
}),
new ModuleSpec(ShareModule.class, new Provider<NativeModule>() {
@Override
public NativeModule get() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
*/
package com.facebook.react.uimanager;

import android.view.View;

import javax.annotation.Nullable;

import java.util.Arrays;
Expand Down Expand Up @@ -240,6 +242,11 @@ public void synchronouslyUpdateViewOnUIThread(int tag, ReactStylesDiffMap props)
mOperationsQueue.getNativeViewHierarchyManager().updateProperties(tag, props);
}


public View getView(int tag) {
return mOperationsQueue.getNativeViewHierarchyManager().resolveView(tag);
}

protected void handleUpdateView(
ReactShadowNode cssNode,
String className,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/**
* Copyright (c) 2016-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/

package com.facebook.react.views.scroll;

public class ChildFrame {
public int index;
public int x;
public int y;
public int height;
public int width;
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@
import com.facebook.react.uimanager.ReactClippingViewGroup;
import com.facebook.react.uimanager.ReactClippingViewGroupHelper;
import com.facebook.react.views.view.ReactViewBackgroundDrawable;
import com.facebook.react.views.view.ReactViewGroup;

import java.util.ArrayList;

/**
* Similar to {@link ReactScrollView} but only supports horizontal scrolling.
Expand Down Expand Up @@ -117,7 +120,7 @@ protected void onScrollChanged(int x, int y, int oldX, int oldY) {

mActivelyScrolling = true;

ReactScrollViewHelper.emitScrollEvent(this);
ReactScrollViewHelper.emitScrollEvent(this, null);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import javax.annotation.Nullable;

import java.lang.reflect.Field;
import java.util.ArrayList;

import android.graphics.Canvas;
import android.graphics.Color;
Expand All @@ -34,6 +35,7 @@
import com.facebook.react.uimanager.ReactClippingViewGroupHelper;
import com.facebook.infer.annotation.Assertions;
import com.facebook.react.views.view.ReactViewBackgroundDrawable;
import com.facebook.react.views.view.ReactViewGroup;

/**
* A simple subclass of ScrollView that doesn't dispatch measure and layout to its children and has
Expand Down Expand Up @@ -63,6 +65,7 @@ public class ReactScrollView extends ScrollView implements ReactClippingViewGrou
private int mEndFillColor = Color.TRANSPARENT;
private View mContentView;
private @Nullable ReactViewBackgroundDrawable mReactBackgroundDrawable;
private ArrayList<ChildFrame> mCachedChildFrames = new ArrayList<>();

public ReactScrollView(ReactContext context) {
this(context, null);
Expand Down Expand Up @@ -164,8 +167,58 @@ protected void onScrollChanged(int x, int y, int oldX, int oldY) {
mDoneFlinging = false;
}

ReactScrollViewHelper.emitScrollEvent(this);
ArrayList<ChildFrame> childFrames = calculateChildFrames();

ReactScrollViewHelper.emitScrollEvent(this, childFrames);
}
}

public ArrayList<ChildFrame> calculateChildFrames() {
ReactViewGroup contentView = (ReactViewGroup)this.getChildAt(0);

if (contentView == null) {
return null;
}

ArrayList<ChildFrame> updatedChildFrames = new ArrayList<>();

int childCount = contentView.getAllChildrenCount();

for (int i = 0; i < childCount; i++) {
View child = contentView.getChildAtWithSubviewClippingEnabled(i);

boolean isChanged = false;
ChildFrame childFrame = new ChildFrame();
childFrame.index = i;
childFrame.x = child.getLeft();
childFrame.y = child.getTop();
childFrame.height = child.getHeight();
childFrame.width = child.getWidth();

// new
if (mCachedChildFrames.size() <= i) {
isChanged = true;
mCachedChildFrames.add(childFrame);
} else {
ChildFrame cachedChildFrame = mCachedChildFrames.get(i);

// ChildFrame has changed
if (cachedChildFrame.height != childFrame.height ||
cachedChildFrame.width != childFrame.width ||
cachedChildFrame.x != childFrame.x ||
cachedChildFrame.y != childFrame.y) {
isChanged = true;
mCachedChildFrames.set(i, childFrame);
}
}

if (isChanged) {
updatedChildFrames.add(childFrame);

}
}

return updatedChildFrames;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,14 @@
import com.facebook.react.bridge.JSApplicationIllegalArgumentException;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.uimanager.UIManagerModule;
import com.facebook.react.views.view.ReactViewGroup;

import java.util.ArrayList;

/**
* Helper class that deals with emitting Scroll Events.
*/

public class ReactScrollViewHelper {

public static final long MOMENTUM_DELAY = 20;
Expand All @@ -29,8 +33,27 @@ public class ReactScrollViewHelper {
/**
* Shared by {@link ReactScrollView} and {@link ReactHorizontalScrollView}.
*/
public static void emitScrollEvent(ViewGroup scrollView) {
emitScrollEvent(scrollView, ScrollEventType.SCROLL);
public static void emitScrollEvent(ViewGroup scrollView, ArrayList<ChildFrame> childFrames) {
View contentView = scrollView.getChildAt(0);

if (contentView == null) {
return;
}

ReactContext reactContext = (ReactContext) scrollView.getContext();
reactContext.getNativeModule(UIManagerModule.class).getEventDispatcher().dispatchEvent(
ScrollEvent.obtain(
scrollView.getId(),
ScrollEventType.SCROLL,
scrollView.getScrollX(),
scrollView.getScrollY(),
contentView.getWidth(),
contentView.getHeight(),
scrollView.getWidth(),
scrollView.getHeight(),
childFrames
)
);
}

public static void emitScrollBeginDragEvent(ViewGroup scrollView) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,13 @@
import javax.annotation.Nullable;

import java.lang.Override;
import java.util.ArrayList;

import android.support.v4.util.Pools;

import com.facebook.infer.annotation.Assertions;
import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.WritableArray;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.uimanager.PixelUtil;
import com.facebook.react.uimanager.events.Event;
Expand All @@ -37,30 +39,58 @@ public class ScrollEvent extends Event<ScrollEvent> {
private int mScrollViewWidth;
private int mScrollViewHeight;
private @Nullable ScrollEventType mScrollEventType;
private @Nullable ArrayList<ChildFrame> mUpdatedChildFrames = new ArrayList<>();

public static ScrollEvent obtain(
int viewTag,
ScrollEventType scrollEventType,
int scrollX,
int scrollY,
int contentWidth,
int contentHeight,
int scrollViewWidth,
int scrollViewHeight) {
ScrollEvent event = EVENTS_POOL.acquire();
if (event == null) {
event = new ScrollEvent();
}
event.init(
viewTag,
scrollEventType,
scrollX,
scrollY,
contentWidth,
contentHeight,
scrollViewWidth,
scrollViewHeight);
return event;
int viewTag,
ScrollEventType scrollEventType,
int scrollX,
int scrollY,
int contentWidth,
int contentHeight,
int scrollViewWidth,
int scrollViewHeight) {
ScrollEvent event = EVENTS_POOL.acquire();
if (event == null) {
event = new ScrollEvent();
}
event.init(
viewTag,
scrollEventType,
scrollX,
scrollY,
contentWidth,
contentHeight,
scrollViewWidth,
scrollViewHeight);
return event;
}

public static ScrollEvent obtain(
int viewTag,
ScrollEventType scrollEventType,
int scrollX,
int scrollY,
int contentWidth,
int contentHeight,
int scrollViewWidth,
int scrollViewHeight,
ArrayList<ChildFrame> updatedChildFrames) {
ScrollEvent event = EVENTS_POOL.acquire();
if (event == null) {
event = new ScrollEvent();
}
event.init(
viewTag,
scrollEventType,
scrollX,
scrollY,
contentWidth,
contentHeight,
scrollViewWidth,
scrollViewHeight,
updatedChildFrames);
return event;
}

@Override
Expand All @@ -72,22 +102,38 @@ private ScrollEvent() {
}

private void init(
int viewTag,
ScrollEventType scrollEventType,
int scrollX,
int scrollY,
int contentWidth,
int contentHeight,
int scrollViewWidth,
int scrollViewHeight) {
super.init(viewTag);
mScrollEventType = scrollEventType;
mScrollX = scrollX;
mScrollY = scrollY;
mContentWidth = contentWidth;
mContentHeight = contentHeight;
mScrollViewWidth = scrollViewWidth;
mScrollViewHeight = scrollViewHeight;
int viewTag,
ScrollEventType scrollEventType,
int scrollX,
int scrollY,
int contentWidth,
int contentHeight,
int scrollViewWidth,
int scrollViewHeight) {
super.init(viewTag);
mScrollEventType = scrollEventType;
mScrollX = scrollX;
mScrollY = scrollY;
mContentWidth = contentWidth;
mContentHeight = contentHeight;
mScrollViewWidth = scrollViewWidth;
mScrollViewHeight = scrollViewHeight;
}

private void init(
int viewTag,
ScrollEventType scrollEventType,
int scrollX,
int scrollY,
int contentWidth,
int contentHeight,
int scrollViewWidth,
int scrollViewHeight,
ArrayList<ChildFrame> updatedChildFrames) {
init(viewTag, scrollEventType, scrollX, scrollY, contentWidth, contentHeight, scrollViewWidth, scrollViewHeight);
if (updatedChildFrames != null) {
mUpdatedChildFrames.addAll(updatedChildFrames);
}
}

@Override
Expand Down Expand Up @@ -134,11 +180,29 @@ private WritableMap serializeEventData() {
layoutMeasurement.putDouble("width", PixelUtil.toDIPFromPixel(mScrollViewWidth));
layoutMeasurement.putDouble("height", PixelUtil.toDIPFromPixel(mScrollViewHeight));

WritableArray updatedFrames = Arguments.createArray();

if (mUpdatedChildFrames != null) {
for (int i = 0; i < mUpdatedChildFrames.size(); i++) {
ChildFrame childFrame = mUpdatedChildFrames.get(i);

WritableMap map = Arguments.createMap();
map.putInt("index", childFrame.index);
map.putDouble("height", PixelUtil.toDIPFromPixel(childFrame.height));
map.putDouble("width", PixelUtil.toDIPFromPixel(childFrame.width));
map.putDouble("x", PixelUtil.toDIPFromPixel(childFrame.x));
map.putDouble("y", PixelUtil.toDIPFromPixel(childFrame.y));

updatedFrames.pushMap(map);
}
}

WritableMap event = Arguments.createMap();
event.putMap("contentInset", contentInset);
event.putMap("contentOffset", contentOffset);
event.putMap("contentSize", contentSize);
event.putMap("layoutMeasurement", layoutMeasurement);
event.putArray("updatedChildFrames", updatedFrames);

event.putInt("target", getViewTag());
event.putBoolean("responderIgnoreScroll", true);
Expand Down
Loading