From 54a93413af7a03bf9a8074dfa23ee3b5b2bc2afc Mon Sep 17 00:00:00 2001 From: Gideon Okuro Date: Wed, 6 Mar 2024 19:40:33 +0300 Subject: [PATCH] courses: enable collections view (fixes #3195) (#3196) Co-authored-by: dogi --- app/build.gradle | 4 +- .../org/ole/planet/myplanet/model/RealmTag.kt | 21 ++- .../ui/library/CollectionsFragment.kt | 126 +++++++++--------- .../ui/library/TagExpandableAdapter.kt | 116 ++++++++-------- 4 files changed, 123 insertions(+), 144 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 2e85f2fed3..aaa9b7bbf9 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -9,8 +9,8 @@ android { applicationId "org.ole.planet.myplanet" minSdkVersion 21 targetSdkVersion 34 - versionCode 1394 - versionName "0.13.94" + versionCode 1395 + versionName "0.13.95" ndkVersion '21.3.6528147' testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" vectorDrawables.useSupportLibrary = true diff --git a/app/src/main/java/org/ole/planet/myplanet/model/RealmTag.kt b/app/src/main/java/org/ole/planet/myplanet/model/RealmTag.kt index 8b3c3dbcee..3a0ccb5e2b 100644 --- a/app/src/main/java/org/ole/planet/myplanet/model/RealmTag.kt +++ b/app/src/main/java/org/ole/planet/myplanet/model/RealmTag.kt @@ -33,9 +33,9 @@ open class RealmTag : RealmObject() { private fun setAttachedTo(attachedTo: JsonArray) { this.attachedTo = RealmList() for (i in 0 until attachedTo.size()) { - this.attachedTo!!.add(JsonUtils.getString(attachedTo, i)) + this.attachedTo?.add(JsonUtils.getString(attachedTo, i)) } - isAttached = this.attachedTo!!.size > 0 + isAttached = (this.attachedTo?.size ?: 0) > 0 } override fun toString(): String { @@ -56,6 +56,7 @@ open class RealmTag : RealmObject() { return map } + @JvmStatic fun insert(mRealm: Realm, act: JsonObject) { var tag = mRealm.where(RealmTag::class.java).equalTo("_id", JsonUtils.getString("_id", act)).findFirst() @@ -73,23 +74,17 @@ open class RealmTag : RealmObject() { if (el != null && el.isJsonArray) { tag.setAttachedTo(JsonUtils.getJsonArray("attachedTo", act)) } else { - tag.attachedTo!!.add(JsonUtils.getString("attachedTo", act)) + tag.attachedTo?.add(JsonUtils.getString("attachedTo", act)) } - tag.isAttached = tag.attachedTo!!.size > 0 + tag.isAttached = (tag.attachedTo?.size ?: 0) > 0 } - - } @JvmStatic - fun getTagsArray(list: List?): JsonArray { + fun getTagsArray(list: List): JsonArray { val array = JsonArray() - if (list != null) { - for (t in list) { - if (t != null) { - array.add(t._id) - } - } + for (t in list) { + array.add(t._id) } return array } diff --git a/app/src/main/java/org/ole/planet/myplanet/ui/library/CollectionsFragment.kt b/app/src/main/java/org/ole/planet/myplanet/ui/library/CollectionsFragment.kt index a8497d8ff6..3d25a9a1ac 100644 --- a/app/src/main/java/org/ole/planet/myplanet/ui/library/CollectionsFragment.kt +++ b/app/src/main/java/org/ole/planet/myplanet/ui/library/CollectionsFragment.kt @@ -1,6 +1,5 @@ package org.ole.planet.myplanet.ui.library -import android.R import android.os.Bundle import android.text.Editable import android.text.TextWatcher @@ -9,43 +8,39 @@ import android.view.View import android.view.ViewGroup import android.widget.CompoundButton import androidx.fragment.app.DialogFragment -import io.realm.Realm -import io.realm.RealmResults import org.ole.planet.myplanet.MainApplication import org.ole.planet.myplanet.callback.TagClickListener import org.ole.planet.myplanet.databinding.FragmentCollectionsBinding import org.ole.planet.myplanet.datamanager.DatabaseService import org.ole.planet.myplanet.model.RealmTag -import org.ole.planet.myplanet.ui.library.TagExpandableAdapter.OnClickTagItem -import org.ole.planet.myplanet.utilities.KeyboardUtils.hideSoftKeyboard -import java.util.Locale +import org.ole.planet.myplanet.utilities.KeyboardUtils +import java.util.* +import kotlin.collections.ArrayList +import kotlin.collections.HashMap +import kotlin.collections.List +import io.realm.Realm -class CollectionsFragment : DialogFragment(), OnClickTagItem, CompoundButton.OnCheckedChangeListener { - private var fragmentCollectionsBinding: FragmentCollectionsBinding? = null - var mRealm: Realm? = null - var list: List? = null - private var filteredList: MutableList? = null - var adapter: TagExpandableAdapter? = null +class CollectionsFragment : DialogFragment(), TagExpandableAdapter.OnClickTagItem, CompoundButton.OnCheckedChangeListener { + private lateinit var fragmentCollectionsBinding: FragmentCollectionsBinding + private lateinit var mRealm: Realm + private lateinit var list: List + private var filteredList: ArrayList = ArrayList() + private lateinit var adapter: TagExpandableAdapter private var dbType: String? = null - private var tagListener: TagClickListener? = null - private var selectedItemsList: MutableList = ArrayList() - - fun setListener(listener: TagClickListener?) { - this.tagListener = listener - } + private var listener: TagClickListener? = null + private var selectedItemsList: ArrayList = ArrayList() override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - setStyle(STYLE_NO_TITLE, R.style.Theme_Holo_Light_Dialog_NoActionBar_MinWidth) - if (arguments != null) dbType = requireArguments().getString("dbType") + setStyle(STYLE_NO_TITLE, android.R.style.Theme_Holo_Light_Dialog_NoActionBar_MinWidth) + dbType = arguments?.getString("dbType") } override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View { fragmentCollectionsBinding = FragmentCollectionsBinding.inflate(inflater, container, false) mRealm = DatabaseService(requireActivity()).realmInstance - filteredList = ArrayList() - hideSoftKeyboard(requireActivity()) - return fragmentCollectionsBinding!!.root + KeyboardUtils.hideSoftKeyboard(requireActivity()) + return fragmentCollectionsBinding.root } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { @@ -55,57 +50,53 @@ class CollectionsFragment : DialogFragment(), OnClickTagItem, CompoundButton.OnC } private fun setListeners() { - fragmentCollectionsBinding!!.btnOk.setOnClickListener { - if (tagListener != null) { - tagListener!!.onOkClicked(selectedItemsList) - dismiss() - } + fragmentCollectionsBinding.btnOk.setOnClickListener { + listener?.onOkClicked(selectedItemsList) + dismiss() } - fragmentCollectionsBinding!!.etFilter.addTextChangedListener(object : TextWatcher { - override fun beforeTextChanged(charSequence: CharSequence, i: Int, i1: Int, i2: Int) {} - override fun onTextChanged(charSequence: CharSequence, i: Int, i1: Int, i2: Int) { - filterTags(charSequence.toString()) + fragmentCollectionsBinding.etFilter.addTextChangedListener(object : TextWatcher { + override fun beforeTextChanged(charSequence: CharSequence?, start: Int, count: Int, after: Int) {} + override fun onTextChanged(charSequence: CharSequence?, start: Int, before: Int, count: Int) { + charSequence?.let { filterTags(it.toString()) } } - - override fun afterTextChanged(editable: Editable) {} + override fun afterTextChanged(editable: Editable?) {} }) } private fun filterTags(charSequence: String) { - filteredList!!.clear() + filteredList.clear() if (charSequence.isEmpty()) { - adapter!!.setTagList(list!!) + adapter.setTagList(list) return } - for (t in list!!) { - if (t.name!!.lowercase(Locale.getDefault()).contains(charSequence.lowercase(Locale.getDefault()))) { - filteredList!!.add(t) + list.forEach { t -> + if (t.name?.lowercase(Locale.ROOT)?.contains(charSequence.lowercase(Locale.ROOT)) == true) { + filteredList.add(t) } } - adapter!!.setTagList(filteredList!!) + adapter.setTagList(filteredList) } private fun setListAdapter() { - list = mRealm!!.where(RealmTag::class.java).equalTo("db", dbType).isNotEmpty("name").equalTo("isAttached", false).findAll() - selectedItemsList = recentList - val allTags: List = mRealm!!.where(RealmTag::class.java).findAll() - val childMap = HashMap>() - for (t in allTags) { - createChildMap(childMap, t) - } - fragmentCollectionsBinding!!.listTags.setGroupIndicator(null) - adapter = TagExpandableAdapter(list as RealmResults, childMap, selectedItemsList) - adapter!!.setSelectMultiple(true) - adapter!!.setClickListener(this) - fragmentCollectionsBinding!!.listTags.setAdapter(adapter) - fragmentCollectionsBinding!!.btnOk.visibility = View.VISIBLE + list = mRealm.where(RealmTag::class.java).equalTo("db", dbType).isNotEmpty("name").equalTo("isAttached", false).findAll() + + selectedItemsList = ArrayList(recentList) + val allTags = mRealm.where(RealmTag::class.java).findAll() + val childMap = HashMap>() + allTags.forEach { t -> createChildMap(childMap, t) } + fragmentCollectionsBinding.listTags.setGroupIndicator(null) + adapter = TagExpandableAdapter(list, childMap, selectedItemsList) + adapter.setSelectMultiple(true) + adapter.setClickListener(this) + fragmentCollectionsBinding.listTags.setAdapter(adapter) + fragmentCollectionsBinding.btnOk.visibility = View.VISIBLE } - private fun createChildMap(childMap: HashMap>, t: RealmTag) { - for (s in t.attachedTo!!) { - var l: MutableList = ArrayList() + private fun createChildMap(childMap: HashMap>, t: RealmTag) { + t.attachedTo?.forEach { s -> + val l: MutableList = ArrayList() if (childMap.containsKey(s)) { - l = childMap[s]!! + l.addAll(childMap[s]!!) } if (!l.contains(t)) l.add(t) childMap[s] = l @@ -113,7 +104,7 @@ class CollectionsFragment : DialogFragment(), OnClickTagItem, CompoundButton.OnC } override fun onTagClicked(tag: RealmTag) { - if (tagListener != null) tagListener!!.onTagSelected(tag) + listener?.onTagSelected(tag) dismiss() } @@ -127,15 +118,16 @@ class CollectionsFragment : DialogFragment(), OnClickTagItem, CompoundButton.OnC override fun onCheckedChanged(compoundButton: CompoundButton, b: Boolean) { MainApplication.isCollectionSwitchOn = b - adapter!!.setSelectMultiple(b) - adapter!!.setTagList(list!!) - fragmentCollectionsBinding!!.listTags.setAdapter(adapter) - fragmentCollectionsBinding!!.btnOk.visibility = if (b) View.VISIBLE else View.GONE + adapter.setSelectMultiple(b) + adapter.setTagList(list) + fragmentCollectionsBinding.listTags.setAdapter(adapter) + fragmentCollectionsBinding.btnOk.visibility = if (b) View.VISIBLE else View.GONE } companion object { - lateinit var recentList: MutableList - fun getInstance(l: MutableList, dbType: String?): CollectionsFragment { + private lateinit var recentList: MutableList + @JvmStatic + fun getInstance(l: MutableList, dbType: String): CollectionsFragment { recentList = l val f = CollectionsFragment() val b = Bundle() @@ -144,4 +136,8 @@ class CollectionsFragment : DialogFragment(), OnClickTagItem, CompoundButton.OnC return f } } -} + + fun setListener(listener: TagClickListener) { + this.listener = listener + } +} \ No newline at end of file diff --git a/app/src/main/java/org/ole/planet/myplanet/ui/library/TagExpandableAdapter.kt b/app/src/main/java/org/ole/planet/myplanet/ui/library/TagExpandableAdapter.kt index 75743cad72..2d4bddde20 100644 --- a/app/src/main/java/org/ole/planet/myplanet/ui/library/TagExpandableAdapter.kt +++ b/app/src/main/java/org/ole/planet/myplanet/ui/library/TagExpandableAdapter.kt @@ -5,21 +5,18 @@ import android.view.View import android.view.ViewGroup import android.widget.BaseExpandableListAdapter import android.widget.CheckBox -import android.widget.CompoundButton import androidx.appcompat.widget.AppCompatImageView import org.ole.planet.myplanet.R import org.ole.planet.myplanet.databinding.RowAdapterNavigationChildBinding import org.ole.planet.myplanet.databinding.RowAdapterNavigationParentBinding import org.ole.planet.myplanet.model.RealmTag +import java.util.* +import kotlin.collections.HashMap +import kotlin.collections.List -class TagExpandableAdapter(private var tagList: List, private val childMap: HashMap>, selectedItemsList: MutableList) : BaseExpandableListAdapter() { +class TagExpandableAdapter(private var tagList: List, private val childMap: HashMap>, private val selectedItemsList: ArrayList) : BaseExpandableListAdapter() { private var clickListener: OnClickTagItem? = null private var isSelectMultiple = false - private var selectedItemsList = ArrayList() - - init { - this.selectedItemsList = selectedItemsList as ArrayList - } fun setSelectMultiple(selectMultiple: Boolean) { isSelectMultiple = selectMultiple @@ -30,19 +27,15 @@ class TagExpandableAdapter(private var tagList: List, private val chil } override fun getChildrenCount(groupPosition: Int): Int { - return if (childMap.containsKey(tagList[groupPosition].id)) { - childMap[tagList[groupPosition].id]!!.size - } else 0 + return childMap[tagList[groupPosition].id]?.size ?: 0 } override fun getGroup(groupPosition: Int): Any { return tagList[groupPosition] } - override fun getChild(groupPosition: Int, childPosition: Int): RealmTag? { - return if (childMap.containsKey(tagList[groupPosition].id)) { - childMap[tagList[groupPosition].id]!![childPosition] - } else null + override fun getChild(groupPosition: Int, childPosition: Int): Any? { + return childMap[tagList[groupPosition].id]?.get(childPosition) } override fun getGroupId(groupPosition: Int): Long { @@ -57,83 +50,78 @@ class TagExpandableAdapter(private var tagList: List, private val chil return false } - override fun getGroupView(groupPosition: Int, isExpanded: Boolean, convertView: View, parent: ViewGroup): View { - var convertView: View? = convertView + override fun getGroupView(groupPosition: Int, isExpanded: Boolean, convertView: View?, parent: ViewGroup?): View { val headerTitle = tagList[groupPosition].name - val rowAdapterNavigationParentBinding: RowAdapterNavigationParentBinding + val binding: RowAdapterNavigationParentBinding + val view: View + if (convertView == null) { - rowAdapterNavigationParentBinding = RowAdapterNavigationParentBinding.inflate(LayoutInflater.from(parent.context), parent, false) - convertView = rowAdapterNavigationParentBinding.root - convertView.setTag(rowAdapterNavigationParentBinding) + binding = RowAdapterNavigationParentBinding.inflate(LayoutInflater.from(parent?.context), parent, false) + view = binding.root + view.tag = binding } else { - rowAdapterNavigationParentBinding = convertView.tag as RowAdapterNavigationParentBinding + binding = convertView.tag as RowAdapterNavigationParentBinding + view = convertView } - rowAdapterNavigationParentBinding.tvDrawerTitle1.text = headerTitle - createCheckbox(convertView, tagList[groupPosition]) - rowAdapterNavigationParentBinding.tvDrawerTitle.text = headerTitle + + binding.tvDrawerTitle1.text = headerTitle + createCheckbox(view, tagList[groupPosition]) + binding.tvDrawerTitle.text = headerTitle + if (!childMap.containsKey(tagList[groupPosition].id)) { - rowAdapterNavigationParentBinding.tvDrawerTitle1.visibility = View.VISIBLE - rowAdapterNavigationParentBinding.tvDrawerTitle.visibility = View.GONE - rowAdapterNavigationParentBinding.ivIndicators.visibility = View.GONE - rowAdapterNavigationParentBinding.tvDrawerTitle1.setOnClickListener { - clickListener!!.onTagClicked(tagList[groupPosition]) - } + binding.tvDrawerTitle1.visibility = View.VISIBLE + binding.tvDrawerTitle.visibility = View.GONE + binding.ivIndicators.visibility = View.GONE + binding.tvDrawerTitle1.setOnClickListener { clickListener?.onTagClicked(tagList[groupPosition]) } } else { - rowAdapterNavigationParentBinding.tvDrawerTitle.visibility = View.VISIBLE - rowAdapterNavigationParentBinding.tvDrawerTitle1.setOnClickListener(null) - rowAdapterNavigationParentBinding.tvDrawerTitle1.visibility = View.GONE - rowAdapterNavigationParentBinding.ivIndicators.visibility = View.VISIBLE - setExpandedIcon(isExpanded, rowAdapterNavigationParentBinding.ivIndicators) - rowAdapterNavigationParentBinding.tvDrawerTitle.setOnClickListener { - clickListener!!.onTagClicked(tagList[groupPosition]) - } + binding.tvDrawerTitle.visibility = View.VISIBLE + binding.tvDrawerTitle1.setOnClickListener(null) + binding.tvDrawerTitle1.visibility = View.GONE + binding.ivIndicators.visibility = View.VISIBLE + setExpandedIcon(isExpanded, binding.ivIndicators) + binding.tvDrawerTitle.setOnClickListener { clickListener?.onTagClicked(tagList[groupPosition]) } } - return convertView + + return view } private fun setExpandedIcon(isExpanded: Boolean, ivIndicator: AppCompatImageView) { - if (isExpanded) { - ivIndicator.setImageResource(R.drawable.ic_keyboard_arrow_up_black_24dp) - } else { - ivIndicator.setImageResource(R.drawable.ic_keyboard_arrow_down_black_24dp) - } + ivIndicator.setImageResource(if (isExpanded) R.drawable.ic_keyboard_arrow_up_black_24dp else R.drawable.ic_keyboard_arrow_down_black_24dp) } private fun createCheckbox(convertView: View, tag: RealmTag) { val checkBox = convertView.findViewById(R.id.checkbox) checkBox.visibility = if (isSelectMultiple) View.VISIBLE else View.GONE checkBox.isChecked = selectedItemsList.contains(tag) - checkBox.setOnCheckedChangeListener { _: CompoundButton?, _: Boolean -> - clickListener!!.onCheckboxTagSelected(tag) - } + checkBox.setOnCheckedChangeListener { _, _ -> clickListener?.onCheckboxTagSelected(tag) } } - override fun getChildView(groupPosition: Int, childPosition: Int, isLastChild: Boolean, convertView: View, parent: ViewGroup): View { - var convertView: View? = convertView + override fun getChildView(groupPosition: Int, childPosition: Int, isLastChild: Boolean, convertView: View?, parent: ViewGroup?): View { val tag = getChild(groupPosition, childPosition) as RealmTag - val rowAdapterNavigationChildBinding: RowAdapterNavigationChildBinding + val binding: RowAdapterNavigationChildBinding + val view: View + if (convertView == null) { - rowAdapterNavigationChildBinding = RowAdapterNavigationChildBinding.inflate(LayoutInflater.from(parent.context), parent, false) - convertView = rowAdapterNavigationChildBinding.root - convertView.setTag(rowAdapterNavigationChildBinding) + binding = RowAdapterNavigationChildBinding.inflate(LayoutInflater.from(parent?.context), parent, false) + view = binding.root + view.tag = binding } else { - rowAdapterNavigationChildBinding = convertView.tag as RowAdapterNavigationChildBinding + binding = convertView.tag as RowAdapterNavigationChildBinding + view = convertView } - createCheckbox(convertView, tag) - rowAdapterNavigationChildBinding.tvDrawerTitle.text = tag.name - rowAdapterNavigationChildBinding.tvDrawerTitle.setOnClickListener { - if (clickListener != null) { - clickListener!!.onTagClicked(tag) - } - } - return convertView + + createCheckbox(view, tag) + binding.tvDrawerTitle.text = tag.name + binding.tvDrawerTitle.setOnClickListener { clickListener?.onTagClicked(tag) } + + return view } override fun isChildSelectable(groupPosition: Int, childPosition: Int): Boolean { return false } - fun setClickListener(clickListener: OnClickTagItem?) { + fun setClickListener(clickListener: OnClickTagItem) { this.clickListener = clickListener } @@ -146,4 +134,4 @@ class TagExpandableAdapter(private var tagList: List, private val chil fun onTagClicked(tag: RealmTag) fun onCheckboxTagSelected(tags: RealmTag) } -} +} \ No newline at end of file