New stylish bottom sheet

This commit is contained in:
Phillip Thelen 2022-04-22 11:32:58 +02:00
parent a7fd3f5fdc
commit c8eeddb6ef
14 changed files with 212 additions and 109 deletions

View file

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
<solid android:color="@color/content_background" />
<corners android:topLeftRadius="@dimen/bottom_sheet_radius" android:topRightRadius="@dimen/bottom_sheet_radius" />
</shape>

View file

@ -2,4 +2,5 @@
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="@color/window_background" />
<corners android:topLeftRadius="@dimen/bottom_sheet_radius" android:topRightRadius="@dimen/bottom_sheet_radius" />
</shape>

View file

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<View
android:id="@+id/grabber"
android:layout_width="40dp"
android:layout_height="4dp"
android:background="@drawable/layout_rounded_bg_gray"
android:layout_margin="@dimen/spacing_large"
android:layout_gravity="center_horizontal"
/>
<FrameLayout
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>

View file

@ -1,28 +1,41 @@
<?xml version="1.0" encoding="utf-8"?>
<com.habitrpg.android.habitica.ui.MaxHeightLinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
<LinearLayout android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:tools="http://schemas.android.com/tools"
android:paddingStart="@dimen/bottom_sheet_inset"
android:paddingEnd="@dimen/bottom_sheet_inset"
android:orientation="vertical"
app:maxHeightMultiplier="0.7">
<!-- margins can't be at the first LinearLayout, it has to be the inner one -->
xmlns:android="http://schemas.android.com/apk/res/android">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginEnd="@dimen/dialog_marginLeftRight"
android:layout_marginStart="@dimen/dialog_marginLeftRight"
android:layout_marginTop="16dp"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/spacing_large">
android:orientation="vertical">
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#1f000000" />
<TextView
style="@style/Headline"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/filters"
android:textColor="@color/text_primary"
android:layout_gravity="center_vertical"/>
<Space
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content" />
<Button
android:id="@+id/clear_button"
style="@style/Body1_Button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end"
android:text="@string/clear"
android:textColor="?colorPrimary"
android:textSize="16sp"
android:gravity="end|center_vertical"
android:paddingEnd="0dp"
android:paddingStart="0dp"
android:visibility="invisible"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
@ -84,7 +97,8 @@
android:checked="true"
android:text="@string/owned"
android:textColor="@color/text_primary"
android:paddingStart="8dp" />
android:paddingStart="8dp"
android:paddingEnd="0dp"/>
<CheckBox
style="@style/Subheader2"
@ -94,6 +108,6 @@
android:checked="true"
android:text="@string/not_owned"
android:textColor="@color/text_primary"
android:paddingStart="8dp"/>
android:paddingStart="8dp"
android:paddingEnd="0dp"/>
</LinearLayout>
</com.habitrpg.android.habitica.ui.MaxHeightLinearLayout>

View file

@ -4,7 +4,38 @@
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginBottom="16dp">
android:layout_marginBottom="16dp"
android:paddingStart="@dimen/bottom_sheet_inset"
android:paddingEnd="@dimen/bottom_sheet_inset">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/spacing_large">
<TextView
style="@style/Headline"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/filters"
android:textColor="@color/text_primary"
android:layout_gravity="center_vertical"/>
<Space
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content" />
<Button
android:id="@+id/clear_button"
style="@style/Body1_Button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end"
android:text="@string/clear"
android:textColor="?colorPrimary"
android:textSize="16sp"
android:gravity="end|center_vertical"
android:paddingEnd="0dp"
android:paddingStart="0dp"/>
</LinearLayout>
<TextView
android:id="@+id/task_type_title"
style="@style/Caption3"

View file

@ -5,8 +5,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
style="@style/BottomMenu"
android:clickable="false"
android:background="@drawable/rounded_avatar_bg">
android:clickable="false">
<TextView
android:id="@+id/title_view"
android:layout_width="match_parent"

View file

