Skip to content

Commit

Permalink
Merge pull request #7 from cabriole/dev
Browse files Browse the repository at this point in the history
1.1.0
  • Loading branch information
rubensousa committed May 13, 2020
2 parents 2d21b8d + e024873 commit 2d467a6
Show file tree
Hide file tree
Showing 14 changed files with 342 additions and 15 deletions.
6 changes: 0 additions & 6 deletions .github/workflows/dev.yml
Original file line number Diff line number Diff line change
@@ -1,12 +1,6 @@
name: Dev

on:
pull_request:
paths-ignore:
- '**/*.md'
- '**/*.txt'
branches:
- 'dev'
push:
paths-ignore:
- '**/*.md'
Expand Down
28 changes: 28 additions & 0 deletions .github/workflows/pull_requests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
name: Pull Requests

on:
pull_request:
paths-ignore:
- '**/*.md'
- '**/*.txt'
branches:
- 'dev'

jobs:
build:

runs-on: ubuntu-latest

steps:
- name: checkout
uses: actions/checkout@v2
- name: setup JDK 1.8
uses: actions/setup-java@v1
with:
java-version: 1.8
- name: Install Android SDK
uses: malinskiy/action-android/install-sdk@release/0.0.5
- name: Run unit tests
run: ./gradlew testDebugUnitTest --stacktrace -Pbintray_user=${{ secrets.BINTRAY_USER }} -Pbintray_apikey=${{ secrets.BINTRAY_KEY }}
- name: Assemble library
run: ./gradlew assembleRelease -Pbintray_user=${{ secrets.BINTRAY_USER }} -Pbintray_apikey=${{ secrets.BINTRAY_KEY }}
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# 1.1.0

- Added `GridSpanBoundsMarginDecoration` to apply margins to the bounds of RecyclerViews that use a GridLayoutManager with different span sizes

# 1.0.0

- Initial release
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ Decorator is a library that helps creating composable margins and dividers in Re
## Install

```groovy
implementation 'io.cabriole:decorator:x.x.x'
implementation 'io.cabriole:decorator:1.1.0'
```

