📜 ⬆️ ⬇️

Snake layout and "quantum" particles in Android applications (Part 2)



It's time to talk about the promised "quantum" particles. Kuantum allows you to reactively change the state of the UI. Vue inspired me to create this library. Immediately show the library in battle.

Practice


Part 1: "Quantum" bunch of particles

We continue to modify the application from the previous post. Now we add the ability to add / remove dictionary elements and change their values.
')
Add the following lines to build.gradle (app level)
implementation 'com.github.Brotandos:koatl:v0.1.3' implementation 'com.github.Brotandos:kuantum:v0.0.7' 

Change Models.kt
 import com.brotandos.kuantumlib.ListKuantum import com.brotandos.kuantumlib.TextKuantum //  'q'  ""  data class Dictionary(var qTitle: TextKuantum, val qItems: ListKuantum<DictionaryItem>) data class DictionaryItem(val qKey: TextKuantum, val qValue: TextKuantum) 

The most fun, DictionaryFragment.kt:

 import android.graphics.Color import android.view.View import android.widget.Button import android.widget.ImageView import com.brotandos.koatlib.* import com.brotandos.kuantumlib.ListKuantum import com.brotandos.kuantumlib.TextKuantum import com.brotandos.kuantumlib.of import org.jetbrains.anko.imageResource import org.jetbrains.anko.matchParent import org.jetbrains.anko.scrollView class DictionaryFragment: KoatlFragment(), View.OnClickListener { //  'q' ,   ""  private val qDictionary: Dictionary private val icCollapsed = R.drawable.ic_collapsed private val icExpanded = R.drawable.ic_expanded init { val list = mutableListOf<DictionaryItem>() for (i in 0 until 7) list += DictionaryItem(TextKuantum("key-$i"), TextKuantum("value-$i")) qDictionary = Dictionary(TextKuantum("First dictionary"), ListKuantum(list)) } override fun markup() = KUI { scrollView { vVertical { vFrame(bg(R.color.colorPrimary)) { //  "of" - infix . //   view-    vLabel(10f.sp, text(Color.WHITE)).lp(submissive, g5) of qDictionary.qTitle }.lparams(matchParent, 50.dp) //        TextKuantum //     .   -  vText(line, "Set dictionary name"()).lp(row) of qDictionary.qTitle //  String.invoke  placeholder-  EditText //  recyclerView         vList(linear).lp(row, m(5.dp)) of qDictionary.qItems.vForEach { item, _ -> vVertical(bgLayerCard, mw) { vLinear(content456) { //  / vImage(icCollapsed, tag(item), this@DictionaryFragment()).lp(row, 5f()) //    vText(line).lp(row, 1f()) of item.qKey //    vImage(R.drawable.ic_remove, tag(item), this@DictionaryFragment()).lp(row, 5f()) }.lp(dominant, 1f()) //    vText(text(G.Color.PRIMARY), hidden).lp(dominant, 1f(), m(2.dp)) of item.qValue }.llp(row, m(2.dp)) } vBtn("Add item to qDictionary", this@DictionaryFragment()) }} } override fun onClick(v: View?) { //      . //       ... // ...   view-    //  ,    ... // ...   view,     fun ListKuantum<DictionaryItem>.getItemValueView(itemAsViewTag: Any) = find { it == itemAsViewTag }!!.qValue.firstView if (v is Button) { //      qDictionary.qItems.add(DictionaryItem(TextKuantum(), TextKuantum())) } else when ((v as ImageView).resourceId) { //   icCollapsed -> { v.imageResource = icExpanded qDictionary.qItems.getItemValueView(v.tag).visible() } //   icExpanded -> { v.imageResource = icCollapsed qDictionary.qItems.getItemValueView(v.tag).hidden() } //   R.drawable.ic_remove -> qDictionary.qItems.removeFirstWhere { it == v.tag } } } } 

Result


Github code

Part 2: Filter and BooleanKuantum

Now add the ability to search in the dictionary.

Add a search icon

Modify DictionaryFragment.kt (I have marked the places for changes with comments)

 import android.graphics.Color import android.support.v7.widget.RecyclerView import android.view.View import android.widget.Button import android.widget.ImageView import com.brotandos.koatlib.* import com.brotandos.kuantumlib.* import org.jetbrains.anko.imageResource import org.jetbrains.anko.matchParent import org.jetbrains.anko.scrollView class DictionaryFragment: KoatlFragment(), View.OnClickListener { private val icCollapsed = R.drawable.ic_collapsed private val icExpanded = R.drawable.ic_expanded private val qDictionary: Dictionary //   private val qFilter = TextKuantum() //     private val qFilterByKey = BooleanKuantum(true) //     private val qFilterByValue = BooleanKuantum(true) //  view-,    private lateinit var vList: RecyclerView init { val list = mutableListOf<DictionaryItem>() for (i in 0 until 7) list += DictionaryItem(TextKuantum("key-$i"), TextKuantum("value-$i")) qDictionary = Dictionary(TextKuantum("First dictionary"), ListKuantum(list)) } override fun markup() = KUI { scrollView { vVertical { vFrame(bg(R.color.colorPrimary)) { vLabel(10f.sp, text(Color.WHITE)).lp(submissive, g5) of qDictionary.qTitle }.lparams(matchParent, 50.dp) //   vText(line, "Search"(), icLeft(R.drawable.ic_search), pIcon(3.dp)).lp(row) of qFilter { //        if (it.isEmpty()) { qDictionary.qItems.clearViewFilter() vList.scrollToPosition(0) } else filterDictionary(it) } vLinear(p(2.dp)) { //     vCheck("by key").lp(row, 1f()) of qFilterByKey { vList.requestLayout() if (it.not() && qFilterByValue.value.not()) { qFilterByKey becomes true qFilterByValue becomes true } filterDictionary(qFilter.value) } //     vCheck("by value").lp(row, 1f()) of qFilterByValue { vList.requestLayout() if (it.not() && qFilterByKey.value.not()) { qFilterByKey becomes true qFilterByValue becomes true } filterDictionary(qFilter.value) } }.lp(submissive, g258) vList = vList(linear).lp(row, m(5.dp)) of qDictionary.qItems.vForEach { item, _ -> vVertical(bgLayerCard, mw) { vLinear(content456) { vImage(icCollapsed, tag(item), this@DictionaryFragment()).lp(row, 5f()) vText(line).lp(row, 1f()) of item.qKey vImage(R.drawable.ic_remove, tag(item), this@DictionaryFragment()).lp(row, 5f()) }.lp(dominant, 1f()) vText(text(G.Color.PRIMARY), hidden).lp(dominant, 1f(), m(2.dp)) of item.qValue }.llp(row, m(2.dp)) } vBtn("Add item to dictionary", this@DictionaryFragment()).lp(row) }} } override fun onClick(v: View?) { fun ListKuantum<DictionaryItem>.getItemValueView(itemAsViewTag: Any) = find { it == itemAsViewTag }!!.qValue.firstView if (v is Button) { qDictionary.qItems.add(DictionaryItem(TextKuantum(), TextKuantum())) vList.scrollToPosition(qDictionary.qItems.lastIndex) } else when ((v as ImageView).resourceId) { icCollapsed -> { v.imageResource = icExpanded qDictionary.qItems.getItemValueView(v.tag).visible() } icExpanded -> { v.imageResource = icCollapsed qDictionary.qItems.getItemValueView(v.tag).hidden() } R.drawable.ic_remove -> qDictionary.qItems.removeFirstWhere { it == v.tag } } } //   private fun filterDictionary(filterWord: String) { qDictionary.qItems.filterView { if (qFilterByKey.value && qFilterByValue.value.not()) it.qKey.value.contains(filterWord) else if (qFilterByValue.value && qFilterByKey.value.not()) it.qValue.value.contains(filterWord) else it.qKey.value.contains(filterWord) || it.qValue.value.contains(filterWord) } } } 

Result


Commit code on github

Now we have a fragment of the dictionary with a filter. Everything fit less than 100 lines. No xml, adapters, findViewById and dances with textWatcher. And this is all in one file, no need to jump between layout and logic.

Next time I will show the download from the Internet and summarize, sign for the pros and cons that I know what risks await you.

Source: https://habr.com/ru/post/354650/


All Articles