Loading tools/layoutlib/bridge/src/android/view/BridgeInflater.java +9 −6 Original line number Diff line number Diff line Loading @@ -265,13 +265,16 @@ public final class BridgeInflater extends LayoutInflater { if (viewKey != null) { bc.addViewKey(view, viewKey); } String scrollPos = attrs.getAttributeValue(BridgeConstants.NS_RESOURCES, "scrollY"); if (scrollPos != null) { if (scrollPos.endsWith("px")) { int value = Integer.parseInt(scrollPos.substring(0, scrollPos.length() - 2)); String scrollPosX = attrs.getAttributeValue(BridgeConstants.NS_RESOURCES, "scrollX"); if (scrollPosX != null && scrollPosX.endsWith("px")) { int value = Integer.parseInt(scrollPosX.substring(0, scrollPosX.length() - 2)); bc.setScrollXPos(view, value); } String scrollPosY = attrs.getAttributeValue(BridgeConstants.NS_RESOURCES, "scrollY"); if (scrollPosY != null && scrollPosY.endsWith("px")) { int value = Integer.parseInt(scrollPosY.substring(0, scrollPosY.length() - 2)); bc.setScrollYPos(view, value); } } if (ReflectionUtils.isInstanceOf(view, RecyclerViewUtil.CN_RECYCLER_VIEW)) { Integer resourceId = null; String attrVal = attrs.getAttributeValue(BridgeConstants.NS_TOOLS_URI, Loading tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java +11 −1 Original line number Diff line number Diff line Loading @@ -127,7 +127,8 @@ public final class BridgeContext extends Context { private final LayoutlibCallback mLayoutlibCallback; private final WindowManager mWindowManager; private final DisplayManager mDisplayManager; private final HashMap<View, Integer> mScrollYPos = new HashMap<View, Integer>(); private final HashMap<View, Integer> mScrollYPos = new HashMap<>(); private final HashMap<View, Integer> mScrollXPos = new HashMap<>(); private Resources.Theme mTheme; Loading Loading @@ -1837,6 +1838,15 @@ public final class BridgeContext extends Context { return pos != null ? pos : 0; } public void setScrollXPos(@NonNull View view, int scrollPos) { mScrollXPos.put(view, scrollPos); } public int getScrollXPos(@NonNull View view) { Integer pos = mScrollXPos.get(view); return pos != null ? pos : 0; } @Override public Context createDeviceProtectedStorageContext() { // pass Loading tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java +24 −14 Original line number Diff line number Diff line Loading @@ -1057,25 +1057,30 @@ public class RenderSessionImpl extends RenderAction<SessionParams> { } /** * Set the vertical scroll position on all the components with the "scrollY" attribute. If the * component supports nested scrolling attempt that first, then use the unconsumed scroll part * to scroll the content in the component. * Set the scroll position on all the components with the "scrollX" and "scrollY" attribute. If * the component supports nested scrolling attempt that first, then use the unconsumed scroll * part to scroll the content in the component. */ private void handleScrolling(View view) { BridgeContext context = getContext(); int scrollPos = context.getScrollYPos(view); if (scrollPos != 0) { int scrollPosX = context.getScrollXPos(view); int scrollPosY = context.getScrollYPos(view); if (scrollPosX != 0 || scrollPosY != 0) { if (view.isNestedScrollingEnabled()) { int[] consumed = new int[2]; if (view.startNestedScroll(DesignLibUtil.SCROLL_AXIS_VERTICAL)) { view.dispatchNestedPreScroll(0, scrollPos, consumed, null); view.dispatchNestedScroll(consumed[0], consumed[1], 0, scrollPos, null); int axis = scrollPosX != 0 ? View.SCROLL_AXIS_HORIZONTAL : 0; axis |= scrollPosY != 0 ? View.SCROLL_AXIS_VERTICAL : 0; if (view.startNestedScroll(axis)) { view.dispatchNestedPreScroll(scrollPosX, scrollPosY, consumed, null); view.dispatchNestedScroll(consumed[0], consumed[1], scrollPosX, scrollPosY, null); view.stopNestedScroll(); scrollPos -= consumed[1]; scrollPosX -= consumed[0]; scrollPosY -= consumed[1]; } } if (scrollPos != 0) { view.scrollBy(0, scrollPos); if (scrollPosX != 0 || scrollPosY != 0) { view.scrollBy(scrollPosX, scrollPosY); } } Loading Loading @@ -1276,14 +1281,20 @@ public class RenderSessionImpl extends RenderAction<SessionParams> { return null; } ViewParent parent = view.getParent(); ViewInfo result; if (isContentFrame) { // Account for parent scroll values when calculating the bounding box int scrollX = parent != null ? ((View)parent).getScrollX() : 0; int scrollY = parent != null ? ((View)parent).getScrollY() : 0; // The view is part of the layout added by the user. Hence, // the ViewCookie may be obtained only through the Context. result = new ViewInfo(view.getClass().getName(), getContext().getViewKey(view), view.getLeft(), view.getTop() + offset, view.getRight(), view.getBottom() + offset, view, view.getLayoutParams()); -scrollX + view.getLeft(), -scrollY + view.getTop() + offset, -scrollX + view.getRight(), -scrollY + view.getBottom() + offset, view, view.getLayoutParams()); } else { // We are part of the system decor. SystemViewInfo r = new SystemViewInfo(view.getClass().getName(), Loading Loading @@ -1311,7 +1322,6 @@ public class RenderSessionImpl extends RenderAction<SessionParams> { // its parent is of type ActionMenuView. We can also check if the view is // instanceof ActionMenuItemView but that will fail for menus using // actionProviderClass. ViewParent parent = view.getParent(); while (parent != mViewRoot && parent instanceof ViewGroup) { if (parent instanceof ActionMenuView) { r.setViewType(ViewType.ACTION_BAR_MENU); Loading tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/scrolled.png 0 → 100644 +714 B Loading image diff... tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/scrolled.xml 0 → 100644 +57 −0 Original line number Diff line number Diff line <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:scrollX="10px" android:scrollY="30px"> <LinearLayout android:layout_width="60dp" android:layout_height="60dp" android:background="#FF0000" /> <LinearLayout android:layout_width="60dp" android:layout_height="30dp" android:background="#00FF00" /> <LinearLayout android:layout_width="60dp" android:layout_height="60dp" android:background="#0000FF" /> <LinearLayout android:layout_width="60dp" android:layout_height="30dp" android:background="#FF00FF" /> <LinearLayout android:layout_width="60dp" android:layout_height="60dp" android:background="#00FFFF" /> <LinearLayout android:layout_width="200dp" android:layout_height="400dp" android:orientation="vertical" android:scrollX="-30px" android:scrollY="150px"> <LinearLayout android:layout_width="fill_parent" android:layout_height="60dp" android:background="#FF0000" /> <LinearLayout android:layout_width="fill_parent" android:layout_height="30dp" android:background="#00FF00" /> <LinearLayout android:layout_width="fill_parent" android:layout_height="60dp" android:background="#0000FF" /> <LinearLayout android:layout_width="fill_parent" android:layout_height="30dp" android:background="#FF00FF" /> <LinearLayout android:layout_width="fill_parent" android:layout_height="60dp" android:background="#00FFFF" /> </LinearLayout> </LinearLayout> Loading
tools/layoutlib/bridge/src/android/view/BridgeInflater.java +9 −6 Original line number Diff line number Diff line Loading @@ -265,13 +265,16 @@ public final class BridgeInflater extends LayoutInflater { if (viewKey != null) { bc.addViewKey(view, viewKey); } String scrollPos = attrs.getAttributeValue(BridgeConstants.NS_RESOURCES, "scrollY"); if (scrollPos != null) { if (scrollPos.endsWith("px")) { int value = Integer.parseInt(scrollPos.substring(0, scrollPos.length() - 2)); String scrollPosX = attrs.getAttributeValue(BridgeConstants.NS_RESOURCES, "scrollX"); if (scrollPosX != null && scrollPosX.endsWith("px")) { int value = Integer.parseInt(scrollPosX.substring(0, scrollPosX.length() - 2)); bc.setScrollXPos(view, value); } String scrollPosY = attrs.getAttributeValue(BridgeConstants.NS_RESOURCES, "scrollY"); if (scrollPosY != null && scrollPosY.endsWith("px")) { int value = Integer.parseInt(scrollPosY.substring(0, scrollPosY.length() - 2)); bc.setScrollYPos(view, value); } } if (ReflectionUtils.isInstanceOf(view, RecyclerViewUtil.CN_RECYCLER_VIEW)) { Integer resourceId = null; String attrVal = attrs.getAttributeValue(BridgeConstants.NS_TOOLS_URI, Loading
tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java +11 −1 Original line number Diff line number Diff line Loading @@ -127,7 +127,8 @@ public final class BridgeContext extends Context { private final LayoutlibCallback mLayoutlibCallback; private final WindowManager mWindowManager; private final DisplayManager mDisplayManager; private final HashMap<View, Integer> mScrollYPos = new HashMap<View, Integer>(); private final HashMap<View, Integer> mScrollYPos = new HashMap<>(); private final HashMap<View, Integer> mScrollXPos = new HashMap<>(); private Resources.Theme mTheme; Loading Loading @@ -1837,6 +1838,15 @@ public final class BridgeContext extends Context { return pos != null ? pos : 0; } public void setScrollXPos(@NonNull View view, int scrollPos) { mScrollXPos.put(view, scrollPos); } public int getScrollXPos(@NonNull View view) { Integer pos = mScrollXPos.get(view); return pos != null ? pos : 0; } @Override public Context createDeviceProtectedStorageContext() { // pass Loading
tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java +24 −14 Original line number Diff line number Diff line Loading @@ -1057,25 +1057,30 @@ public class RenderSessionImpl extends RenderAction<SessionParams> { } /** * Set the vertical scroll position on all the components with the "scrollY" attribute. If the * component supports nested scrolling attempt that first, then use the unconsumed scroll part * to scroll the content in the component. * Set the scroll position on all the components with the "scrollX" and "scrollY" attribute. If * the component supports nested scrolling attempt that first, then use the unconsumed scroll * part to scroll the content in the component. */ private void handleScrolling(View view) { BridgeContext context = getContext(); int scrollPos = context.getScrollYPos(view); if (scrollPos != 0) { int scrollPosX = context.getScrollXPos(view); int scrollPosY = context.getScrollYPos(view); if (scrollPosX != 0 || scrollPosY != 0) { if (view.isNestedScrollingEnabled()) { int[] consumed = new int[2]; if (view.startNestedScroll(DesignLibUtil.SCROLL_AXIS_VERTICAL)) { view.dispatchNestedPreScroll(0, scrollPos, consumed, null); view.dispatchNestedScroll(consumed[0], consumed[1], 0, scrollPos, null); int axis = scrollPosX != 0 ? View.SCROLL_AXIS_HORIZONTAL : 0; axis |= scrollPosY != 0 ? View.SCROLL_AXIS_VERTICAL : 0; if (view.startNestedScroll(axis)) { view.dispatchNestedPreScroll(scrollPosX, scrollPosY, consumed, null); view.dispatchNestedScroll(consumed[0], consumed[1], scrollPosX, scrollPosY, null); view.stopNestedScroll(); scrollPos -= consumed[1]; scrollPosX -= consumed[0]; scrollPosY -= consumed[1]; } } if (scrollPos != 0) { view.scrollBy(0, scrollPos); if (scrollPosX != 0 || scrollPosY != 0) { view.scrollBy(scrollPosX, scrollPosY); } } Loading Loading @@ -1276,14 +1281,20 @@ public class RenderSessionImpl extends RenderAction<SessionParams> { return null; } ViewParent parent = view.getParent(); ViewInfo result; if (isContentFrame) { // Account for parent scroll values when calculating the bounding box int scrollX = parent != null ? ((View)parent).getScrollX() : 0; int scrollY = parent != null ? ((View)parent).getScrollY() : 0; // The view is part of the layout added by the user. Hence, // the ViewCookie may be obtained only through the Context. result = new ViewInfo(view.getClass().getName(), getContext().getViewKey(view), view.getLeft(), view.getTop() + offset, view.getRight(), view.getBottom() + offset, view, view.getLayoutParams()); -scrollX + view.getLeft(), -scrollY + view.getTop() + offset, -scrollX + view.getRight(), -scrollY + view.getBottom() + offset, view, view.getLayoutParams()); } else { // We are part of the system decor. SystemViewInfo r = new SystemViewInfo(view.getClass().getName(), Loading Loading @@ -1311,7 +1322,6 @@ public class RenderSessionImpl extends RenderAction<SessionParams> { // its parent is of type ActionMenuView. We can also check if the view is // instanceof ActionMenuItemView but that will fail for menus using // actionProviderClass. ViewParent parent = view.getParent(); while (parent != mViewRoot && parent instanceof ViewGroup) { if (parent instanceof ActionMenuView) { r.setViewType(ViewType.ACTION_BAR_MENU); Loading
tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/scrolled.png 0 → 100644 +714 B Loading image diff...
tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/scrolled.xml 0 → 100644 +57 −0 Original line number Diff line number Diff line <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:scrollX="10px" android:scrollY="30px"> <LinearLayout android:layout_width="60dp" android:layout_height="60dp" android:background="#FF0000" /> <LinearLayout android:layout_width="60dp" android:layout_height="30dp" android:background="#00FF00" /> <LinearLayout android:layout_width="60dp" android:layout_height="60dp" android:background="#0000FF" /> <LinearLayout android:layout_width="60dp" android:layout_height="30dp" android:background="#FF00FF" /> <LinearLayout android:layout_width="60dp" android:layout_height="60dp" android:background="#00FFFF" /> <LinearLayout android:layout_width="200dp" android:layout_height="400dp" android:orientation="vertical" android:scrollX="-30px" android:scrollY="150px"> <LinearLayout android:layout_width="fill_parent" android:layout_height="60dp" android:background="#FF0000" /> <LinearLayout android:layout_width="fill_parent" android:layout_height="30dp" android:background="#00FF00" /> <LinearLayout android:layout_width="fill_parent" android:layout_height="60dp" android:background="#0000FF" /> <LinearLayout android:layout_width="fill_parent" android:layout_height="30dp" android:background="#FF00FF" /> <LinearLayout android:layout_width="fill_parent" android:layout_height="60dp" android:background="#00FFFF" /> </LinearLayout> </LinearLayout>