@ -118,4 +118,6 @@
<dimen name="widget_rounding">5dp</dimen>
<dimen name="task_spacing_vertical">4dp</dimen>
<dimen name="task_spacing_horizontal">10dp</dimen>
<dimen name="bottom_sheet_radius">20dp</dimen>
<dimen name="bottom_sheet_inset">16dp</dimen>
</resources>

View file

@ -845,5 +845,40 @@
<item name="android:textStyle">bold</item>
</style>
<style name="SheetDialog" parent="Theme.Design.Light.BottomSheetDialog">
<!--<item name="android:windowCloseOnTouchOutside">false</item>-->
<item name="android:windowIsTranslucent">true</item>
<item name="android:windowContentOverlay">@null</item>
<item name="android:colorBackground">@color/content_background</item>
<item name="android:backgroundDimEnabled">true</item>
<item name="android:backgroundDimAmount">0.3</item>
<item name="android:windowFrame">@null</item>
<item name="android:windowIsFloating">true</item>
<item name="shapeAppearanceOverlay">@style/CustomShapeAppearanceBottomSheetDialog</item>
<item name="bottomSheetStyle">@style/Widget.App.BottomSheet.Modal</item>
<item name="colorPrimary">@color/brand</item>
<item name="colorPrimaryDark">@color/brand_50</item>
<item name="colorAccent">@color/color_accent</item>
<item name="android:colorPrimary">@color/brand</item>
<item name="android:colorPrimaryDark">@color/brand_50</item>
<item name="android:colorAccent">@color/brand_400</item>
</style>
<style name="Widget.App.BottomSheet.Modal" parent="Widget.MaterialComponents.BottomSheet.Modal">
<item name="shapeAppearanceOverlay">@style/CustomShapeAppearanceBottomSheetDialog</item>
<item name="android:layout_marginStart">4dp</item>
<item name="android:layout_marginEnd">4dp</item>
</style>
<style name="CustomShapeAppearanceBottomSheetDialog" parent="">
<item name="cornerFamily">rounded</item>
<item name="cornerSizeTopRight">20dp</item>
<item name="cornerSizeTopLeft">20dp</item>
<item name="cornerSizeBottomRight">0dp</item>
<item name="cornerSizeBottomLeft">0dp</item>
</style>
<dimen name="my_background_radius_dimen">12dp</dimen>
</resources>

View file

@ -8,7 +8,6 @@ import android.view.animation.AccelerateInterpolator
import android.widget.FrameLayout
import androidx.core.content.ContextCompat
import androidx.lifecycle.lifecycleScope
import com.google.android.material.bottomsheet.BottomSheetDialog
import com.habitrpg.android.habitica.R
import com.habitrpg.android.habitica.components.UserComponent
import com.habitrpg.android.habitica.data.InventoryRepository
@ -20,6 +19,7 @@ import com.habitrpg.android.habitica.helpers.AppConfigManager
import com.habitrpg.android.habitica.helpers.RxErrorHandler
import com.habitrpg.android.habitica.ui.helpers.loadImage
import com.habitrpg.android.habitica.ui.viewmodels.MainUserViewModel
import com.habitrpg.android.habitica.ui.views.dialogs.HabiticaBottomSheetDialog
import com.plattysoft.leonids.ParticleSystem
import javax.inject.Inject
@ -166,7 +166,7 @@ class ArmoireActivity: BaseActivity() {
}
fun showDropRateDialog() {
val dialog = BottomSheetDialog(this)
val dialog = HabiticaBottomSheetDialog(this)
dialog.setContentView(R.layout.armoire_drop_rate_dialog)
dialog.show()
}

View file

