Skip to content

Commit

Permalink
Keep guide searchbar pinned to top
Browse files Browse the repository at this point in the history
  • Loading branch information
kylecorry31 committed Jan 26, 2024
1 parent 39c706c commit 089afc6
Show file tree
Hide file tree
Showing 3 changed files with 129 additions and 83 deletions.
Original file line number Diff line number Diff line change
@@ -1,108 +1,58 @@
package com.kylecorry.trail_sense.tools.guide.ui

import android.os.Bundle
import androidx.core.os.bundleOf
import androidx.navigation.fragment.findNavController
import androidx.preference.Preference
import androidx.preference.PreferenceCategory
import androidx.preference.PreferenceFragmentCompat
import com.kylecorry.andromeda.core.tryOrNothing
import com.kylecorry.andromeda.fragments.inBackground
import com.kylecorry.luna.coroutines.CoroutineQueueRunner
import com.kylecorry.trail_sense.R
import com.kylecorry.trail_sense.settings.ui.SearchBarPreference
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.fragment.app.commit
import com.kylecorry.andromeda.fragments.BoundFragment
import com.kylecorry.trail_sense.databinding.FragmentGuideListBinding
import com.kylecorry.trail_sense.tools.guide.domain.UserGuideCategory
import com.kylecorry.trail_sense.tools.guide.infrastructure.Guides
import kotlinx.coroutines.Dispatchers

class GuideListFragment : PreferenceFragmentCompat() {
class GuideListFragment : BoundFragment<FragmentGuideListBinding>() {

private var guides = listOf<UserGuideCategory>()
private var searchPref: SearchBarPreference? = null
private var prefs = mutableListOf<Preference>()
private val queue = CoroutineQueueRunner(dispatcher = Dispatchers.Main)

override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
setPreferencesFromResource(R.xml.user_guide, rootKey)
guides = Guides.guides(requireContext())
preferenceScreen.setShouldUseGeneratedIds(true)
createSearchBar()
updateList(guides)
override fun generateBinding(
layoutInflater: LayoutInflater,
container: ViewGroup?
): FragmentGuideListBinding {
return FragmentGuideListBinding.inflate(layoutInflater, container, false)
}

private fun createSearchBar() {
searchPref = SearchBarPreference(requireContext(), null)
searchPref?.setOnSearchListener {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val fragment = GuideListPreferenceFragment()
val guides = Guides.guides(requireContext())

binding.searchbox.setOnSearchListener {
val newGuides = mutableListOf<UserGuideCategory>()

for (category in guides){
if (category.name.contains(it, true)){
for (category in guides) {
if (category.name.contains(it, true)) {
newGuides.add(category)
} else {
val newCategory = UserGuideCategory(category.name, category.guides.filter { guide ->
guide.name.contains(it, true)
})
if (newCategory.guides.isNotEmpty()){
val newCategory =
UserGuideCategory(category.name, category.guides.filter { guide ->
guide.name.contains(it, true)
})
if (newCategory.guides.isNotEmpty()) {
newGuides.add(newCategory)
}
}
}

updateList(newGuides)
}
// Add a searchbar to the top
searchPref?.let {
preferenceScreen.addPreference(it)
fragment.updateList(newGuides)
}
}

private fun updateList(guides: List<UserGuideCategory>) {
inBackground {
queue.enqueue {
prefs.forEach {
preferenceScreen.removePreference(it)
}
prefs.clear()

for (guideCategory in guides) {
val category = PreferenceCategory(requireContext())
category.title = guideCategory.name
category.isIconSpaceReserved = false
category.isSingleLineTitle = false
preferenceScreen.addPreference(category)
prefs.add(category)

for (guide in guideCategory.guides) {
val guidePref = Preference(requireContext())
guidePref.title = guide.name
if (guide.description != null) {
guidePref.summary = guide.description
}
guidePref.isSingleLineTitle = false
guidePref.isIconSpaceReserved = false
onClick(guidePref) {
tryOrNothing {
findNavController().navigate(
R.id.action_guideListFragment_to_guideFragment, bundleOf(
"guide_name" to guide.name,
"guide_contents" to guide.contents
)
)
}
}
category.addPreference(guidePref)
prefs.add(guidePref)
}
}
}
}
setFragment(fragment)
fragment.updateList(guides)
}


private fun onClick(pref: Preference?, action: () -> Unit) {
pref?.setOnPreferenceClickListener {
action.invoke()
true
private fun setFragment(fragment: Fragment) {
val fragmentManager = childFragmentManager
fragmentManager.commit {
replace(binding.guideFragment.id, fragment)
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package com.kylecorry.trail_sense.tools.guide.ui

import android.os.Bundle
import androidx.core.os.bundleOf
import androidx.navigation.fragment.findNavController
import androidx.preference.Preference
import androidx.preference.PreferenceCategory
import androidx.preference.PreferenceFragmentCompat
import com.kylecorry.andromeda.core.tryOrNothing
import com.kylecorry.andromeda.fragments.inBackground
import com.kylecorry.luna.coroutines.CoroutineQueueRunner
import com.kylecorry.trail_sense.R
import com.kylecorry.trail_sense.tools.guide.domain.UserGuideCategory
import kotlinx.coroutines.Dispatchers

class GuideListPreferenceFragment : PreferenceFragmentCompat() {

private val queue = CoroutineQueueRunner(dispatcher = Dispatchers.Main)

override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
setPreferencesFromResource(R.xml.user_guide, rootKey)
preferenceScreen.setShouldUseGeneratedIds(true)
}

fun updateList(guides: List<UserGuideCategory>) {
inBackground {
queue.enqueue {
preferenceScreen.removeAll()

for (guideCategory in guides) {
val category = PreferenceCategory(requireContext())
category.title = guideCategory.name
category.isIconSpaceReserved = false
category.isSingleLineTitle = false
preferenceScreen.addPreference(category)

for (guide in guideCategory.guides) {
val guidePref = Preference(requireContext())
guidePref.title = guide.name
if (guide.description != null) {
guidePref.summary = guide.description
}
guidePref.isSingleLineTitle = false
guidePref.isIconSpaceReserved = false
onClick(guidePref) {
tryOrNothing {
findNavController().navigate(
R.id.action_guideListFragment_to_guideFragment, bundleOf(
"guide_name" to guide.name,
"guide_contents" to guide.contents
)
)
}
}
category.addPreference(guidePref)
}
}
}
}
}


private fun onClick(pref: Preference?, action: () -> Unit) {
pref?.setOnPreferenceClickListener {
action.invoke()
true
}
}
}
27 changes: 27 additions & 0 deletions app/src/main/res/layout/fragment_guide_list.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">

<com.kylecorry.trail_sense.shared.views.SearchView
android:id="@+id/searchbox"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="16dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />

<androidx.fragment.app.FragmentContainerView
android:id="@+id/guide_fragment"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/searchbox" />

</androidx.constraintlayout.widget.ConstraintLayout>

0 comments on commit 089afc6

Please sign in to comment.