looping-layout icon indicating copy to clipboard operation
looping-layout copied to clipboard

android:clipToPadding="false" doesn't work

Open darnogor opened this issue 4 years ago • 2 comments

If I use LinearLayoutManager (horizontal in my case) and set left/right paddings with android:clipToPadding="false" in RecyclerView, I can partially see left and right elements of the list

Screenshot from Figma (what I need to achive): image

But it doesn't work for LoopingLayoutManager Looks like it's not a trivial task, but it would be great if you implement it in the LoopingLayoutManager

darnogor avatar Nov 29 '21 00:11 darnogor

Hello! Thank you for filing this issue =) That looks like a great thing to add! But sadly I'm a bit swamped with other projects at the moment :/ If anyone else wantes to take this on feel free to comment and give it a shot =)

BeksOmega avatar Nov 29 '21 19:11 BeksOmega

@BeksOmega Any progress on it? I partially did this for already added views, but I can't add this when adding new views, i have bugs

For already added view -

    private val paddingLeftClip
        get() = paddingLeft.takeIf { clipToPadding } ?: 0

    private val paddingRightClip
        get() = paddingRight.takeIf { clipToPadding } ?: 0

    private val paddingTopClip
        get() = paddingTop.takeIf { clipToPadding } ?: 0

    private val paddingBottomClip
        get() = paddingBottom.takeIf { clipToPadding } ?: 0

    /**
     * Returns true if any part of the [view] is within the visible bounds of the recycler.
     * False otherwise.
     */
    private fun viewIsVisible(view: View): Boolean {
        // Note for future: Making these checks or= breaks extraLayoutSpacing because (I think) if
        // the hidden view's edge is aligned with the recycler edge, it isn't scrapped when it
        // should be.
        return if (orientation == HORIZONTAL) {
            getDecoratedRight(view) > paddingLeftClip && getDecoratedLeft(view) < width - paddingRightClip
        } else {
            getDecoratedBottom(view) > paddingTopClip && getDecoratedTop(view) < height - paddingBottomClip
        }
    }

    /**
     * Returns true if the [view] is fully within the visible bounds of the recycler along the
     * layout axis. This means fully visible horizontally in horizontal mode, and fully visible
     * vertically in vertical mode. False otherwise.
     */
    private fun viewIsFullyVisible(view: View): Boolean {
        return if (orientation == HORIZONTAL) {
            getDecoratedLeft(view) >= paddingLeftClip && getDecoratedRight(view) <= width - paddingRightClip
        } else {
            getDecoratedTop(view) >= paddingTopClip && getDecoratedBottom(view) <= height - paddingBottomClip
        }
    }

For new view I tried this method, but it leads to bugs (example class, i replace all four)


    private inner class LeadingRightListItem(view: View) : ListItem(view) {

        override val hiddenSize: Int
            get() = (paddingLeftClip - getDecoratedLeft(view)).coerceAtLeast(0)

        override val leadingEdge: Int
            get() = getDecoratedRight(view)

        override val followingEdge: Int
            get() = getDecoratedLeft(view)

        override val size: Int
            get() = getDecoratedMeasuredWidth(view)

        override fun getPositionOfItemFollowingSelf(item: ListItem, rect: Rect): Rect {
            rect.right = followingEdge
            rect.left = rect.right - item.size
            return rect
        }

        override fun getPositionOfSelfAsFirst(rect: Rect, hiddenAmount: Int): Rect {
            rect.right = (width - paddingRight) + hiddenAmount
            rect.left = rect.right - size
            return rect
        }
    }

P1NG2WIN avatar Apr 20 '23 00:04 P1NG2WIN