Skip to content

Commit

Permalink
change to adapter
Browse files Browse the repository at this point in the history
  • Loading branch information
toni-kustiana committed Nov 19, 2021
1 parent 270c3a8 commit 5265b43
Show file tree
Hide file tree
Showing 11 changed files with 189 additions and 103 deletions.
8 changes: 4 additions & 4 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@ plugins {
}

android {
compileSdk 30
compileSdk 31

defaultConfig {
applicationId "id.co.edtslib.slidingchipsview.example"
minSdk 21
targetSdk 30
targetSdk 31
versionCode 1
versionName "1.0"

Expand All @@ -33,10 +33,10 @@ android {

dependencies {

implementation 'androidx.core:core-ktx:1.6.0'
implementation 'androidx.core:core-ktx:1.7.0'
implementation 'androidx.appcompat:appcompat:1.3.1'
implementation 'com.google.android.material:material:1.4.0'
implementation 'androidx.constraintlayout:constraintlayout:2.1.0'
implementation 'androidx.constraintlayout:constraintlayout:2.1.1'
implementation project(":slidingchipsview")
testImplementation 'junit:junit:4.+'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ class MainActivity : AppCompatActivity() {

val list = mutableListOf("Abah", "Hezbi", "Ade", "Robert", "Jovan", "Ucup")

val chips = findViewById<GroupChipsView<String>>(R.id.chips)
val chips = findViewById<SlidingChipsView<String>>(R.id.chips)
chips.delegate = object : SlidingChipsDelegate<String> {
override fun onSelected(item: String, position: Int) {
Toast.makeText(this@MainActivity, item, Toast.LENGTH_SHORT).show()
Expand Down
2 changes: 1 addition & 1 deletion app/src/main/res/layout/activity_main.xml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
android:background="@color/white"
tools:context=".MainActivity">

<id.co.edtslib.slidingchipsview.GroupChipsView
<id.co.edtslib.slidingchipsview.SlidingChipsView
android:orientation="vertical"
android:id="@+id/chips"
android:layout_width="wrap_content"
Expand Down
1 change: 1 addition & 0 deletions settings.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ dependencyResolutionManagement {
google()
mavenCentral()
jcenter() // Warning: this repository is going to shut down soon
maven { url 'https://jitpack.io' }
}
}
rootProject.name = "SlidingChipsView"
Expand Down
8 changes: 7 additions & 1 deletion slidingchipsview/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,11 @@ android {
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
android {
buildFeatures {
viewBinding true
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
Expand All @@ -51,9 +56,10 @@ android {

dependencies {

implementation 'androidx.core:core-ktx:1.6.0'
implementation 'androidx.core:core-ktx:1.7.0'
implementation 'androidx.appcompat:appcompat:1.3.1'
implementation 'com.google.android.material:material:1.4.0'
implementation 'com.github.edtslib:baserecyclerview:1.1.2'
testImplementation 'junit:junit:4.+'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package id.co.edtslib.slidingchipsview

import android.view.LayoutInflater
import android.view.ViewGroup
import id.co.edtslib.baserecyclerview.BaseRecyclerViewAdapter
import id.co.edtslib.slidingchipsview.databinding.AdapterChipBinding

class ChipAdapter<T>(private val textColor: Int, private val textPadding: Float,
private val chipBackgroundColor: Int, private val strokeColor: Int,
private val textStyle: Int): BaseRecyclerViewAdapter<AdapterChipBinding, T>() {
override val bindingInflater: (LayoutInflater, ViewGroup?, Boolean) -> AdapterChipBinding
get() = AdapterChipBinding::inflate

override fun createHolder() = ChipHolder<T>(binding, textColor, textPadding,
chipBackgroundColor, strokeColor, textStyle)

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package id.co.edtslib.slidingchipsview

import androidx.core.content.ContextCompat
import androidx.core.widget.TextViewCompat
import id.co.edtslib.baserecyclerview.BaseRecyclerViewAdapterDelegate
import id.co.edtslib.baserecyclerview.BaseViewHolder
import id.co.edtslib.slidingchipsview.databinding.AdapterChipBinding

class ChipHolder<T>(private val binding: AdapterChipBinding, textColor: Int,
textPadding: Float, chipBackgroundColor: Int, strokeColor: Int, textStyle: Int):
BaseViewHolder<T>(binding) {
init {
binding.chip.setTextColor(
ContextCompat.getColorStateList(
itemView.context,
textColor
)
)

binding.chip.chipStartPadding = textPadding
binding.chip.chipEndPadding = textPadding

binding.chip.chipBackgroundColor = ContextCompat.getColorStateList(
itemView.context,
chipBackgroundColor
)

if (strokeColor != 0) {
binding.chip.chipStrokeColor = ContextCompat.getColorStateList(
itemView.context,
strokeColor
)
binding.chip.chipStrokeWidth = itemView.context.resources.getDimensionPixelSize(R.dimen.chip_dimen_1dp).toFloat()
}

if (textStyle > 0) {
TextViewCompat.setTextAppearance(binding.chip, textStyle)
}

}
override fun setData(
list: MutableList<T>,
position: Int,
delegate: BaseRecyclerViewAdapterDelegate<T>?
) {
val item = list[position]
if (item is RecyclerData<*>) {
binding.chip.text = item.data.toString()
itemView.isSelected = item.selected

binding.chip.setOnClickListener {
delegate?.onClick(item, position, this)
}

}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package id.co.edtslib.slidingchipsview

data class RecyclerData<T>(
val data: T,
var selected: Boolean
)
Original file line number Diff line number Diff line change
@@ -1,122 +1,99 @@
package id.co.edtslib.slidingchipsview

import android.annotation.SuppressLint
import android.content.Context
import android.graphics.Rect
import android.util.AttributeSet
import android.view.ViewGroup
import android.widget.HorizontalScrollView
import androidx.core.content.ContextCompat
import androidx.core.view.get
import androidx.core.widget.TextViewCompat
import com.google.android.material.chip.Chip
import com.google.android.material.chip.ChipGroup

class SlidingChipsView<T> : HorizontalScrollView {
var delegate: SlidingChipsDelegate<T>? = null
import android.view.View
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import id.co.edtslib.baserecyclerview.BaseRecyclerViewAdapterDelegate
import id.co.edtslib.baserecyclerview.BaseViewHolder

class SlidingChipsView<T> : RecyclerView {
class ItemDecoration(private val margin: Int): RecyclerView.ItemDecoration() {
override fun getItemOffsets(
outRect: Rect,
view: View,
parent: RecyclerView,
state: State
) {
super.getItemOffsets(outRect, view, parent, state)

val position = parent.getChildAdapterPosition(view)
outRect.left = if (position == 0) 0 else margin
}
}

private lateinit var chipGroup: ChipGroup
private var textColor = R.color.chip_text_color
private var strokeColor = 0
private var chipBackgroundColor = R.color.chip_background_color
private var textPadding = 0f
private var textStyle = 0
private var _adapter: ChipAdapter<RecyclerData<T>>? = null

var items: MutableList<T> = mutableListOf()
var delegate: SlidingChipsDelegate<T>? = null

private var prevSelectedIndex = -1
var selectionIndex = 0
set(value) {
field = value

chipGroup.removeAllViews()
for ((i, item) in items.withIndex()) {

val chip = Chip(context)
chip.text = item.toString()

if (textStyle > 0) {
TextViewCompat.setTextAppearance(chip, textStyle)
}


chip.tag = item
chip.setTextColor(
ContextCompat.getColorStateList(
context,
textColor
)
)
chip.chipStartPadding = textPadding
chip.chipEndPadding = textPadding

chip.chipBackgroundColor = ContextCompat.getColorStateList(
context,
chipBackgroundColor
)
if (strokeColor != 0) {
chip.chipStrokeColor = ContextCompat.getColorStateList(
context,
strokeColor
)
chip.chipStrokeWidth = context.resources.getDimensionPixelSize(R.dimen.chip_dimen_1dp).toFloat()
}
chip.setOnClickListener {
repeat (chipGroup.childCount) {idx ->
chipGroup[idx].isSelected = false
}
chip.isSelected = true

val left = it.left - scrollX
val space = resources.getDimensionPixelSize(R.dimen.chip_dimen_16dp)

// if partial show on right
if (it.width + left + space > width) {
val diff = width - it.width - left - space
val scrollX = scrollX - diff
scrollTo(scrollX, 0)
}

delegate?.onSelected(item, i)
}

chip.isSelected = selectionIndex == i

chipGroup.addView(chip)
if (prevSelectedIndex >= 0) {
val item = _adapter?.list?.get(prevSelectedIndex)
item?.selected = false

_adapter?.notifyItemChanged(prevSelectedIndex)
}

val item = _adapter?.list?.get(value)
item?.selected = true

_adapter?.notifyItemChanged(value)
prevSelectedIndex = value

delegate?.onSelected(item?.data!!, value)

val linearLayoutManager = layoutManager as LinearLayoutManager
val last = linearLayoutManager.findLastCompletelyVisibleItemPosition()
if (value > last) {
linearLayoutManager.scrollToPosition(value)
}
}

var selectionIndex = 0
var items: MutableList<T> = mutableListOf()
@SuppressLint("NotifyDataSetChanged")
set(value) {
field = value

repeat(chipGroup.childCount) {
chipGroup.getChildAt(it).isSelected = it == value
val list = mutableListOf<RecyclerData<T>>()
for (item in items) {
list.add(RecyclerData(item, false))
}

_adapter?.list = list
_adapter?.notifyDataSetChanged()
}

constructor(context: Context?) : super(context) {
constructor(context: Context) : super(context) {
init(null)
}
constructor(context: Context?, attrs: AttributeSet?) : super(context, attrs) {
constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) {
init(attrs)
}
constructor(context: Context?, attrs: AttributeSet?, defStyleAttr: Int) : super(
constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(
context,
attrs,
defStyleAttr
) {
init(attrs)
}

constructor(
context: Context?,
attrs: AttributeSet?,
defStyleAttr: Int,
defStyleRes: Int
) : super(context, attrs, defStyleAttr, defStyleRes) {
init(attrs)
}

private fun init(attrs: AttributeSet?) {
isVerticalScrollBarEnabled = false
isHorizontalScrollBarEnabled = false

var textColor = R.color.chip_text_color
var textPadding = resources.getDimensionPixelSize(R.dimen.chip_dimen_20dp).toFloat()
var chipBackgroundColor = R.color.chip_background_color
var strokeColor = 0
var textStyle = 0

if (attrs != null) {
val a = context.theme.obtainStyledAttributes(
attrs,
Expand All @@ -127,6 +104,8 @@ class SlidingChipsView<T> : HorizontalScrollView {
val startEndSpace = a.getDimension(R.styleable.SlidingChipsView_slideChipMargin,
resources.getDimensionPixelSize(R.dimen.chip_dimen_16dp).toFloat())

setPadding(startEndSpace.toInt(), 0, startEndSpace.toInt(), 0)

textColor = a.getResourceId(R.styleable.SlidingChipsView_slideChipTextColor,
R.color.chip_text_color)

Expand All @@ -141,20 +120,26 @@ class SlidingChipsView<T> : HorizontalScrollView {

textStyle = a.getResourceId(R.styleable.SlidingChipsView_slideChipTextStyle, 0)

chipGroup = ChipGroup(context)
addView(chipGroup)

chipGroup.isSingleLine = true
chipGroup.isSingleSelection = true
chipGroup.setPadding(startEndSpace.toInt(), 0, startEndSpace.toInt(), 0)
a.recycle()
}

val layoutParams = chipGroup.layoutParams
layoutParams.width = ViewGroup.LayoutParams.WRAP_CONTENT
layoutParams.height = ViewGroup.LayoutParams.WRAP_CONTENT
clipToPadding = false
layoutManager = LinearLayoutManager(context, HORIZONTAL, false)

chipGroup.layoutParams = layoutParams
addItemDecoration(ItemDecoration(context.resources.getDimensionPixelSize(R.dimen.chip_dimen_8dp)))

a.recycle()
_adapter = ChipAdapter<RecyclerData<T>>(textColor, textPadding, chipBackgroundColor, strokeColor,
textStyle)
_adapter?.delegate = object : BaseRecyclerViewAdapterDelegate<RecyclerData<T>> {
override fun onClick(t: RecyclerData<T>, position: Int, holder: BaseViewHolder<RecyclerData<T>>?) {
selectionIndex = position
}

override fun onDraw(t: RecyclerData<T>, position: Int) {
}
}

adapter = _adapter
}
}
Loading

0 comments on commit 5265b43

Please sign in to comment.