Index: android_webview/java/src/org/chromium/android_webview/AwViewAndroidDelegate.java |
diff --git a/android_webview/java/src/org/chromium/android_webview/AwViewAndroidDelegate.java b/android_webview/java/src/org/chromium/android_webview/AwViewAndroidDelegate.java |
new file mode 100644 |
index 0000000000000000000000000000000000000000..101db6aef1ea690dc80565fe2629e0eee6b2ae27 |
--- /dev/null |
+++ b/android_webview/java/src/org/chromium/android_webview/AwViewAndroidDelegate.java |
@@ -0,0 +1,143 @@ |
+// Copyright 2016 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+package org.chromium.android_webview; |
+ |
+import android.view.View; |
+import android.view.ViewGroup; |
+import android.widget.FrameLayout; |
+ |
+import org.chromium.base.VisibleForTesting; |
+import org.chromium.content.browser.RenderCoordinates; |
+import org.chromium.ui.base.ViewAndroidDelegate; |
+import org.chromium.ui.gfx.DeviceDisplayInfo; |
+ |
+import java.util.LinkedHashMap; |
+import java.util.Map; |
+import java.util.Map.Entry; |
+ |
+/** |
+ * Implementation of the abstract class {@link ViewAndroidDelegate} for WebView. |
+ */ |
+public class AwViewAndroidDelegate extends ViewAndroidDelegate { |
+ /** |
+ * The current container view. This view can be updated with |
+ * {@link #updateCurrentContainerView()}. |
+ */ |
+ private ViewGroup mContainerView; |
+ |
+ /** |
+ * List of anchor views stored in the order in which they were acquired mapped |
+ * to their position. |
+ */ |
+ private final Map<View, Position> mAnchorViews = new LinkedHashMap<>(); |
+ |
+ private final RenderCoordinates mRenderCoordinates; |
+ |
+ /** |
+ * Represents the position of an anchor view. |
+ */ |
+ @VisibleForTesting |
+ private static class Position { |
+ public final float mX; |
+ public final float mY; |
+ public final float mWidth; |
+ public final float mHeight; |
+ public final int mLeftMargin; |
+ public final int mTopMargin; |
+ |
+ public Position(float x, float y, float width, float height, int leftMargin, |
+ int topMargin) { |
+ mX = x; |
+ mY = y; |
+ mWidth = width; |
+ mHeight = height; |
+ mLeftMargin = leftMargin; |
+ mTopMargin = topMargin; |
+ } |
+ } |
+ |
+ AwViewAndroidDelegate(ViewGroup containerView, RenderCoordinates renderCoordinates) { |
+ mContainerView = containerView; |
+ mRenderCoordinates = renderCoordinates; |
+ } |
+ |
+ @Override |
+ public View acquireView() { |
+ ViewGroup containerView = getContainerView(); |
+ if (containerView == null) return null; |
+ View anchorView = new View(containerView.getContext()); |
+ containerView.addView(anchorView); |
+ // |mAnchorViews| will be updated with the right view position in |setViewPosition|. |
+ mAnchorViews.put(anchorView, null); |
+ return anchorView; |
+ } |
+ |
+ @Override |
+ public void removeView(View anchorView) { |
+ mAnchorViews.remove(anchorView); |
+ ViewGroup containerView = getContainerView(); |
+ if (containerView != null) { |
+ containerView.removeView(anchorView); |
+ } |
+ } |
+ |
+ /** |
+ * Updates the current container view to which this class delegates. Existing anchor views |
+ * are transferred from the old to the new container view. |
+ */ |
+ public void updateCurrentContainerView(ViewGroup containerView) { |
+ ViewGroup oldContainerView = getContainerView(); |
+ mContainerView = containerView; |
+ for (Entry<View, Position> entry : mAnchorViews.entrySet()) { |
+ View anchorView = entry.getKey(); |
+ Position position = entry.getValue(); |
+ if (oldContainerView != null) { |
+ oldContainerView.removeView(anchorView); |
+ } |
+ containerView.addView(anchorView); |
+ if (position != null) { |
+ float scale = (float) DeviceDisplayInfo.create(containerView.getContext()) |
+ .getDIPScale(); |
+ setViewPosition(anchorView, position.mX, position.mY, |
+ position.mWidth, position.mHeight, scale, |
+ position.mLeftMargin, position.mTopMargin); |
+ } |
+ } |
+ } |
+ |
+ @SuppressWarnings("deprecation") // AbsoluteLayout |
+ @Override |
+ public void setViewPosition(View anchorView, float x, float y, float width, float height, |
+ float scale, int leftMargin, int topMargin) { |
+ ViewGroup containerView = getContainerView(); |
+ if (!mAnchorViews.containsKey(anchorView) || containerView == null) return; |
+ |
+ mAnchorViews.put(anchorView, new Position(x, y, width, height, leftMargin, topMargin)); |
+ |
+ if (containerView instanceof FrameLayout) { |
+ super.setViewPosition(anchorView, x, y, width, height, scale, leftMargin, topMargin); |
+ return; |
+ } |
+ // This fixes the offset due to a difference in |
+ // scrolling model of WebView vs. Chrome. |
+ // TODO(sgurun) fix this to use mContainerViewAtCreation.getScroll[X/Y]() |
+ // as it naturally accounts for scroll differences between |
+ // these models. |
+ leftMargin += mRenderCoordinates.getScrollXPixInt(); |
+ topMargin += mRenderCoordinates.getScrollYPixInt(); |
+ |
+ int scaledWidth = Math.round(width * scale); |
+ int scaledHeight = Math.round(height * scale); |
+ android.widget.AbsoluteLayout.LayoutParams lp = |
+ new android.widget.AbsoluteLayout.LayoutParams( |
+ scaledWidth, scaledHeight, leftMargin, topMargin); |
+ anchorView.setLayoutParams(lp); |
+ } |
+ |
+ @Override |
+ public ViewGroup getContainerView() { |
+ return mContainerView; |
+ } |
+} |