/** * Copyright (c) 2015-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; import javax.annotation.Nullable; import java.lang.Override; import android.support.v4.util.Pools; import com.facebook.infer.annotation.Assertions; import com.facebook.react.bridge.Arguments; import com.facebook.react.bridge.WritableMap; import com.facebook.react.uimanager.PixelUtil; import com.facebook.react.uimanager.events.Event; import com.facebook.react.uimanager.events.RCTEventEmitter; /** * A event dispatched from a ScrollView scrolling. */ public class ScrollEvent extends Event<ScrollEvent> { private static final Pools.SynchronizedPool<ScrollEvent> EVENTS_POOL = new Pools.SynchronizedPool<>(3); private int mScrollX; private int mScrollY; private int mContentWidth; private int mContentHeight; private int mScrollViewWidth; private int mScrollViewHeight; private @Nullable ScrollEventType mScrollEventType; 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; } @Override public void onDispose() { EVENTS_POOL.release(this); } 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; } @Override public String getEventName() { return Assertions.assertNotNull(mScrollEventType).getJSEventName(); } @Override public short getCoalescingKey() { // All scroll events for a given view can be coalesced return 0; } @Override public boolean canCoalesce() { // Only SCROLL events can be coalesced, all others can not be if (mScrollEventType == ScrollEventType.SCROLL) { return true; } return false; } @Override public void dispatch(RCTEventEmitter rctEventEmitter) { rctEventEmitter.receiveEvent(getViewTag(), getEventName(), serializeEventData()); } private WritableMap serializeEventData() { WritableMap contentInset = Arguments.createMap(); contentInset.putDouble("top", 0); contentInset.putDouble("bottom", 0); contentInset.putDouble("left", 0); contentInset.putDouble("right", 0); WritableMap contentOffset = Arguments.createMap(); contentOffset.putDouble("x", PixelUtil.toDIPFromPixel(mScrollX)); contentOffset.putDouble("y", PixelUtil.toDIPFromPixel(mScrollY)); WritableMap contentSize = Arguments.createMap(); contentSize.putDouble("width", PixelUtil.toDIPFromPixel(mContentWidth)); contentSize.putDouble("height", PixelUtil.toDIPFromPixel(mContentHeight)); WritableMap layoutMeasurement = Arguments.createMap(); layoutMeasurement.putDouble("width", PixelUtil.toDIPFromPixel(mScrollViewWidth)); layoutMeasurement.putDouble("height", PixelUtil.toDIPFromPixel(mScrollViewHeight)); WritableMap event = Arguments.createMap(); event.putMap("contentInset", contentInset); event.putMap("contentOffset", contentOffset); event.putMap("contentSize", contentSize); event.putMap("layoutMeasurement", layoutMeasurement); event.putInt("target", getViewTag()); event.putBoolean("responderIgnoreScroll", true); return event; } }