diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/library/MaterialMenuSheet.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/library/MaterialMenuSheet.kt new file mode 100644 index 0000000000..63e6c8bf0c --- /dev/null +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/library/MaterialMenuSheet.kt @@ -0,0 +1,147 @@ +package eu.kanade.tachiyomi.ui.library + +import android.animation.ObjectAnimator +import android.animation.ValueAnimator +import android.app.Activity +import android.content.res.ColorStateList +import android.os.Build +import android.view.View +import android.view.ViewGroup +import android.view.ViewGroup.LayoutParams.MATCH_PARENT +import android.widget.ImageView +import android.widget.TextView +import androidx.annotation.DrawableRes +import androidx.annotation.StringRes +import com.google.android.material.bottomsheet.BottomSheetBehavior +import com.google.android.material.bottomsheet.BottomSheetDialog +import com.google.android.material.textview.MaterialTextView +import eu.kanade.tachiyomi.R +import eu.kanade.tachiyomi.util.system.dpToPx +import eu.kanade.tachiyomi.util.system.getResourceColor +import eu.kanade.tachiyomi.util.system.hasSideNavBar +import eu.kanade.tachiyomi.util.system.isInNightMode +import eu.kanade.tachiyomi.util.view.expand +import eu.kanade.tachiyomi.util.view.invisible +import eu.kanade.tachiyomi.util.view.isVisible +import eu.kanade.tachiyomi.util.view.setBottomEdge +import eu.kanade.tachiyomi.util.view.setEdgeToEdge +import eu.kanade.tachiyomi.util.view.setTextColorRes +import eu.kanade.tachiyomi.util.view.updateLayoutParams +import eu.kanade.tachiyomi.util.view.visible +import eu.kanade.tachiyomi.util.view.visibleIf +import kotlinx.android.synthetic.main.bottom_menu_sheet.* + +class MaterialMenuSheet( + activity: Activity, + items: List, + title: String? = null, + selectedId: Int? = null, + onMenuItemClicked: (MaterialMenuSheet, Int) -> Boolean +) : + BottomSheetDialog + (activity, R.style.BottomSheetDialogTheme) { + + val primaryColor = activity.getResourceColor(android.R.attr.textColorPrimary) + private val view = activity.layoutInflater.inflate(R.layout.bottom_menu_sheet, null) + + init { + setContentView(view) + setEdgeToEdge(activity, view) + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && !context.isInNightMode() && !activity.window.decorView.rootWindowInsets.hasSideNavBar()) { + window?.decorView?.systemUiVisibility = View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR + } + + items.forEach { + val view = + activity.layoutInflater.inflate(R.layout.menu_sheet_item, null) as ViewGroup + val textView = view.getChildAt(0) as MaterialTextView + with(view) { + id = it.id + menu_layout.addView(this) + setOnClickListener { + val shouldDismiss = onMenuItemClicked(this@MaterialMenuSheet, id) + if (shouldDismiss) { + dismiss() + } + } + } + with(textView) { + if (it.text != null) { + text = it.text + } else { + setText(it.textRes) + } + setCompoundDrawablesRelativeWithIntrinsicBounds(it.drawable, 0, 0, 0) + if (it.id == selectedId) { + setTextColorRes(R.color.colorAccent) + compoundDrawableTintList = + ColorStateList.valueOf(context.getColor(R.color.colorAccent)) + } + updateLayoutParams { + height = 48.dpToPx + width = MATCH_PARENT + } + } + } + + BottomSheetBehavior.from(view.parent as ViewGroup).expand() + BottomSheetBehavior.from(view.parent as ViewGroup).skipCollapsed = true + + setBottomEdge(menu_layout, activity) + + title_layout.visibleIf(title != null) + toolbar_title.text = title + + var isNotElevated = false + var elevationAnimator: ValueAnimator? = null + if (title_layout.isVisible()) { + menu_scroll_view.setOnScrollChangeListener { _: View?, _: Int, _: Int, _: Int, _: Int -> + val atTop = !menu_scroll_view.canScrollVertically(-1) + if (atTop != isNotElevated) { + elevationAnimator?.cancel() + isNotElevated = atTop + elevationAnimator?.cancel() + elevationAnimator = ObjectAnimator.ofFloat( + title_layout, + "elevation", + title_layout.elevation, + if (atTop) 0f else 10f.dpToPx + ) + elevationAnimator?.duration = 100 + elevationAnimator?.start() + } + } + } + } + + private fun clearEndDrawables() { + (0 until menu_layout.childCount).forEach { + val textView = (menu_layout.getChildAt(it) as ViewGroup).getChildAt(0) as TextView + val imageView = (menu_layout.getChildAt(it) as ViewGroup).getChildAt(1) as ImageView + textView.setTextColor(primaryColor) + textView.compoundDrawableTintList = ColorStateList.valueOf(primaryColor) + imageView.invisible() + } + } + + fun setDrawable(id: Int, @DrawableRes drawableRes: Int, clearAll: Boolean = true) { + if (clearAll) { + clearEndDrawables() + } + val layout = menu_layout.findViewById(id) ?: return + val textView = layout.getChildAt(0) as? TextView + val imageView = layout.getChildAt(1) as? ImageView + textView?.setTextColorRes(R.color.colorAccent) + textView?.compoundDrawableTintList = + ColorStateList.valueOf(context.getColor(R.color.colorAccent)) + imageView?.visible() + imageView?.setImageResource(drawableRes) + } + + data class MenuSheetItem( + val id: Int, + @DrawableRes val drawable: Int = 0, + @StringRes val textRes: Int = 0, + val text: String? = null + ) +} diff --git a/app/src/main/res/layout/bottom_menu_sheet.xml b/app/src/main/res/layout/bottom_menu_sheet.xml new file mode 100644 index 0000000000..a7541e6802 --- /dev/null +++ b/app/src/main/res/layout/bottom_menu_sheet.xml @@ -0,0 +1,70 @@ + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/menu_sheet_item.xml b/app/src/main/res/layout/menu_sheet_item.xml new file mode 100644 index 0000000000..2621c06ee7 --- /dev/null +++ b/app/src/main/res/layout/menu_sheet_item.xml @@ -0,0 +1,35 @@ + + + + + + + \ No newline at end of file