@ -4,8 +4,8 @@ import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.DialogFragment
import androidx.viewbinding.ViewBinding
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
import com.habitrpg.android.habitica.HabiticaBaseApplication
import com.habitrpg.android.habitica.components.UserComponent
import com.habitrpg.android.habitica.data.TutorialRepository
@ -18,7 +18,7 @@ import io.reactivex.rxjava3.functions.Consumer
import java.util.concurrent.TimeUnit
import javax.inject.Inject
abstract class BaseDialogFragment<VB : ViewBinding> : DialogFragment() {
abstract class BaseDialogFragment<VB : ViewBinding> : BottomSheetDialogFragment() {
var isModal: Boolean = false
abstract var binding: VB?

View file

@ -8,6 +8,7 @@ import com.habitrpg.android.habitica.R
import com.habitrpg.android.habitica.databinding.DialogChallengeFilterBinding
import com.habitrpg.android.habitica.models.social.Group
import com.habitrpg.android.habitica.ui.adapter.social.challenges.ChallengesFilterRecyclerViewAdapter
import com.habitrpg.android.habitica.ui.views.dialogs.HabiticaBottomSheetDialog
import com.habitrpg.android.habitica.utils.Action1
internal class ChallengeFilterDialogHolder private constructor(
@ -28,13 +29,10 @@ internal class ChallengeFilterDialogHolder private constructor(
}
fun bind(
builder: AlertDialog.Builder,
filterGroups: List<Group>,
currentFilter: ChallengeFilterOptions?,
selectedGroupsCallback: Action1<ChallengeFilterOptions>
) {
builder.setPositiveButton(context.getString(R.string.done)) { _, _ -> doneClicked() }
.show()
this.filterGroups = filterGroups
this.currentFilter = currentFilter
this.selectedGroupsCallback = selectedGroupsCallback
@ -86,11 +84,11 @@ internal class ChallengeFilterDialogHolder private constructor(
val challengeFilterDialogHolder = ChallengeFilterDialogHolder(dialogLayout, activity)
val builder = AlertDialog.Builder(activity)
.setTitle(R.string.filter)
.setView(dialogLayout)
val sheet = HabiticaBottomSheetDialog(activity)
sheet.setContentView(dialogLayout)
challengeFilterDialogHolder.bind(builder, filterGroups, currentFilter, selectedGroupsCallback)
challengeFilterDialogHolder.bind(filterGroups, currentFilter, selectedGroupsCallback)
sheet.show()
}
}
}

View file

@ -2,21 +2,16 @@ package com.habitrpg.android.habitica.ui.menu
import android.content.Context
import android.view.View
import com.google.android.material.bottomsheet.BottomSheetBehavior
import com.google.android.material.bottomsheet.BottomSheetDialog
import com.habitrpg.android.habitica.databinding.MenuBottomSheetBinding
import com.habitrpg.android.habitica.ui.views.dialogs.HabiticaBottomSheetDialog
class BottomSheetMenu(context: Context) : BottomSheetDialog(context), View.OnClickListener {
class BottomSheetMenu(context: Context) : HabiticaBottomSheetDialog(context), View.OnClickListener {
private var binding = MenuBottomSheetBinding.inflate(layoutInflater)
private var runnable: ((Int) -> Unit)? = null
init {
setContentView(binding.root)
binding.titleView.visibility = View.GONE
val behavior = BottomSheetBehavior.from(binding.root.parent as View)
behavior.state = BottomSheetBehavior.STATE_EXPANDED
behavior.peekHeight = 0
}
fun setSelectionRunnable(runnable: (Int) -> Unit) {
@ -26,12 +21,14 @@ class BottomSheetMenu(context: Context) : BottomSheetDialog(context), View.OnCli
override fun setTitle(title: CharSequence?) {
binding.titleView.text = title
binding.titleView.visibility = View.VISIBLE
grabberVisibility = View.GONE
}
fun addMenuItem(menuItem: BottomSheetMenuItem) {
val item = menuItem.inflate(this.context, layoutInflater, this.binding.menuItems)
item.setOnClickListener(this)
this.binding.menuItems.addView(item)
binding.root.requestLayout()
}
override fun onClick(v: View) {

View file

@ -0,0 +1,27 @@
package com.habitrpg.android.habitica.ui.views.dialogs
import android.content.Context
import android.view.View
import com.google.android.material.bottomsheet.BottomSheetDialog
import com.habitrpg.android.habitica.R
import com.habitrpg.android.habitica.databinding.BottomSheetWrapperBinding
open class HabiticaBottomSheetDialog(context: Context) : BottomSheetDialog(context, R.style.SheetDialog) {
private val wrapperBinding = BottomSheetWrapperBinding.inflate(layoutInflater)
var grabberVisibility: Int
get() = wrapperBinding.grabber.visibility
set(value) {
wrapperBinding.grabber.visibility = value
}
override fun setContentView(view: View) {
wrapperBinding.container.addView(view)
super.setContentView(wrapperBinding.root)
}
override fun setContentView(layoutResId: Int) {
layoutInflater.inflate(layoutResId, wrapperBinding.container)
super.setContentView(wrapperBinding.root)
}
}

View file

@ -12,9 +12,7 @@ import android.widget.Button
import android.widget.EditText
import android.widget.ImageButton
import android.widget.LinearLayout
import android.widget.RadioButton
import android.widget.RadioGroup
import android.widget.TextView
import androidx.annotation.IdRes
import androidx.appcompat.widget.AppCompatCheckBox
import androidx.core.content.ContextCompat
@ -22,32 +20,24 @@ import androidx.core.widget.CompoundButtonCompat
import com.habitrpg.android.habitica.R
import com.habitrpg.android.habitica.components.UserComponent
import com.habitrpg.android.habitica.data.TagRepository
import com.habitrpg.android.habitica.databinding.DialogTaskFilterBinding
import com.habitrpg.android.habitica.extensions.OnChangeTextWatcher
import com.habitrpg.android.habitica.extensions.getThemeColor
import com.habitrpg.android.habitica.helpers.RxErrorHandler
import com.habitrpg.android.habitica.models.Tag
import com.habitrpg.android.habitica.models.tasks.Task
import com.habitrpg.android.habitica.models.tasks.TaskType
import com.habitrpg.android.habitica.ui.views.dialogs.HabiticaAlertDialog
import com.habitrpg.android.habitica.ui.views.dialogs.HabiticaBottomSheetDialog
import io.reactivex.rxjava3.core.Observable
import java.util.UUID
import javax.inject.Inject
class TaskFilterDialog(context: Context, component: UserComponent?) : HabiticaAlertDialog(context), RadioGroup.OnCheckedChangeListener {
private var clearButton: Button
class TaskFilterDialog(context: Context, component: UserComponent?) : HabiticaBottomSheetDialog(context), RadioGroup.OnCheckedChangeListener {
private val binding = DialogTaskFilterBinding.inflate(layoutInflater)
@Inject
lateinit var repository: TagRepository
private var taskTypeTitle: TextView
private var taskFilters: RadioGroup
private var allTaskFilter: RadioButton
private var secondTaskFilter: RadioButton
private var thirdTaskFilter: RadioButton
private var tagsEditButton: Button
private var tagsList: LinearLayout
private var taskType: TaskType? = null
private var listener: OnFilterCompletedListener? = null
@ -65,22 +55,12 @@ class TaskFilterDialog(context: Context, component: UserComponent?) : HabiticaAl
component?.inject(this)
addIcon = ContextCompat.getDrawable(context, R.drawable.ic_add_purple_300_36dp)
val inflater = LayoutInflater.from(context)
val view = inflater.inflate(R.layout.dialog_task_filter, null)
setTitle(R.string.filters)
this.setAdditionalContentView(view)
this.setContentView(binding.root)
taskTypeTitle = view.findViewById(R.id.task_type_title)
taskFilters = view.findViewById(R.id.task_filter_wrapper)
allTaskFilter = view.findViewById(R.id.all_task_filter)
secondTaskFilter = view.findViewById(R.id.second_task_filter)
thirdTaskFilter = view.findViewById(R.id.third_task_filter)
tagsEditButton = view.findViewById(R.id.tag_edit_button)
tagsList = view.findViewById(R.id.tags_list)
binding.taskFilterWrapper.setOnCheckedChangeListener(this)
taskFilters.setOnCheckedChangeListener(this)
clearButton = addButton(R.string.clear, false, false, false) { _, _ ->
binding.clearButton.setOnClickListener {
if (isEditing) {
stopEditing()
}
@ -88,16 +68,12 @@ class TaskFilterDialog(context: Context, component: UserComponent?) : HabiticaAl
setActiveTags(null)
}
addButton(R.string.done, false) { _, _ ->
if (isEditing) {
stopEditing()
}
listener?.onFilterCompleted(filterType, activeTags)
this.dismiss()
}
buttonAxis = LinearLayout.HORIZONTAL
binding.tagEditButton.setOnClickListener { editButtonClicked() }
}
tagsEditButton.setOnClickListener { editButtonClicked() }
override fun dismiss() {
listener?.onFilterCompleted(filterType, activeTags)
super.dismiss()
}
override fun show() {
@ -111,7 +87,7 @@ class TaskFilterDialog(context: Context, component: UserComponent?) : HabiticaAl
}
private fun createTagViews() {
tagsList.removeAllViews()
binding.tagsList.removeAllViews()
val colorStateList = ColorStateList(
arrayOf(
intArrayOf(-android.R.attr.state_checked), // disabled
@ -149,7 +125,7 @@ class TaskFilterDialog(context: Context, component: UserComponent?) : HabiticaAl
}
filtersChanged()
}
tagsList.addView(tagCheckbox)
binding.tagsList.addView(tagCheckbox)
}
createAddTagButton()
}
@ -164,7 +140,7 @@ class TaskFilterDialog(context: Context, component: UserComponent?) : HabiticaAl
}
button.setBackgroundResource(R.drawable.layout_rounded_bg_lighter_gray)
button.setTextColor(ContextCompat.getColor(context, R.color.text_secondary))
tagsList.addView(button)
binding.tagsList.addView(button)
}
private fun createTag() {
@ -177,17 +153,17 @@ class TaskFilterDialog(context: Context, component: UserComponent?) : HabiticaAl
private fun startEditing() {
isEditing = true
tagsList.removeAllViews()
binding.tagsList.removeAllViews()
createTagEditViews()
tagsEditButton.setText(R.string.done)
binding.tagEditButton.setText(R.string.done)
this.window?.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE)
}
private fun stopEditing() {
isEditing = false
tagsList.removeAllViews()
binding.tagsList.removeAllViews()
createTagViews()
tagsEditButton.setText(R.string.edit_tag_btn_edit)
binding.tagEditButton.setText(R.string.edit_tag_btn_edit)
this.window?.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN)
repository.updateTags(editedTags.values).toObservable().flatMap { tags -> Observable.fromIterable(tags) }.subscribe({ tag -> editedTags.remove(tag.id) }, RxErrorHandler.handleEmptyError())
repository.createTags(createdTags.values).toObservable().flatMap { tags -> Observable.fromIterable(tags) }.subscribe({ tag -> createdTags.remove(tag.id) }, RxErrorHandler.handleEmptyError())
@ -204,7 +180,7 @@ class TaskFilterDialog(context: Context, component: UserComponent?) : HabiticaAl
}
private fun createTagEditView(inflater: LayoutInflater, index: Int, tag: Tag) {
val wrapper = inflater.inflate(R.layout.edit_tag_item, tagsList, false) as? LinearLayout
val wrapper = inflater.inflate(R.layout.edit_tag_item, binding.tagsList, false) as? LinearLayout
val tagEditText = wrapper?.findViewById<View>(R.id.edit_text) as? EditText
tagEditText?.setText(tag.name)
tagEditText?.addTextChangedListener(
@ -233,9 +209,9 @@ class TaskFilterDialog(context: Context, component: UserComponent?) : HabiticaAl
}
activeTags.remove(tag.id)
tags.remove(tag)
tagsList.removeView(wrapper)
binding.tagsList.removeView(wrapper)
}
tagsList.addView(wrapper)
binding.tagsList.addView(wrapper)
}
fun setActiveTags(tagIds: MutableList<String>?) {
@ -244,13 +220,13 @@ class TaskFilterDialog(context: Context, component: UserComponent?) : HabiticaAl
} else {
this.activeTags = tagIds
}
for (index in 0 until tagsList.childCount - 1) {
(tagsList.getChildAt(index) as? AppCompatCheckBox)?.isChecked = false
for (index in 0 until binding.tagsList.childCount - 1) {
(binding.tagsList.getChildAt(index) as? AppCompatCheckBox)?.isChecked = false
}
for (tagId in this.activeTags) {
val index = indexForId(tagId)
if (index >= 0) {
(tagsList.getChildAt(index) as? AppCompatCheckBox)?.isChecked = true
(binding.tagsList.getChildAt(index) as? AppCompatCheckBox)?.isChecked = true
}
}
filtersChanged()
@ -269,22 +245,22 @@ class TaskFilterDialog(context: Context, component: UserComponent?) : HabiticaAl
this.taskType = taskType
when (taskType) {
TaskType.HABIT -> {
taskTypeTitle.setText(R.string.habits)
allTaskFilter.setText(R.string.all)
secondTaskFilter.setText(R.string.weak)
thirdTaskFilter.setText(R.string.strong)
binding.taskTypeTitle.setText(R.string.habits)
binding.allTaskFilter.setText(R.string.all)
binding.secondTaskFilter.setText(R.string.weak)
binding.thirdTaskFilter.setText(R.string.strong)
}
TaskType.DAILY -> {
taskTypeTitle.setText(R.string.dailies)
allTaskFilter.setText(R.string.all)
secondTaskFilter.setText(R.string.due)
thirdTaskFilter.setText(R.string.gray)
binding.taskTypeTitle.setText(R.string.dailies)
binding.allTaskFilter.setText(R.string.all)
binding.secondTaskFilter.setText(R.string.due)
binding.thirdTaskFilter.setText(R.string.gray)
}
TaskType.TODO -> {
taskTypeTitle.setText(R.string.todos)
allTaskFilter.setText(R.string.active)
secondTaskFilter.setText(R.string.dated)
thirdTaskFilter.setText(R.string.completed)
binding.taskTypeTitle.setText(R.string.todos)
binding.allTaskFilter.setText(R.string.active)
binding.secondTaskFilter.setText(R.string.dated)
binding.thirdTaskFilter.setText(R.string.completed)
}
}
setActiveFilter(activeFilter)
@ -307,7 +283,7 @@ class TaskFilterDialog(context: Context, component: UserComponent?) : HabiticaAl
}
}
}
taskFilters.check(checkedId)
binding.taskFilterWrapper.check(checkedId)
filtersChanged()
}
@ -345,9 +321,9 @@ class TaskFilterDialog(context: Context, component: UserComponent?) : HabiticaAl
}
private fun filtersChanged() {
clearButton.isEnabled = hasActiveFilters()
clearButton.setTextColor(
if (clearButton.isEnabled) {
binding.clearButton.isEnabled = hasActiveFilters()
binding.clearButton.setTextColor(
if (binding.clearButton.isEnabled) {
context.getThemeColor(R.attr.colorAccent)
} else {
ContextCompat.getColor(context, R.color.text_dimmed)
@ -356,7 +332,7 @@ class TaskFilterDialog(context: Context, component: UserComponent?) : HabiticaAl
}
private fun hasActiveFilters(): Boolean {
return taskFilters.checkedRadioButtonId != R.id.all_task_filter || activeTags.size > 0
return binding.taskFilterWrapper.checkedRadioButtonId != R.id.all_task_filter || activeTags.size > 0
}
fun setListener(listener: OnFilterCompletedListener) {