Add measureInWindow on Android
Summary:public This adds the capability to get a View in absolute position on the screen, not just relative to the RootView. This is the Android implementation Reviewed By: andreicoman11 Differential Revision: D2939170 fb-gh-sync-id: 658f1ebe6a458088f657a7469389add1a12222cd shipit-source-id: 658f1ebe6a458088f657a7469389add1a12222cd
This commit is contained in:
parent
f9e81d9bcc
commit
b26f699c9a
|
@ -482,6 +482,28 @@ public class NativeViewHierarchyManager {
|
|||
outputBuffer[3] = v.getHeight();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the coordinates of a view relative to the entire phone screen (not just the RootView
|
||||
* which is what measure will return)
|
||||
*
|
||||
* @param tag - the tag for the view
|
||||
* @param outputBuffer - output buffer that contains [x,y,width,height] of the view in coordinates
|
||||
* relative to the device window
|
||||
*/
|
||||
public void measureInWindow(int tag, int[] outputBuffer) {
|
||||
UiThreadUtil.assertOnUiThread();
|
||||
View v = mTagsToViews.get(tag);
|
||||
if (v == null) {
|
||||
throw new NoSuchNativeViewException("No native view for " + tag + " currently exists");
|
||||
}
|
||||
|
||||
v.getLocationOnScreen(outputBuffer);
|
||||
|
||||
// outputBuffer[0,1] already contain what we want
|
||||
outputBuffer[2] = v.getWidth();
|
||||
outputBuffer[3] = v.getHeight();
|
||||
}
|
||||
|
||||
public int findTargetTagForTouch(int reactTag, float touchX, float touchY) {
|
||||
View view = mTagsToViews.get(reactTag);
|
||||
if (view == null) {
|
||||
|
|
|
@ -380,8 +380,8 @@ public class UIImplementation {
|
|||
}
|
||||
|
||||
/**
|
||||
* Determines the location on screen, width, and height of the given view and returns the values
|
||||
* via an async callback.
|
||||
* Determines the location on screen, width, and height of the given view relative to the root
|
||||
* view and returns the values via an async callback.
|
||||
*/
|
||||
public void measure(int reactTag, Callback callback) {
|
||||
// This method is called by the implementation of JS touchable interface (see Touchable.js for
|
||||
|
@ -391,6 +391,15 @@ public class UIImplementation {
|
|||
mOperationsQueue.enqueueMeasure(reactTag, callback);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines the location on screen, width, and height of the given view relative to the device
|
||||
* screen and returns the values via an async callback. This is the absolute position including
|
||||
* things like the status bar
|
||||
*/
|
||||
public void measureInWindow(int reactTag, Callback callback) {
|
||||
mOperationsQueue.enqueueMeasureInWindow(reactTag, callback);
|
||||
}
|
||||
|
||||
/**
|
||||
* Measures the view specified by tag relative to the given ancestorTag. This means that the
|
||||
* returned x, y are relative to the origin x, y of the ancestor view. Results are stored in the
|
||||
|
|
|
@ -253,6 +253,16 @@ public class UIManagerModule extends ReactContextBaseJavaModule implements
|
|||
mUIImplementation.measure(reactTag, callback);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines the location on screen, width, and height of the given view relative to the device
|
||||
* screen and returns the values via an async callback. This is the absolute position including
|
||||
* things like the status bar
|
||||
*/
|
||||
@ReactMethod
|
||||
public void measureInWindow(int reactTag, Callback callback) {
|
||||
mUIImplementation.measureInWindow(reactTag, callback);
|
||||
}
|
||||
|
||||
/**
|
||||
* Measures the view specified by tag relative to the given ancestorTag. This means that the
|
||||
* returned x, y are relative to the origin x, y of the ancestor view. Results are stored in the
|
||||
|
|
|
@ -385,6 +385,38 @@ public class UIViewOperationQueue {
|
|||
}
|
||||
}
|
||||
|
||||
private final class MeasureInWindowOperation implements UIOperation {
|
||||
|
||||
private final int mReactTag;
|
||||
private final Callback mCallback;
|
||||
|
||||
private MeasureInWindowOperation(
|
||||
final int reactTag,
|
||||
final Callback callback) {
|
||||
super();
|
||||
mReactTag = reactTag;
|
||||
mCallback = callback;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute() {
|
||||
try {
|
||||
mNativeViewHierarchyManager.measureInWindow(mReactTag, mMeasureBuffer);
|
||||
} catch (NoSuchNativeViewException e) {
|
||||
// Invoke with no args to signal failure and to allow JS to clean up the callback
|
||||
// handle.
|
||||
mCallback.invoke();
|
||||
return;
|
||||
}
|
||||
|
||||
float x = PixelUtil.toDIPFromPixel(mMeasureBuffer[0]);
|
||||
float y = PixelUtil.toDIPFromPixel(mMeasureBuffer[1]);
|
||||
float width = PixelUtil.toDIPFromPixel(mMeasureBuffer[2]);
|
||||
float height = PixelUtil.toDIPFromPixel(mMeasureBuffer[3]);
|
||||
mCallback.invoke(x, y, width, height);
|
||||
}
|
||||
}
|
||||
|
||||
private ArrayList<UIOperation> mOperations = new ArrayList<>();
|
||||
|
||||
private final class FindTargetForTouchOperation implements UIOperation {
|
||||
|
@ -634,6 +666,14 @@ public class UIViewOperationQueue {
|
|||
new MeasureOperation(reactTag, callback));
|
||||
}
|
||||
|
||||
public void enqueueMeasureInWindow(
|
||||
final int reactTag,
|
||||
final Callback callback) {
|
||||
mOperations.add(
|
||||
new MeasureInWindowOperation(reactTag, callback)
|
||||
);
|
||||
}
|
||||
|
||||
public void enqueueFindTargetForTouch(
|
||||
final int reactTag,
|
||||
final float targetX,
|
||||
|
|
Loading…
Reference in New Issue