From bacba3378f71f51d203cf291f2c220d55e40b04b Mon Sep 17 00:00:00 2001 From: Peter Siegmund Date: Mon, 22 Sep 2014 15:12:20 +0200 Subject: [PATCH 1/4] Added support for item margin --- .../horizontallistview/HorizontalListView.java | 11 +++++++---- README.md | 1 + 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/AndroidHorizontalListView/src/com/meetme/android/horizontallistview/HorizontalListView.java b/AndroidHorizontalListView/src/com/meetme/android/horizontallistview/HorizontalListView.java index c64dc4c..4935271 100644 --- a/AndroidHorizontalListView/src/com/meetme/android/horizontallistview/HorizontalListView.java +++ b/AndroidHorizontalListView/src/com/meetme/android/horizontallistview/HorizontalListView.java @@ -666,7 +666,8 @@ private boolean determineMaxX() { int oldMaxX = mMaxX; // Determine the maximum x position - mMaxX = mCurrentX + (rightView.getRight() - getPaddingLeft()) - getRenderWidth(); + MarginLayoutParams params = (MarginLayoutParams) getLayoutParams(rightView); + mMaxX = mCurrentX + (rightView.getRight() - getPaddingLeft()) - getRenderWidth() + params.rightMargin; // Handle the case where the views do not fill at least 1 screen if (mMaxX < 0) { @@ -787,8 +788,10 @@ private void positionChildren(final int dx) { // Loop each child view for (int i = 0; i < childCount; i++) { View child = getChildAt(i); - int left = leftOffset + getPaddingLeft(); - int top = getPaddingTop(); + MarginLayoutParams params = (MarginLayoutParams) getLayoutParams(child); + + int left = leftOffset + getPaddingLeft() + params.leftMargin; + int top = getPaddingTop() + params.topMargin; int right = left + child.getMeasuredWidth(); int bottom = top + child.getMeasuredHeight(); @@ -796,7 +799,7 @@ private void positionChildren(final int dx) { child.layout(left, top, right, bottom); // Increment our offset by added child's size and divider width - leftOffset += child.getMeasuredWidth() + mDividerWidth; + leftOffset += child.getMeasuredWidth() + mDividerWidth + params.leftMargin + params.rightMargin; } } } diff --git a/README.md b/README.md index 7080251..b66ac64 100644 --- a/README.md +++ b/README.md @@ -34,6 +34,7 @@ Notice you set the `dividerWidth` via the XML namespace you just defined as it i ## Contributors - [Bill Donahue](https://github.com/bdonahue) + - [Peter Siegmund](https://github.com/mars3142) ## Licenses From b5eafa59a4daae17a575e7fbbea56c65f00b8484 Mon Sep 17 00:00:00 2001 From: Peter Siegmund Date: Mon, 22 Sep 2014 15:29:47 +0200 Subject: [PATCH 2/4] Added check, if LayoutParams is instance of MarginLayoutParams --- .../HorizontalListView.java | 34 ++++++++++++++----- 1 file changed, 26 insertions(+), 8 deletions(-) diff --git a/AndroidHorizontalListView/src/com/meetme/android/horizontallistview/HorizontalListView.java b/AndroidHorizontalListView/src/com/meetme/android/horizontallistview/HorizontalListView.java index 4935271..c817619 100644 --- a/AndroidHorizontalListView/src/com/meetme/android/horizontallistview/HorizontalListView.java +++ b/AndroidHorizontalListView/src/com/meetme/android/horizontallistview/HorizontalListView.java @@ -663,11 +663,15 @@ private boolean determineMaxX() { View rightView = getRightmostChild(); if (rightView != null) { + MarginLayoutParams params; int oldMaxX = mMaxX; // Determine the maximum x position - MarginLayoutParams params = (MarginLayoutParams) getLayoutParams(rightView); - mMaxX = mCurrentX + (rightView.getRight() - getPaddingLeft()) - getRenderWidth() + params.rightMargin; + mMaxX = mCurrentX + (rightView.getRight() - getPaddingLeft()) - getRenderWidth(); + if (getLayoutParams(rightView) instanceof MarginLayoutParams) { + params = (MarginLayoutParams) getLayoutParams(rightView); + mMaxX += params.rightMargin; + } // Handle the case where the views do not fill at least 1 screen if (mMaxX < 0) { @@ -787,19 +791,33 @@ private void positionChildren(final int dx) { // Loop each child view for (int i = 0; i < childCount; i++) { + int left; + int top; + int right; + int bottom; View child = getChildAt(i); - MarginLayoutParams params = (MarginLayoutParams) getLayoutParams(child); + MarginLayoutParams params = null; + + left = leftOffset + getPaddingLeft(); + top = getPaddingTop(); + if (child.getLayoutParams() instanceof MarginLayoutParams) { + params = (MarginLayoutParams) getLayoutParams(child); - int left = leftOffset + getPaddingLeft() + params.leftMargin; - int top = getPaddingTop() + params.topMargin; - int right = left + child.getMeasuredWidth(); - int bottom = top + child.getMeasuredHeight(); + left += params.leftMargin; + top += params.topMargin; + } + right = left + child.getMeasuredWidth(); + bottom = top + child.getMeasuredHeight(); // Layout the child child.layout(left, top, right, bottom); // Increment our offset by added child's size and divider width - leftOffset += child.getMeasuredWidth() + mDividerWidth + params.leftMargin + params.rightMargin; + if (params != null) { + leftOffset += child.getMeasuredWidth() + mDividerWidth + params.leftMargin + params.rightMargin; + } else { + leftOffset += child.getMeasuredWidth() + mDividerWidth; + } } } } From 92de650518bda810585f0333466b991805adad22 Mon Sep 17 00:00:00 2001 From: Peter Siegmund Date: Mon, 22 Sep 2014 15:32:26 +0200 Subject: [PATCH 3/4] Fixed wrong check --- .../meetme/android/horizontallistview/HorizontalListView.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AndroidHorizontalListView/src/com/meetme/android/horizontallistview/HorizontalListView.java b/AndroidHorizontalListView/src/com/meetme/android/horizontallistview/HorizontalListView.java index c817619..68d7913 100644 --- a/AndroidHorizontalListView/src/com/meetme/android/horizontallistview/HorizontalListView.java +++ b/AndroidHorizontalListView/src/com/meetme/android/horizontallistview/HorizontalListView.java @@ -800,7 +800,7 @@ private void positionChildren(final int dx) { left = leftOffset + getPaddingLeft(); top = getPaddingTop(); - if (child.getLayoutParams() instanceof MarginLayoutParams) { + if (getLayoutParams(child) instanceof MarginLayoutParams) { params = (MarginLayoutParams) getLayoutParams(child); left += params.leftMargin; From 7b421b67fe6660260cbe9a8bd0182af3a50bf4d0 Mon Sep 17 00:00:00 2001 From: Peter Siegmund Date: Tue, 23 Sep 2014 16:26:07 +0200 Subject: [PATCH 4/4] Fixed jumping while deleting/added left items, if item has margin --- .../HorizontalListView.java | 61 ++++++++++++++----- 1 file changed, 47 insertions(+), 14 deletions(-) diff --git a/AndroidHorizontalListView/src/com/meetme/android/horizontallistview/HorizontalListView.java b/AndroidHorizontalListView/src/com/meetme/android/horizontallistview/HorizontalListView.java index 68d7913..a94fd7a 100644 --- a/AndroidHorizontalListView/src/com/meetme/android/horizontallistview/HorizontalListView.java +++ b/AndroidHorizontalListView/src/com/meetme/android/horizontallistview/HorizontalListView.java @@ -480,7 +480,7 @@ private void addAndMeasureChild(final View child, int viewPos) { * @param child The child. */ private void measureChild(View child) { - ViewGroup.LayoutParams childLayoutParams = getLayoutParams(child); + LayoutParams childLayoutParams = getLayoutParams(child); int childHeightSpec = ViewGroup.getChildMeasureSpec(mHeightMeasureSpec, getPaddingTop() + getPaddingBottom(), childLayoutParams.height); int childWidthSpec; @@ -494,16 +494,27 @@ private void measureChild(View child) { } /** Gets a child's layout parameters, defaults if not available. */ - private ViewGroup.LayoutParams getLayoutParams(View child) { - ViewGroup.LayoutParams layoutParams = child.getLayoutParams(); + private LayoutParams getLayoutParams(View child) { + LayoutParams layoutParams = child.getLayoutParams(); if (layoutParams == null) { // Since this is a horizontal list view default to matching the parents height, and wrapping the width - layoutParams = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.MATCH_PARENT); + layoutParams = new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.MATCH_PARENT); } return layoutParams; } + /** + * Gets a child's margin layout parameters, null if not available + */ + private MarginLayoutParams getMarginLayoutParams(View view) { + MarginLayoutParams params = null; + if (view != null && getLayoutParams(view) instanceof MarginLayoutParams) { + params = (MarginLayoutParams) getLayoutParams(view); + } + return params; + } + @SuppressLint("WrongCall") @Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) { @@ -663,13 +674,12 @@ private boolean determineMaxX() { View rightView = getRightmostChild(); if (rightView != null) { - MarginLayoutParams params; int oldMaxX = mMaxX; // Determine the maximum x position mMaxX = mCurrentX + (rightView.getRight() - getPaddingLeft()) - getRenderWidth(); - if (getLayoutParams(rightView) instanceof MarginLayoutParams) { - params = (MarginLayoutParams) getLayoutParams(rightView); + MarginLayoutParams params = getMarginLayoutParams(rightView); + if (params != null) { mMaxX += params.rightMargin; } @@ -689,11 +699,16 @@ private boolean determineMaxX() { /** Adds children views to the left and right of the current views until the screen is full */ private void fillList(final int dx) { + MarginLayoutParams params; // Get the rightmost child and determine its right edge int edge = 0; View child = getRightmostChild(); if (child != null) { edge = child.getRight(); + params = getMarginLayoutParams(child); + if (params != null) { + edge -= params.rightMargin; + } } // Add new children views to the right, until past the edge of the screen @@ -704,6 +719,10 @@ private void fillList(final int dx) { child = getLeftmostChild(); if (child != null) { edge = child.getLeft(); + params = getMarginLayoutParams(child); + if (params != null) { + edge -= params.leftMargin; + } } // Add new children views to the left, until past the edge of the screen @@ -711,14 +730,22 @@ private void fillList(final int dx) { } private void removeNonVisibleChildren(final int dx) { + int rightMargin = 0; View child = getLeftmostChild(); + MarginLayoutParams params = getMarginLayoutParams(child); + if (params != null) { + rightMargin = params.rightMargin; + } // Loop removing the leftmost child, until that child is on the screen - while (child != null && child.getRight() + dx <= 0) { + while (child != null && child.getRight() + rightMargin + dx <= 0) { // The child is being completely removed so remove its width from the display offset and its divider if it has one. // To remove add the size of the child and its divider (if it has one) to the offset. // You need to add since its being removed from the left side, i.e. shifting the offset to the right. mDisplayOffset += isLastItemInAdapter(mLeftViewAdapterIndex) ? child.getMeasuredWidth() : mDividerWidth + child.getMeasuredWidth(); + if (params != null) { + mDisplayOffset += params.rightMargin; + } // Add the removed view to the cache recycleView(mLeftViewAdapterIndex, child); @@ -731,6 +758,10 @@ private void removeNonVisibleChildren(final int dx) { // Get the new leftmost child child = getLeftmostChild(); + params = getMarginLayoutParams(child); + if (params != null) { + mDisplayOffset += params.leftMargin; + } } child = getRightmostChild(); @@ -771,6 +802,7 @@ private void fillListLeft(int leftEdge, final int dx) { while (leftEdge + dx - mDividerWidth > 0 && mLeftViewAdapterIndex >= 1) { mLeftViewAdapterIndex--; View child = mAdapter.getView(mLeftViewAdapterIndex, getRecycledView(mLeftViewAdapterIndex), this); + MarginLayoutParams params = getMarginLayoutParams(child); addAndMeasureChild(child, INSERT_AT_START_OF_LIST); // If first view, then no divider to the left of it @@ -778,6 +810,9 @@ private void fillListLeft(int leftEdge, final int dx) { // If on a clean edge then just remove the child, otherwise remove the divider as well mDisplayOffset -= leftEdge + dx == 0 ? child.getMeasuredWidth() : mDividerWidth + child.getMeasuredWidth(); + if (params != null) { + mDisplayOffset -= (params.leftMargin + params.rightMargin); + } } } @@ -796,13 +831,11 @@ private void positionChildren(final int dx) { int right; int bottom; View child = getChildAt(i); - MarginLayoutParams params = null; - - left = leftOffset + getPaddingLeft(); - top = getPaddingTop(); - if (getLayoutParams(child) instanceof MarginLayoutParams) { - params = (MarginLayoutParams) getLayoutParams(child); + left = leftOffset + child.getPaddingLeft(); + top = child.getPaddingTop(); + MarginLayoutParams params = getMarginLayoutParams(child); + if (params != null) { left += params.leftMargin; top += params.topMargin; }