Skip to content

Instantly share code, notes, and snippets.

@aiya000
Last active February 18, 2019 05:58
Show Gist options
  • Save aiya000/85a4b495e4216544fddf44c1b2c3159b to your computer and use it in GitHub Desktop.
Save aiya000/85a4b495e4216544fddf44c1b2c3159b to your computer and use it in GitHub Desktop.
Make an adapter easily than SimpleExpandableListAdapter
/**
* SimpleExpandableListAdapterのコンストラクタが受け取る引数が
* 何を言っているのか全然わからないので、
* 自然な形のやつ。
*
* @param Child CShowによって表示可能な子
* @param clever リストアップされる親と子の木
* @param CShow 子を表示する方法
*/
class BasicDataExpandableListAdapter<Child>(
CShow: Show<Child>,
context: Context,
clever: Map<String, List<Child>>,
groupLayout: Int,
groupTo: List<Int>,
childLayout: Int,
childTo: List<Int>
) : SimpleExpandableListAdapter(
context,
takeOnlyGroupName(clever),
groupLayout,
arrayOf(uniqueGroupKey),
groupTo.toIntArray(),
jsonize(CShow, clever),
childLayout,
arrayOf(uniqueChildKey, uniqueGroupKey),
childTo.toIntArray()
)
private const val uniqueGroupKey = "very-very-uniqueness-group-key"
private const val uniqueChildKey = "very-very-uniqueness-child-key"
const val uniqueInvisibleKey = "very-very-uniqueness-invisible-data-key"
private fun <Child> takeOnlyGroupName(clever: Map<String, List<Child>>): List<Map<String, String>> =
clever.toList().map { (parent, _) ->
mapOf(uniqueGroupKey to parent)
}
/**
* ```
* >>> val clever = mapOf(
* "x" to listOf("x-1", "x-2"),
* "y" to listOf("y-1")
* )
* listOf(
* listOf(
* mapOf(uniqueGroupKey to "x", uniqueChildKey to "x-1"),
* mapOf(uniqueGroupKey to "x", uniqueChildKey to "x-2")
* ),
* listOf(
* mapOf(uniqueGroupKey to "y", uniqueChildKey to "y-1")
* )
* )
* ```
*/
private fun <Child> jsonize(
CShow: Show<Child>,
clever: Map<String, List<Child>>
): List<List<Map<String, Any?>>> {
val jsonlike: List<List<Pair<String, Child>>> =
clever.map { (parent, children) ->
children.map { child ->
parent to child
}
}
return jsonlike.map { pairs ->
pairs.map { (parent, child) ->
mapOf(
uniqueGroupKey to parent,
uniqueChildKey to CShow.show(child),
uniqueInvisibleKey to child
)
}
}
}
import android.content.Context
import android.widget.SimpleExpandableListAdapter
/**
* A basic adapter by a basic structure `Map<String, List<String>>`
*/
class BasicExpandableListAdapter(
context: Context,
clever: Map<String, List<String>>,
groupLayout: Int,
groupTo: List<Int>,
childLayout: Int,
childTo: List<Int>
) : SimpleExpandableListAdapter(
context,
takeOnlyGroupName(clever),
groupLayout,
arrayOf(uniqueGroupKey),
groupTo.toIntArray(),
jsonize(clever),
childLayout,
arrayOf(uniqueChildKey, uniqueGroupKey),
childTo.toIntArray()
)
private const val uniqueGroupKey = "very-very-uniqueness-group-key"
private const val uniqueChildKey = "very-very-uniqueness-child-key"
private fun takeOnlyGroupName(clever: Map<String, List<String>>): List<Map<String, String>> =
clever.toList().map { (parent, _) ->
mapOf(uniqueGroupKey to parent)
}
/**
* ```
* >>> val clever = mapOf(
* "x" to listOf("x-1", "x-2"),
* "y" to listOf("y-1")
* )
* listOf(
* listOf(
* mapOf("very-very-uniqueness-group-key" to "x", "very-very-uniqueness-child-key" to "x-1"),
* mapOf("very-very-uniqueness-group-key" to "x", "very-very-uniqueness-child-key" to "x-2")
* ),
* listOf(
* mapOf("very-very-uniqueness-group-key" to "y", "very-very-uniqueness-child-key" to "y-1")
* )
* )
* ```
*/
private fun jsonize(clever: Map<String, List<String>>): List<List<Map<String, String>>> {
val jsonlike: List<List<Pair<String, String>>> =
clever.map { (parent, children) ->
children.map { child ->
parent to child
}
}
return jsonlike.map { pairs ->
pairs.map { (parent, child) ->
mapOf(uniqueGroupKey to parent, uniqueChildKey to child)
}
}
}
/**
* 表示可能なデータ。
* toStringを使いたくないときに使う。
*/
interface Show<T> {
fun show(self: T): String
}
@aiya000
Copy link
Author

aiya000 commented Feb 18, 2019

In my opinion, SimpleExpandableListView is a little crazy for a basic usage.

This allows to

val this: Context = aContext
val outline =
    mapOf(
        "x" to listOf("x-1", "x-2"),
        "y" to listOf("y-1")
    )

BasicExpandableListAdapter(
    this,
    outline,
    android.R.layout.simple_expandable_list_item_1,
    listOf(android.R.id.text1),
    android.R.layout.simple_expandable_list_item_2,
    listOf(android.R.id.text1, android.R.id.text2)
)

@aiya000
Copy link
Author

aiya000 commented Feb 18, 2019

BasicDataExpandableListAdapter added.
Here is the example 👇

val context: Context = aContext
val view: ExpandableListView = anExpandableListView

data class Foo(val label: String, val value: Int) {
    companion object {
        val show = object : Show<Foo> {
            override fun show(self: Foo) = self.label
        }
    }
}

val outline =
    mapOf(
        "x" to listOf(
            Foo("x-1", 10),
            Foo("x-2", 20),
        ),
        "y" to listOf(
            Foo("y-1", 100)
        )
    )

BasicExpandableListAdapter(
    Foo.show,
    context,
    outline,
    android.R.layout.simple_expandable_list_item_1,
    listOf(android.R.id.text1),
    android.R.layout.simple_expandable_list_item_2,
    listOf(android.R.id.text1, android.R.id.text2)
)

view.setOnChildClickListener { parent, _, groupPos, childPos, _ ->
    println(
        parent.expandableListAdapter.getChild(groupPos, childPos)
    )
    true
}
/* on "x-1" clicked

I/System.out:
 {
    very-very-uniqueness-group-key=x
    very-very-uniqueness-child-key="x-1"
    very-very-uniqueness-invisible-data-key=Foo(label=x-1, value=10
}

*/

or simply, you can use toString instead of Show<T>.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment