2019-11-12 16:35:47 -06:00
|
|
|
package pl.szczodrzynski.edziennik.utils
|
|
|
|
|
|
|
|
import android.content.Context
|
|
|
|
import android.util.AttributeSet
|
|
|
|
import androidx.appcompat.widget.PopupMenu
|
|
|
|
import androidx.core.graphics.drawable.DrawableCompat
|
|
|
|
import com.google.android.material.textfield.TextInputEditText
|
|
|
|
import pl.szczodrzynski.edziennik.R
|
|
|
|
|
|
|
|
class TextInputDropDown : TextInputEditText {
|
|
|
|
constructor(context: Context) : super(context) {
|
|
|
|
create(context)
|
|
|
|
}
|
|
|
|
|
|
|
|
constructor(context: Context, attrs: AttributeSet) : super(context, attrs) {
|
|
|
|
create(context)
|
|
|
|
}
|
|
|
|
|
|
|
|
constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr) {
|
|
|
|
create(context)
|
|
|
|
}
|
|
|
|
|
|
|
|
var items = mutableListOf<Item>()
|
|
|
|
private var onChangeListener: ((item: Item) -> Boolean)? = null
|
|
|
|
|
|
|
|
var selected: Item? = null
|
|
|
|
val selectedId
|
|
|
|
get() = selected?.id
|
|
|
|
|
|
|
|
fun updateText() {
|
|
|
|
setText(selected?.displayText ?: selected?.text)
|
|
|
|
}
|
|
|
|
|
|
|
|
fun create(context: Context) {
|
|
|
|
val drawable = context.resources.getDrawable(R.drawable.dropdown_arrow)
|
|
|
|
val wrappedDrawable = DrawableCompat.wrap(drawable)
|
|
|
|
DrawableCompat.setTint(wrappedDrawable, Themes.getPrimaryTextColor(context))
|
|
|
|
|
|
|
|
setCompoundDrawablesWithIntrinsicBounds(null, null, wrappedDrawable, null)
|
|
|
|
isFocusableInTouchMode = false
|
|
|
|
isCursorVisible = false
|
|
|
|
isLongClickable = false
|
|
|
|
maxLines = 1
|
|
|
|
inputType = 0
|
|
|
|
keyListener = null
|
|
|
|
setOnFocusChangeListener { v, hasFocus ->
|
|
|
|
if (!hasFocus) {
|
|
|
|
v.isFocusableInTouchMode = false
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
setOnClickListener {
|
|
|
|
isFocusableInTouchMode = true
|
|
|
|
requestFocus()
|
|
|
|
val popup = PopupMenu(context, this)
|
|
|
|
|
|
|
|
items.forEachIndexed { index, item ->
|
|
|
|
popup.menu.add(0, item.id.toInt(), index, item.text)
|
|
|
|
}
|
|
|
|
|
|
|
|
popup.setOnMenuItemClickListener { menuItem ->
|
|
|
|
val item = items[menuItem.order]
|
|
|
|
if (onChangeListener?.invoke(item) != false) {
|
|
|
|
select(item)
|
|
|
|
}
|
|
|
|
clearFocus()
|
|
|
|
true
|
|
|
|
}
|
|
|
|
|
|
|
|
popup.setOnDismissListener {
|
|
|
|
clearFocus()
|
|
|
|
}
|
|
|
|
|
|
|
|
popup.show()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-11-20 14:13:43 -06:00
|
|
|
fun select(item: Item): Item? {
|
2019-11-12 16:35:47 -06:00
|
|
|
selected = item
|
|
|
|
updateText()
|
2019-12-13 15:07:42 -06:00
|
|
|
error = null
|
2019-11-20 14:13:43 -06:00
|
|
|
return item
|
2019-11-12 16:35:47 -06:00
|
|
|
}
|
|
|
|
|
2019-11-20 14:13:43 -06:00
|
|
|
fun select(id: Long?): Item? {
|
|
|
|
return items.singleOrNull { it.id == id }?.let { select(it) }
|
2019-11-12 16:35:47 -06:00
|
|
|
}
|
|
|
|
|
2019-11-20 14:13:43 -06:00
|
|
|
fun select(tag: Any?): Item? {
|
|
|
|
return items.singleOrNull { it.tag == tag }?.let { select(it) }
|
2019-11-12 16:35:47 -06:00
|
|
|
}
|
|
|
|
|
2019-11-20 14:13:43 -06:00
|
|
|
fun select(index: Int): Item? {
|
|
|
|
return items.getOrNull(index)?.let { select(it) }
|
2019-11-12 16:35:47 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
fun deselect(): TextInputDropDown {
|
|
|
|
selected = null
|
|
|
|
text = null
|
|
|
|
return this
|
|
|
|
}
|
|
|
|
|
|
|
|
fun clear(): TextInputDropDown {
|
|
|
|
items.clear()
|
|
|
|
return this
|
|
|
|
}
|
|
|
|
|
|
|
|
fun append(items: List<Item>): TextInputDropDown {
|
|
|
|
this.items.addAll(items)
|
|
|
|
return this
|
|
|
|
}
|
|
|
|
|
|
|
|
fun prepend(items: List<Item>): TextInputDropDown{
|
|
|
|
this.items.addAll(0, items)
|
|
|
|
return this
|
|
|
|
}
|
|
|
|
|
|
|
|
operator fun plusAssign(items: Item) {
|
|
|
|
this.items.add(items)
|
|
|
|
}
|
|
|
|
operator fun plusAssign(items: List<Item>) {
|
|
|
|
this.items.addAll(items)
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Set the listener called when other item is selected.
|
|
|
|
*
|
|
|
|
* The listener should return true to allow the item to be selected, false otherwise.
|
|
|
|
*/
|
|
|
|
fun setOnChangeListener(onChangeListener: ((item: Item) -> Boolean)? = null): TextInputDropDown {
|
|
|
|
this.onChangeListener = onChangeListener
|
|
|
|
return this
|
|
|
|
}
|
|
|
|
|
|
|
|
override fun setOnClickListener(onClickListener: OnClickListener?) {
|
|
|
|
super.setOnClickListener { v ->
|
|
|
|
isFocusableInTouchMode = true
|
|
|
|
requestFocus()
|
|
|
|
onClickListener!!.onClick(v)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
class Item(val id: Long, val text: CharSequence, val displayText: CharSequence? = null, val tag: Any? = null)
|
|
|
|
}
|