Replace x.x.x with the latest version available
Expand Down
2 changes: 1 addition & 1 deletion decorator/gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
#
LIBRARY_VERSION=1.0.0
LIBRARY_VERSION=1.1.0
LIBRARY_GROUP=io.cabriole
LIBRARY_ARTIFACT=decorator
# POM info
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ import androidx.recyclerview.widget.RecyclerView
*
* @param topMargin margin to be applied to the top bound
*
* @param rightMargin margin to be applied to the right bound
*
* @param bottomMargin margin to be applied to the bottom bound
*
* @param orientation the orientation of the RecyclerView. Default is [RecyclerView.VERTICAL]
*
* @param inverted true if the LayoutManager is inverted and items are laid out
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,205 @@
/*
* Copyright (c) 2020. Cabriole
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package io.cabriole.decorator

import android.graphics.Rect
import android.view.View
import androidx.annotation.Px
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.RecyclerView

/**
* A [RecyclerView.ItemDecoration] that applies a margin to the bounds of the RecyclerView
*
* Unlike [GridBoundsMarginDecoration], this one supports grids with different span sizes
* but requires a [GridLayoutManager].
*
* @param leftMargin margin to be applied to the left bound
*
* @param topMargin margin to be applied to the top bound
*
* @param rightMargin margin to be applied to the right bound
*
* @param bottomMargin margin to be applied to the bottom bound
*
* @param gridLayoutManager the [GridLayoutManager] used by the [RecyclerView]
*
* @param decorationLookup an optional [DecorationLookup] to filter positions
* that shouldn't have this decoration applied to
*
* Any property change should be followed by [RecyclerView.invalidateItemDecorations]
*
* Any property change in [margin] or [gridLayoutManager]
* should be followed by [RecyclerView.invalidateItemDecorations]
*/
class GridSpanBoundsMarginDecoration(
@Px private var leftMargin: Int = 0,
@Px private var topMargin: Int = 0,
@Px private var rightMargin: Int = 0,
@Px private var bottomMargin: Int = 0,
private var gridLayoutManager: GridLayoutManager,
private var decorationLookup: DecorationLookup? = null
) : AbstractMarginDecoration(decorationLookup) {

fun setMargin(margin: Int) {
setMargin(left = margin, top = margin, right = margin, bottom = margin)
}

fun setMargin(left: Int = 0, top: Int = 0, right: Int = 0, bottom: Int = 0) {
this.leftMargin = left
this.topMargin = top
this.rightMargin = right
this.bottomMargin = bottom
}

fun setGridLayoutManager(layoutManager: GridLayoutManager) {
this.gridLayoutManager = layoutManager
}

fun getGridLayoutManager() = gridLayoutManager

fun getLeftMargin() = leftMargin

fun getTopMargin() = topMargin

fun getRightMargin() = rightMargin

fun getBottomMargin() = bottomMargin

/**
* @param decorationLookup an optional [DecorationLookup] to filter positions
* that shouldn't have this decoration applied to
*/
fun setDecorationLookup(decorationLookup: DecorationLookup?) {
this.decorationLookup = decorationLookup
}


override fun getItemOffsets(
outRect: Rect,
view: View,
position: Int,
parent: RecyclerView,
state: RecyclerView.State,
layoutManager: RecyclerView.LayoutManager
) {
val layoutParams = view.layoutParams as GridLayoutManager.LayoutParams
val columnIndex = layoutParams.spanIndex

if (columnIndex == GridLayoutManager.LayoutParams.INVALID_SPAN_ID) {
return
}

val itemCount = layoutManager.itemCount
val columns = gridLayoutManager.spanCount

if (gridLayoutManager.orientation == RecyclerView.VERTICAL) {
applyVerticalOffsets(
outRect,
position,
itemCount,
columns,
columnIndex,
layoutParams.spanSize
)
} else {
applyHorizontalOffsets(
outRect,
position,
itemCount,
columns,
columnIndex,
layoutParams.spanSize
)
}
}

private fun applyVerticalOffsets(
outRect: Rect,
position: Int,
itemCount: Int,
columns: Int,
columnIndex: Int,
spanSize: Int
) {
val isInFirstLine = position <= columnIndex

// Our position plus the size we occupy will be greater
// or equal than the item count if we're in the last line.
val isInLastLine = position + (columns - columnIndex - spanSize) >= itemCount - 1

if (columnIndex == 0) {
outRect.left = leftMargin
}

if (columnIndex + spanSize >= columns) {
outRect.right = rightMargin
}

if (isInFirstLine) {
if (!gridLayoutManager.reverseLayout) {
outRect.top = topMargin
} else {
outRect.bottom = bottomMargin
}
} else if (isInLastLine) {
if (!gridLayoutManager.reverseLayout) {
outRect.bottom = bottomMargin
} else {
outRect.top = topMargin
}
}
}

private fun applyHorizontalOffsets(
outRect: Rect,
position: Int,
itemCount: Int,
columns: Int,
columnIndex: Int,
spanSize: Int
) {
val isInFirstLine = position <= columnIndex

// Our position plus the size we occupy will be greater
// or equal than the item count if we're in the last line.
val isInLastLine = position + (columns - columnIndex - spanSize) >= itemCount - 1

if (columnIndex == 0) {
outRect.top = topMargin
}

if (columnIndex + spanSize >= columns) {
outRect.bottom = bottomMargin
}

if (isInFirstLine) {
if (!gridLayoutManager.reverseLayout) {
outRect.left = leftMargin
} else {
outRect.right = rightMargin
}
} else if (isInLastLine) {
if (!gridLayoutManager.reverseLayout) {
outRect.right = rightMargin
} else {
outRect.left = leftMargin
}
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -46,13 +46,13 @@ class GridSpanMarginDecoration(

fun getMargin() = margin

fun getLayoutManager() = gridLayoutManager
fun getGridLayoutManager() = gridLayoutManager

fun setMargin(margin: Int) {
this.margin = margin
}

fun setGridLayoutManage(layoutManager: GridLayoutManager) {
fun setGridLayoutManager(layoutManager: GridLayoutManager) {
this.gridLayoutManager = layoutManager
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ class DecorationFragment : Fragment(R.layout.screen_decoration),
const val ARG_GRID_DIVIDER_DECORATION = 4
const val ARG_LINEAR_BOUNDS_DECORATION = 5
const val ARG_GRID_BOUNDS_DECORATION = 6
const val ARG_GRID_SPAN_BOUNDS_DECORATION = 7
}

private val binding get() = _binding!!
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ class DecorationListController(
GridBoundsDelegate(fragment.resources)
decorations[DecorationFragment.ARG_GRID_SPAN_DECORATION] =
GridSpanDelegate(fragment.requireActivity())
decorations[DecorationFragment.ARG_GRID_SPAN_BOUNDS_DECORATION] =
GridSpanBoundsDelegate(fragment.requireActivity())
decorations[DecorationFragment.ARG_GRID_DIVIDER_DECORATION] =
GridDividerDelegate(fragment.resources)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,13 @@ class MainFragment : Fragment(R.layout.screen_options) {
R.string.decorator_grid_bounds_margin_summary
)
)
optionList.add(
OptionModel(
DecorationFragment.ARG_GRID_SPAN_BOUNDS_DECORATION,
R.string.decorator_grid_span_bounds_margin,
R.string.decorator_grid_span_bounds_margin_summary
)
)
listController.submitList(optionList)
}

Expand Down

0 comments on commit 2d467a6

Please sign in to comment.