Merge branch 'feature/m3' into devel

This commit is contained in:
Koitharu
2022-03-20 17:04:06 +02:00
54 changed files with 569 additions and 224 deletions

View File

@@ -12,18 +12,20 @@ import androidx.appcompat.view.ActionMode
import androidx.appcompat.widget.ActionBarContextView import androidx.appcompat.widget.ActionBarContextView
import androidx.appcompat.widget.Toolbar import androidx.appcompat.widget.Toolbar
import androidx.core.app.ActivityCompat import androidx.core.app.ActivityCompat
import androidx.core.graphics.Insets import androidx.core.view.ViewCompat
import androidx.core.view.* import androidx.core.view.WindowCompat
import androidx.core.view.WindowInsetsCompat
import androidx.core.view.updateLayoutParams
import androidx.viewbinding.ViewBinding import androidx.viewbinding.ViewBinding
import com.google.android.material.appbar.AppBarLayout
import com.google.android.material.appbar.AppBarLayout.LayoutParams.*
import org.koin.android.ext.android.get import org.koin.android.ext.android.get
import org.koitharu.kotatsu.BuildConfig import org.koitharu.kotatsu.BuildConfig
import org.koitharu.kotatsu.R import org.koitharu.kotatsu.R
import org.koitharu.kotatsu.base.ui.util.WindowInsetsDelegate
import org.koitharu.kotatsu.core.exceptions.resolve.ExceptionResolver import org.koitharu.kotatsu.core.exceptions.resolve.ExceptionResolver
import org.koitharu.kotatsu.core.prefs.AppSettings import org.koitharu.kotatsu.core.prefs.AppSettings
abstract class BaseActivity<B : ViewBinding> : AppCompatActivity(), OnApplyWindowInsetsListener { abstract class BaseActivity<B : ViewBinding> : AppCompatActivity(),
WindowInsetsDelegate.WindowInsetsListener {
protected lateinit var binding: B protected lateinit var binding: B
private set private set
@@ -31,7 +33,8 @@ abstract class BaseActivity<B : ViewBinding> : AppCompatActivity(), OnApplyWindo
@Suppress("LeakingThis") @Suppress("LeakingThis")
protected val exceptionResolver = ExceptionResolver(this) protected val exceptionResolver = ExceptionResolver(this)
private var lastInsets: Insets? = null @Suppress("LeakingThis")
protected val insetsDelegate = WindowInsetsDelegate(this)
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
val settings = get<AppSettings>() val settings = get<AppSettings>()
@@ -41,6 +44,7 @@ abstract class BaseActivity<B : ViewBinding> : AppCompatActivity(), OnApplyWindo
} }
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
WindowCompat.setDecorFitsSystemWindows(window, false) WindowCompat.setDecorFitsSystemWindows(window, false)
insetsDelegate.handleImeInsets = true
} }
@Deprecated("Use ViewBinding", level = DeprecationLevel.ERROR) @Deprecated("Use ViewBinding", level = DeprecationLevel.ERROR)
@@ -60,28 +64,7 @@ abstract class BaseActivity<B : ViewBinding> : AppCompatActivity(), OnApplyWindo
super.setContentView(binding.root) super.setContentView(binding.root)
val toolbar = (binding.root.findViewById<View>(R.id.toolbar) as? Toolbar) val toolbar = (binding.root.findViewById<View>(R.id.toolbar) as? Toolbar)
toolbar?.let(this::setSupportActionBar) toolbar?.let(this::setSupportActionBar)
ViewCompat.setOnApplyWindowInsetsListener(binding.root, this) insetsDelegate.onViewCreated(binding.root)
val toolbarParams = (binding.root.findViewById<View>(R.id.toolbar_card) ?: toolbar)
?.layoutParams as? AppBarLayout.LayoutParams
if (toolbarParams != null) {
if (get<AppSettings>().isToolbarHideWhenScrolling) {
toolbarParams.scrollFlags = SCROLL_FLAG_SCROLL or SCROLL_FLAG_ENTER_ALWAYS or SCROLL_FLAG_SNAP
} else {
toolbarParams.scrollFlags = SCROLL_FLAG_NO_SCROLL
}
}
}
override fun onApplyWindowInsets(v: View, insets: WindowInsetsCompat): WindowInsetsCompat {
val baseInsets = insets.getInsets(WindowInsetsCompat.Type.systemBars())
val imeInsets = insets.getInsets(WindowInsetsCompat.Type.ime())
val newInsets = Insets.max(baseInsets, imeInsets)
if (newInsets != lastInsets) {
onWindowInsetsChanged(newInsets)
lastInsets = newInsets
}
return insets
} }
override fun onOptionsItemSelected(item: MenuItem) = if (item.itemId == android.R.id.home) { override fun onOptionsItemSelected(item: MenuItem) = if (item.itemId == android.R.id.home) {
@@ -97,8 +80,6 @@ abstract class BaseActivity<B : ViewBinding> : AppCompatActivity(), OnApplyWindo
return super.onKeyDown(keyCode, event) return super.onKeyDown(keyCode, event)
} }
protected abstract fun onWindowInsetsChanged(insets: Insets)
private fun setupToolbar() { private fun setupToolbar() {
(findViewById<View>(R.id.toolbar) as? Toolbar)?.let(this::setSupportActionBar) (findViewById<View>(R.id.toolbar) as? Toolbar)?.let(this::setSupportActionBar)
} }

View File

@@ -4,16 +4,13 @@ import android.os.Bundle
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.core.graphics.Insets
import androidx.core.view.OnApplyWindowInsetsListener
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import androidx.core.view.doOnNextLayout
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.viewbinding.ViewBinding import androidx.viewbinding.ViewBinding
import org.koitharu.kotatsu.base.ui.util.WindowInsetsDelegate
import org.koitharu.kotatsu.core.exceptions.resolve.ExceptionResolver import org.koitharu.kotatsu.core.exceptions.resolve.ExceptionResolver
abstract class BaseFragment<B : ViewBinding> : Fragment(), OnApplyWindowInsetsListener { abstract class BaseFragment<B : ViewBinding> : Fragment(),
WindowInsetsDelegate.WindowInsetsListener {
private var viewBinding: B? = null private var viewBinding: B? = null
@@ -23,7 +20,8 @@ abstract class BaseFragment<B : ViewBinding> : Fragment(), OnApplyWindowInsetsLi
@Suppress("LeakingThis") @Suppress("LeakingThis")
protected val exceptionResolver = ExceptionResolver(this) protected val exceptionResolver = ExceptionResolver(this)
private var lastInsets: Insets? = null @Suppress("LeakingThis")
protected val insetsDelegate = WindowInsetsDelegate(this)
override fun onCreateView( override fun onCreateView(
inflater: LayoutInflater, inflater: LayoutInflater,
@@ -37,33 +35,16 @@ abstract class BaseFragment<B : ViewBinding> : Fragment(), OnApplyWindowInsetsLi
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
ViewCompat.setOnApplyWindowInsetsListener(view, this) insetsDelegate.onViewCreated(view)
view.doOnNextLayout {
// Listener may not be called
if (lastInsets == null) {
onWindowInsetsChanged(Insets.NONE)
}
}
} }
override fun onDestroyView() { override fun onDestroyView() {
viewBinding = null viewBinding = null
lastInsets = null insetsDelegate.onDestroyView()
super.onDestroyView() super.onDestroyView()
} }
override fun onApplyWindowInsets(v: View?, insets: WindowInsetsCompat): WindowInsetsCompat {
val newInsets = insets.getInsets(WindowInsetsCompat.Type.systemBars())
if (newInsets != lastInsets) {
onWindowInsetsChanged(newInsets)
lastInsets = newInsets
}
return insets
}
protected fun bindingOrNull() = viewBinding protected fun bindingOrNull() = viewBinding
protected abstract fun onInflateView(inflater: LayoutInflater, container: ViewGroup?): B protected abstract fun onInflateView(inflater: LayoutInflater, container: ViewGroup?): B
protected abstract fun onWindowInsetsChanged(insets: Insets)
} }

View File

@@ -2,38 +2,53 @@ package org.koitharu.kotatsu.base.ui
import android.os.Bundle import android.os.Bundle
import android.view.View import android.view.View
import androidx.annotation.CallSuper
import androidx.annotation.StringRes import androidx.annotation.StringRes
import androidx.core.view.OnApplyWindowInsetsListener import androidx.core.graphics.Insets
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import androidx.core.view.updatePadding import androidx.core.view.updatePadding
import androidx.preference.PreferenceFragmentCompat import androidx.preference.PreferenceFragmentCompat
import androidx.recyclerview.widget.RecyclerView
import org.koin.android.ext.android.inject import org.koin.android.ext.android.inject
import org.koitharu.kotatsu.base.ui.util.RecyclerViewOwner
import org.koitharu.kotatsu.base.ui.util.WindowInsetsDelegate
import org.koitharu.kotatsu.core.prefs.AppSettings import org.koitharu.kotatsu.core.prefs.AppSettings
abstract class BasePreferenceFragment(@StringRes private val titleId: Int) : PreferenceFragmentCompat(), abstract class BasePreferenceFragment(@StringRes private val titleId: Int) : PreferenceFragmentCompat(),
OnApplyWindowInsetsListener { WindowInsetsDelegate.WindowInsetsListener,
RecyclerViewOwner {
protected val settings by inject<AppSettings>(mode = LazyThreadSafetyMode.NONE) protected val settings by inject<AppSettings>(mode = LazyThreadSafetyMode.NONE)
@Suppress("LeakingThis")
protected val insetsDelegate = WindowInsetsDelegate(this)
override val recyclerView: RecyclerView
get() = listView
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
listView.clipToPadding = false listView.clipToPadding = false
ViewCompat.setOnApplyWindowInsetsListener(view, this) insetsDelegate.onViewCreated(view)
}
override fun onDestroyView() {
insetsDelegate.onDestroyView()
super.onDestroyView()
} }
override fun onResume() { override fun onResume() {
super.onResume() super.onResume()
activity?.setTitle(titleId) if (titleId != 0) {
activity?.setTitle(titleId)
}
} }
override fun onApplyWindowInsets(v: View?, insets: WindowInsetsCompat): WindowInsetsCompat { @CallSuper
val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars()) override fun onWindowInsetsChanged(insets: Insets) {
listView.updatePadding( listView.updatePadding(
left = systemBars.left, left = insets.left,
right = systemBars.right, right = insets.right,
bottom = systemBars.bottom bottom = insets.bottom
) )
return insets
} }
} }

View File

@@ -0,0 +1,8 @@
package org.koitharu.kotatsu.base.ui.util
import androidx.recyclerview.widget.RecyclerView
interface RecyclerViewOwner {
val recyclerView: RecyclerView
}

View File

@@ -0,0 +1,69 @@
package org.koitharu.kotatsu.base.ui.util
import android.view.View
import androidx.core.graphics.Insets
import androidx.core.view.OnApplyWindowInsetsListener
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
class WindowInsetsDelegate(
private val listener: WindowInsetsListener,
) : OnApplyWindowInsetsListener, View.OnLayoutChangeListener {
var handleImeInsets: Boolean = false
var interceptingWindowInsetsListener: OnApplyWindowInsetsListener? = null
private var lastInsets: Insets? = null
override fun onApplyWindowInsets(v: View?, insets: WindowInsetsCompat?): WindowInsetsCompat? {
if (insets == null) {
return null
}
val handledInsets = interceptingWindowInsetsListener?.onApplyWindowInsets(v, insets) ?: insets
val newInsets = if (handleImeInsets) {
Insets.max(
handledInsets.getInsets(WindowInsetsCompat.Type.systemBars()),
handledInsets.getInsets(WindowInsetsCompat.Type.ime()),
)
} else {
handledInsets.getInsets(WindowInsetsCompat.Type.systemBars())
}
if (newInsets != lastInsets) {
listener.onWindowInsetsChanged(newInsets)
lastInsets = newInsets
}
return handledInsets
}
override fun onLayoutChange(
view: View,
left: Int,
top: Int,
right: Int,
bottom: Int,
oldLeft: Int,
oldTop: Int,
oldRight: Int,
oldBottom: Int,
) {
view.removeOnLayoutChangeListener(this)
if (lastInsets == null) { // Listener may not be called
onApplyWindowInsets(view, ViewCompat.getRootWindowInsets(view))
}
}
fun onViewCreated(view: View) {
ViewCompat.setOnApplyWindowInsetsListener(view, this)
view.addOnLayoutChangeListener(this)
}
fun onDestroyView() {
lastInsets = null
}
interface WindowInsetsListener {
fun onWindowInsetsChanged(insets: Insets)
}
}

View File

@@ -0,0 +1,120 @@
package org.koitharu.kotatsu.base.ui.widgets
import android.content.Context
import android.content.res.ColorStateList
import android.content.res.TypedArray
import android.graphics.Color
import android.graphics.drawable.Drawable
import android.graphics.drawable.InsetDrawable
import android.graphics.drawable.RippleDrawable
import android.graphics.drawable.ShapeDrawable
import android.graphics.drawable.shapes.RectShape
import android.util.AttributeSet
import androidx.annotation.AttrRes
import androidx.appcompat.widget.AppCompatCheckedTextView
import androidx.core.content.res.use
import androidx.core.content.withStyledAttributes
import com.google.android.material.shape.MaterialShapeDrawable
import com.google.android.material.shape.ShapeAppearanceModel
import org.koitharu.kotatsu.R
class ListItemTextView @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
@AttrRes defStyleAttr: Int = R.attr.listItemTextViewStyle,
) : AppCompatCheckedTextView(context, attrs, defStyleAttr) {
private var checkedDrawableStart: Drawable? = null
private var checkedDrawableEnd: Drawable? = null
private var isInitialized = false
private var isCheckDrawablesVisible: Boolean = false
private var defaultPaddingStart: Int = 0
private var defaultPaddingEnd: Int = 0
init {
context.withStyledAttributes(attrs, R.styleable.ListItemTextView, defStyleAttr) {
background = RippleDrawable(
getColorStateList(R.styleable.ListItemTextView_rippleColor) ?: getRippleColorFallback(context),
createShapeDrawable(this),
ShapeDrawable(RectShape()),
)
checkedDrawableStart = getDrawable(R.styleable.ListItemTextView_checkedDrawableStart)
checkedDrawableEnd = getDrawable(R.styleable.ListItemTextView_checkedDrawableEnd)
}
checkedDrawableStart?.setTintList(textColors)
checkedDrawableEnd?.setTintList(textColors)
defaultPaddingStart = paddingStart
defaultPaddingEnd = paddingEnd
isInitialized = true
adjustCheckDrawables()
}
override fun refreshDrawableState() {
super.refreshDrawableState()
adjustCheckDrawables()
}
override fun setTextColor(colors: ColorStateList?) {
checkedDrawableStart?.setTintList(colors)
checkedDrawableEnd?.setTintList(colors)
super.setTextColor(colors)
}
override fun setPaddingRelative(start: Int, top: Int, end: Int, bottom: Int) {
defaultPaddingStart = start
defaultPaddingEnd = end
super.setPaddingRelative(start, top, end, bottom)
}
override fun setPadding(left: Int, top: Int, right: Int, bottom: Int) {
val isRtl = layoutDirection == LAYOUT_DIRECTION_RTL
defaultPaddingStart = if (isRtl) right else left
defaultPaddingEnd = if (isRtl) left else right
super.setPadding(left, top, right, bottom)
}
private fun adjustCheckDrawables() {
if (isInitialized && isCheckDrawablesVisible != isChecked) {
setCompoundDrawablesRelativeWithIntrinsicBounds(
if (isChecked) checkedDrawableStart else null,
null,
if (isChecked) checkedDrawableEnd else null,
null,
)
super.setPaddingRelative(
if (isChecked && checkedDrawableStart != null) {
defaultPaddingStart + compoundDrawablePadding
} else defaultPaddingStart,
paddingTop,
if (isChecked && checkedDrawableEnd != null) {
defaultPaddingEnd + compoundDrawablePadding
} else defaultPaddingEnd,
paddingBottom,
)
isCheckDrawablesVisible = isChecked
}
}
private fun createShapeDrawable(ta: TypedArray): InsetDrawable {
val shapeAppearance = ShapeAppearanceModel.builder(
context,
ta.getResourceId(R.styleable.ListItemTextView_shapeAppearance, 0),
ta.getResourceId(R.styleable.ListItemTextView_shapeAppearanceOverlay, 0),
).build()
val shapeDrawable = MaterialShapeDrawable(shapeAppearance)
shapeDrawable.fillColor = ta.getColorStateList(R.styleable.ListItemTextView_backgroundTint)
return InsetDrawable(
shapeDrawable,
ta.getDimensionPixelOffset(R.styleable.ListItemTextView_android_insetLeft, 0),
ta.getDimensionPixelOffset(R.styleable.ListItemTextView_android_insetTop, 0),
ta.getDimensionPixelOffset(R.styleable.ListItemTextView_android_insetRight, 0),
ta.getDimensionPixelOffset(R.styleable.ListItemTextView_android_insetBottom, 0),
)
}
private fun getRippleColorFallback(context: Context): ColorStateList {
return context.obtainStyledAttributes(intArrayOf(android.R.attr.colorControlHighlight)).use {
it.getColorStateList(0)
} ?: ColorStateList.valueOf(Color.TRANSPARENT)
}
}

View File

@@ -45,9 +45,6 @@ class AppSettings(context: Context) {
val isAmoledTheme: Boolean val isAmoledTheme: Boolean
get() = prefs.getBoolean(KEY_THEME_AMOLED, false) get() = prefs.getBoolean(KEY_THEME_AMOLED, false)
val isToolbarHideWhenScrolling: Boolean
get() = prefs.getBoolean(KEY_HIDE_TOOLBAR, true)
var gridSize: Int var gridSize: Int
get() = prefs.getInt(KEY_GRID_SIZE, 100) get() = prefs.getInt(KEY_GRID_SIZE, 100)
set(value) = prefs.edit { putInt(KEY_GRID_SIZE, value) } set(value) = prefs.edit { putInt(KEY_GRID_SIZE, value) }
@@ -215,7 +212,6 @@ class AppSettings(context: Context) {
const val KEY_DYNAMIC_THEME = "dynamic_theme" const val KEY_DYNAMIC_THEME = "dynamic_theme"
const val KEY_THEME_AMOLED = "amoled_theme" const val KEY_THEME_AMOLED = "amoled_theme"
const val KEY_DATE_FORMAT = "date_format" const val KEY_DATE_FORMAT = "date_format"
const val KEY_HIDE_TOOLBAR = "hide_toolbar"
const val KEY_SOURCES_ORDER = "sources_order" const val KEY_SOURCES_ORDER = "sources_order"
const val KEY_SOURCES_HIDDEN = "sources_hidden" const val KEY_SOURCES_HIDDEN = "sources_hidden"
const val KEY_TRAFFIC_WARNING = "traffic_warning" const val KEY_TRAFFIC_WARNING = "traffic_warning"

View File

@@ -53,7 +53,6 @@ class ChaptersFragment : BaseFragment<FragmentChaptersBinding>(),
chaptersAdapter = ChaptersAdapter(this) chaptersAdapter = ChaptersAdapter(this)
selectionDecoration = ChaptersSelectionDecoration(view.context) selectionDecoration = ChaptersSelectionDecoration(view.context)
with(binding.recyclerViewChapters) { with(binding.recyclerViewChapters) {
addItemDecoration(MaterialDividerItemDecoration(view.context, RecyclerView.VERTICAL))
addItemDecoration(selectionDecoration!!) addItemDecoration(selectionDecoration!!)
setHasFixedSize(true) setHasFixedSize(true)
adapter = chaptersAdapter adapter = chaptersAdapter

View File

@@ -47,15 +47,10 @@ class DownloadsActivity : BaseActivity<ActivityDownloadsBinding>() {
right = insets.right, right = insets.right,
bottom = insets.bottom bottom = insets.bottom
) )
with(binding.toolbar) { binding.toolbar.updatePadding(
updatePadding( left = insets.left,
left = insets.left, right = insets.right
right = insets.right )
)
updateLayoutParams<ViewGroup.MarginLayoutParams> {
topMargin = insets.top
}
}
} }
companion object { companion object {

View File

@@ -12,7 +12,6 @@ import androidx.core.view.updateLayoutParams
import androidx.core.view.updatePadding import androidx.core.view.updatePadding
import androidx.recyclerview.widget.ItemTouchHelper import androidx.recyclerview.widget.ItemTouchHelper
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import com.google.android.material.divider.MaterialDividerItemDecoration
import com.google.android.material.snackbar.Snackbar import com.google.android.material.snackbar.Snackbar
import org.koin.androidx.viewmodel.ext.android.viewModel import org.koin.androidx.viewmodel.ext.android.viewModel
import org.koitharu.kotatsu.R import org.koitharu.kotatsu.R
@@ -42,7 +41,6 @@ class CategoriesActivity : BaseActivity<ActivityCategoriesBinding>(),
supportActionBar?.setDisplayHomeAsUpEnabled(true) supportActionBar?.setDisplayHomeAsUpEnabled(true)
adapter = CategoriesAdapter(this) adapter = CategoriesAdapter(this)
editDelegate = CategoriesEditDelegate(this, this) editDelegate = CategoriesEditDelegate(this, this)
binding.recyclerView.addItemDecoration(MaterialDividerItemDecoration(this, RecyclerView.VERTICAL))
binding.recyclerView.setHasFixedSize(true) binding.recyclerView.setHasFixedSize(true)
binding.recyclerView.adapter = adapter binding.recyclerView.adapter = adapter
binding.fabAdd.setOnClickListener(this) binding.fabAdd.setOnClickListener(this)
@@ -94,15 +92,6 @@ class CategoriesActivity : BaseActivity<ActivityCategoriesBinding>(),
right = insets.right, right = insets.right,
bottom = 2 * insets.bottom + binding.fabAdd.measureHeight() bottom = 2 * insets.bottom + binding.fabAdd.measureHeight()
) )
with(binding.toolbar) {
updatePadding(
left = insets.left,
right = insets.right
)
updateLayoutParams<ViewGroup.MarginLayoutParams> {
topMargin = insets.top
}
}
} }
private fun onCategoriesChanged(categories: List<FavouriteCategory>) { private fun onCategoriesChanged(categories: List<FavouriteCategory>) {

View File

@@ -6,14 +6,13 @@ import com.hannesdorfmann.adapterdelegates4.dsl.adapterDelegate
import com.hannesdorfmann.adapterdelegates4.dsl.adapterDelegateViewBinding import com.hannesdorfmann.adapterdelegates4.dsl.adapterDelegateViewBinding
import org.koitharu.kotatsu.R import org.koitharu.kotatsu.R
import org.koitharu.kotatsu.core.ui.titleRes import org.koitharu.kotatsu.core.ui.titleRes
import org.koitharu.kotatsu.databinding.ItemCheckableMultipleBinding import org.koitharu.kotatsu.databinding.ItemCheckableNewBinding
import org.koitharu.kotatsu.databinding.ItemCheckableSingleBinding
import org.koitharu.kotatsu.databinding.ItemFilterHeaderBinding import org.koitharu.kotatsu.databinding.ItemFilterHeaderBinding
fun filterSortDelegate( fun filterSortDelegate(
listener: OnFilterChangedListener, listener: OnFilterChangedListener,
) = adapterDelegateViewBinding<FilterItem.Sort, FilterItem, ItemCheckableSingleBinding>( ) = adapterDelegateViewBinding<FilterItem.Sort, FilterItem, ItemCheckableNewBinding>(
{ layoutInflater, parent -> ItemCheckableSingleBinding.inflate(layoutInflater, parent, false) } { layoutInflater, parent -> ItemCheckableNewBinding.inflate(layoutInflater, parent, false) }
) { ) {
itemView.setOnClickListener { itemView.setOnClickListener {
@@ -28,8 +27,8 @@ fun filterSortDelegate(
fun filterTagDelegate( fun filterTagDelegate(
listener: OnFilterChangedListener, listener: OnFilterChangedListener,
) = adapterDelegateViewBinding<FilterItem.Tag, FilterItem, ItemCheckableMultipleBinding>( ) = adapterDelegateViewBinding<FilterItem.Tag, FilterItem, ItemCheckableNewBinding>(
{ layoutInflater, parent -> ItemCheckableMultipleBinding.inflate(layoutInflater, parent, false) } { layoutInflater, parent -> ItemCheckableNewBinding.inflate(layoutInflater, parent, false) }
) { ) {
itemView.setOnClickListener { itemView.setOnClickListener {

View File

@@ -13,10 +13,7 @@ import androidx.activity.result.ActivityResultCallback
import androidx.activity.result.contract.ActivityResultContracts import androidx.activity.result.contract.ActivityResultContracts
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import androidx.core.graphics.Insets import androidx.core.graphics.Insets
import androidx.core.view.WindowInsetsCompat import androidx.core.view.*
import androidx.core.view.isVisible
import androidx.core.view.postDelayed
import androidx.core.view.updatePadding
import androidx.fragment.app.commit import androidx.fragment.app.commit
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
import androidx.transition.Slide import androidx.transition.Slide
@@ -60,7 +57,7 @@ import org.koitharu.kotatsu.utils.ext.observeWithPrevious
class ReaderActivity : BaseFullscreenActivity<ActivityReaderBinding>(), class ReaderActivity : BaseFullscreenActivity<ActivityReaderBinding>(),
ChaptersBottomSheet.OnChapterChangeListener, ChaptersBottomSheet.OnChapterChangeListener,
GridTouchHelper.OnGridTouchListener, OnPageSelectListener, ReaderConfigDialog.Callback, GridTouchHelper.OnGridTouchListener, OnPageSelectListener, ReaderConfigDialog.Callback,
ActivityResultCallback<Boolean>, ReaderControlDelegate.OnInteractionListener { ActivityResultCallback<Boolean>, ReaderControlDelegate.OnInteractionListener, OnApplyWindowInsetsListener {
private val viewModel by viewModel<ReaderViewModel> { private val viewModel by viewModel<ReaderViewModel> {
parametersOf(MangaIntent(intent), intent?.getParcelableExtra<ReaderState>(EXTRA_STATE)) parametersOf(MangaIntent(intent), intent?.getParcelableExtra<ReaderState>(EXTRA_STATE))
@@ -87,6 +84,7 @@ class ReaderActivity : BaseFullscreenActivity<ActivityReaderBinding>(),
controlDelegate = ReaderControlDelegate(lifecycleScope, get(), this) controlDelegate = ReaderControlDelegate(lifecycleScope, get(), this)
binding.toolbarBottom.inflateMenu(R.menu.opt_reader_bottom) binding.toolbarBottom.inflateMenu(R.menu.opt_reader_bottom)
binding.toolbarBottom.setOnMenuItemClickListener(::onOptionsItemSelected) binding.toolbarBottom.setOnMenuItemClickListener(::onOptionsItemSelected)
insetsDelegate.interceptingWindowInsetsListener = this
orientationHelper.observeAutoOrientation() orientationHelper.observeAutoOrientation()
.onEach { .onEach {
@@ -286,8 +284,6 @@ class ReaderActivity : BaseFullscreenActivity<ActivityReaderBinding>(),
viewModel.switchMode(mode) viewModel.switchMode(mode)
} }
override fun onWindowInsetsChanged(insets: Insets) = Unit
private fun onPageSaved(uri: Uri?) { private fun onPageSaved(uri: Uri?) {
if (uri != null) { if (uri != null) {
Snackbar.make(binding.container, R.string.page_saved, Snackbar.LENGTH_INDEFINITE) Snackbar.make(binding.container, R.string.page_saved, Snackbar.LENGTH_INDEFINITE)
@@ -353,6 +349,8 @@ class ReaderActivity : BaseFullscreenActivity<ActivityReaderBinding>(),
.build() .build()
} }
override fun onWindowInsetsChanged(insets: Insets) = Unit
override fun switchPageBy(delta: Int) { override fun switchPageBy(delta: Int) {
reader?.switchPageBy(delta) reader?.switchPageBy(delta)
} }

View File

@@ -119,9 +119,6 @@ class MainSettingsFragment : BasePreferenceFragment(R.string.settings),
AppSettings.KEY_THEME_AMOLED -> { AppSettings.KEY_THEME_AMOLED -> {
findPreference<Preference>(key)?.setSummary(R.string.restart_required) findPreference<Preference>(key)?.setSummary(R.string.restart_required)
} }
AppSettings.KEY_HIDE_TOOLBAR -> {
findPreference<Preference>(key)?.setSummary(R.string.restart_required)
}
AppSettings.KEY_LOCAL_STORAGE -> { AppSettings.KEY_LOCAL_STORAGE -> {
findPreference<Preference>(key)?.bindStorageName() findPreference<Preference>(key)?.bindStorageName()
} }

View File

@@ -3,10 +3,7 @@ package org.koitharu.kotatsu.settings
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.os.Bundle import android.os.Bundle
import android.view.ViewGroup
import androidx.core.graphics.Insets import androidx.core.graphics.Insets
import androidx.core.view.updateLayoutParams
import androidx.core.view.updatePadding
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentManager import androidx.fragment.app.FragmentManager
import androidx.fragment.app.FragmentTransaction import androidx.fragment.app.FragmentTransaction
@@ -15,8 +12,10 @@ import androidx.preference.Preference
import androidx.preference.PreferenceFragmentCompat import androidx.preference.PreferenceFragmentCompat
import org.koitharu.kotatsu.R import org.koitharu.kotatsu.R
import org.koitharu.kotatsu.base.ui.BaseActivity import org.koitharu.kotatsu.base.ui.BaseActivity
import org.koitharu.kotatsu.base.ui.util.RecyclerViewOwner
import org.koitharu.kotatsu.databinding.ActivitySettingsBinding import org.koitharu.kotatsu.databinding.ActivitySettingsBinding
import org.koitharu.kotatsu.parsers.model.MangaSource import org.koitharu.kotatsu.parsers.model.MangaSource
import org.koitharu.kotatsu.utils.ext.isScrolledToTop
class SettingsActivity : BaseActivity<ActivitySettingsBinding>(), class SettingsActivity : BaseActivity<ActivitySettingsBinding>(),
PreferenceFragmentCompat.OnPreferenceStartFragmentCallback, PreferenceFragmentCompat.OnPreferenceStartFragmentCallback,
@@ -34,6 +33,11 @@ class SettingsActivity : BaseActivity<ActivitySettingsBinding>(),
} }
} }
override fun onTitleChanged(title: CharSequence?, color: Int) {
super.onTitleChanged(title, color)
binding.collapsingToolbarLayout.title = title
}
override fun onStart() { override fun onStart() {
super.onStart() super.onStart()
supportFragmentManager.addOnBackStackChangedListener(this) supportFragmentManager.addOnBackStackChangedListener(this)
@@ -45,7 +49,11 @@ class SettingsActivity : BaseActivity<ActivitySettingsBinding>(),
} }
override fun onBackStackChanged() { override fun onBackStackChanged() {
binding.appbar.setExpanded(true, true) val fragment = supportFragmentManager.findFragmentById(R.id.container) as? RecyclerViewOwner ?: return
val recyclerView = fragment.recyclerView
recyclerView.post {
binding.appbar.setExpanded(recyclerView.isScrolledToTop, false)
}
} }
override fun onPreferenceStartFragment( override fun onPreferenceStartFragment(
@@ -77,17 +85,7 @@ class SettingsActivity : BaseActivity<ActivitySettingsBinding>(),
} }
} }
override fun onWindowInsetsChanged(insets: Insets) { override fun onWindowInsetsChanged(insets: Insets) = Unit
with(binding.toolbar) {
updatePadding(
left = insets.left,
right = insets.right
)
updateLayoutParams<ViewGroup.MarginLayoutParams> {
topMargin = insets.top
}
}
}
companion object { companion object {

View File

@@ -3,12 +3,12 @@ package org.koitharu.kotatsu.settings
import android.os.Bundle import android.os.Bundle
import android.view.View import android.view.View
import androidx.preference.Preference import androidx.preference.Preference
import androidx.preference.PreferenceFragmentCompat
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import org.koitharu.kotatsu.BuildConfig import org.koitharu.kotatsu.BuildConfig
import org.koitharu.kotatsu.R import org.koitharu.kotatsu.R
import org.koitharu.kotatsu.base.ui.BasePreferenceFragment
import org.koitharu.kotatsu.core.parser.MangaRepository import org.koitharu.kotatsu.core.parser.MangaRepository
import org.koitharu.kotatsu.core.parser.RemoteMangaRepository import org.koitharu.kotatsu.core.parser.RemoteMangaRepository
import org.koitharu.kotatsu.parsers.exception.AuthRequiredException import org.koitharu.kotatsu.parsers.exception.AuthRequiredException
@@ -18,7 +18,7 @@ import org.koitharu.kotatsu.utils.ext.serializableArgument
import org.koitharu.kotatsu.utils.ext.viewLifecycleScope import org.koitharu.kotatsu.utils.ext.viewLifecycleScope
import org.koitharu.kotatsu.utils.ext.withArgs import org.koitharu.kotatsu.utils.ext.withArgs
class SourceSettingsFragment : PreferenceFragmentCompat() { class SourceSettingsFragment : BasePreferenceFragment(0) {
private val source by serializableArgument<MangaSource>(EXTRA_SOURCE) private val source by serializableArgument<MangaSource>(EXTRA_SOURCE)
private var repository: RemoteMangaRepository? = null private var repository: RemoteMangaRepository? = null

View File

@@ -11,19 +11,25 @@ import org.koin.android.ext.android.get
import org.koin.androidx.viewmodel.ext.android.viewModel import org.koin.androidx.viewmodel.ext.android.viewModel
import org.koitharu.kotatsu.R import org.koitharu.kotatsu.R
import org.koitharu.kotatsu.base.ui.BaseFragment import org.koitharu.kotatsu.base.ui.BaseFragment
import org.koitharu.kotatsu.base.ui.util.RecyclerViewOwner
import org.koitharu.kotatsu.databinding.FragmentSettingsSourcesBinding import org.koitharu.kotatsu.databinding.FragmentSettingsSourcesBinding
import org.koitharu.kotatsu.settings.SettingsActivity import org.koitharu.kotatsu.settings.SettingsActivity
import org.koitharu.kotatsu.settings.sources.adapter.SourceConfigAdapter import org.koitharu.kotatsu.settings.sources.adapter.SourceConfigAdapter
import org.koitharu.kotatsu.settings.sources.adapter.SourceConfigItemDecoration
import org.koitharu.kotatsu.settings.sources.adapter.SourceConfigListener import org.koitharu.kotatsu.settings.sources.adapter.SourceConfigListener
import org.koitharu.kotatsu.settings.sources.model.SourceConfigItem import org.koitharu.kotatsu.settings.sources.model.SourceConfigItem
class SourcesSettingsFragment : BaseFragment<FragmentSettingsSourcesBinding>(), class SourcesSettingsFragment : BaseFragment<FragmentSettingsSourcesBinding>(),
SourceConfigListener, SearchView.OnQueryTextListener, MenuItem.OnActionExpandListener { SourceConfigListener,
SearchView.OnQueryTextListener,
MenuItem.OnActionExpandListener,
RecyclerViewOwner {
private var reorderHelper: ItemTouchHelper? = null private var reorderHelper: ItemTouchHelper? = null
private val viewModel by viewModel<SourcesSettingsViewModel>() private val viewModel by viewModel<SourcesSettingsViewModel>()
override val recyclerView: RecyclerView
get() = binding.recyclerView
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
setHasOptionsMenu(true) setHasOptionsMenu(true)
@@ -44,7 +50,7 @@ class SourcesSettingsFragment : BaseFragment<FragmentSettingsSourcesBinding>(),
val sourcesAdapter = SourceConfigAdapter(this, get(), viewLifecycleOwner) val sourcesAdapter = SourceConfigAdapter(this, get(), viewLifecycleOwner)
with(binding.recyclerView) { with(binding.recyclerView) {
setHasFixedSize(true) setHasFixedSize(true)
addItemDecoration(SourceConfigItemDecoration(view.context)) // addItemDecoration(SourceConfigItemDecoration(view.context))
adapter = sourcesAdapter adapter = sourcesAdapter
reorderHelper = ItemTouchHelper(SourcesReorderCallback()).also { reorderHelper = ItemTouchHelper(SourcesReorderCallback()).also {
it.attachToRecyclerView(this) it.attachToRecyclerView(this)

View File

@@ -79,6 +79,7 @@ class SourcesSettingsViewModel(
} }
SourceConfigItem.SourceItem( SourceConfigItem.SourceItem(
source = it, source = it,
summary = null,
isEnabled = it.name !in hiddenSources, isEnabled = it.name !in hiddenSources,
isDraggable = false, isDraggable = false,
) )
@@ -101,6 +102,7 @@ class SourcesSettingsViewModel(
enabledSources.mapTo(result) { enabledSources.mapTo(result) {
SourceConfigItem.SourceItem( SourceConfigItem.SourceItem(
source = it, source = it,
summary = getLocaleTitle(it.locale),
isEnabled = true, isEnabled = true,
isDraggable = true, isDraggable = true,
) )
@@ -116,13 +118,14 @@ class SourcesSettingsViewModel(
val isExpanded = key in expandedGroups val isExpanded = key in expandedGroups
result += SourceConfigItem.LocaleGroup( result += SourceConfigItem.LocaleGroup(
localeId = key, localeId = key,
title = locale?.getDisplayLanguage(locale)?.toTitleCase(locale), title = getLocaleTitle(key),
isExpanded = isExpanded, isExpanded = isExpanded,
) )
if (isExpanded) { if (isExpanded) {
list.mapTo(result) { list.mapTo(result) {
SourceConfigItem.SourceItem( SourceConfigItem.SourceItem(
source = it, source = it,
summary = null,
isEnabled = false, isEnabled = false,
isDraggable = false, isDraggable = false,
) )
@@ -133,6 +136,11 @@ class SourcesSettingsViewModel(
items.value = result items.value = result
} }
private fun getLocaleTitle(localeKey: String?): String? {
val locale = Locale(localeKey ?: return null)
return locale.getDisplayLanguage(locale).toTitleCase(locale)
}
private class LocaleKeyComparator : Comparator<String?> { private class LocaleKeyComparator : Comparator<String?> {
private val deviceLocales = LocaleListCompat.getAdjustedDefault() private val deviceLocales = LocaleListCompat.getAdjustedDefault()

View File

@@ -38,7 +38,7 @@ fun sourceConfigGroupDelegate(
} }
bind { bind {
binding.root.text = item.title ?: getString(R.string.other) binding.root.text = item.title ?: getString(R.string.various_languages)
binding.root.isChecked = item.isExpanded binding.root.isChecked = item.isExpanded
} }
} }
@@ -107,6 +107,7 @@ fun sourceConfigDraggableItemDelegate(
bind { bind {
binding.textViewTitle.text = item.source.title binding.textViewTitle.text = item.source.title
binding.textViewDescription.text = item.summary ?: getString(R.string.various_languages)
binding.switchToggle.isChecked = item.isEnabled binding.switchToggle.isChecked = item.isEnabled
} }
} }

View File

@@ -50,6 +50,7 @@ sealed interface SourceConfigItem {
class SourceItem( class SourceItem(
val source: MangaSource, val source: MangaSource,
val isEnabled: Boolean, val isEnabled: Boolean,
val summary: String?,
val isDraggable: Boolean, val isDraggable: Boolean,
) : SourceConfigItem { ) : SourceConfigItem {
@@ -63,6 +64,7 @@ sealed interface SourceConfigItem {
other as SourceItem other as SourceItem
if (source != other.source) return false if (source != other.source) return false
if (summary != other.summary) return false
if (isEnabled != other.isEnabled) return false if (isEnabled != other.isEnabled) return false
if (isDraggable != other.isDraggable) return false if (isDraggable != other.isDraggable) return false
@@ -71,6 +73,7 @@ sealed interface SourceConfigItem {
override fun hashCode(): Int { override fun hashCode(): Int {
var result = source.hashCode() var result = source.hashCode()
result = 31 * result + summary.hashCode()
result = 31 * result + isEnabled.hashCode() result = 31 * result + isEnabled.hashCode()
result = 31 * result + isDraggable.hashCode() result = 31 * result + isDraggable.hashCode()
return result return result

View File

@@ -154,4 +154,13 @@ fun BaseProgressIndicator<*>.setIndeterminateCompat(indeterminate: Boolean) {
fun Slider.setValueRounded(newValue: Float) { fun Slider.setValueRounded(newValue: Float) {
val step = stepSize val step = stepSize
value = (newValue / step).roundToInt() * step value = (newValue / step).roundToInt() * step
} }
val RecyclerView.isScrolledToTop: Boolean
get() {
if (childCount == 0) {
return true
}
val holder = findViewHolderForAdapterPosition(0)
return holder != null && holder.itemView.top >= 0
}

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:alpha="0.3" android:color="?attr/colorPrimary" android:state_checked="true"/>
<item android:color="@android:color/transparent"/>
</selector>

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:alpha="@dimen/material_emphasis_disabled" android:color="?attr/colorOnSurfaceVariant" android:state_enabled="false" />
<item android:color="?attr/colorPrimaryDark" android:state_checked="true" />
<item android:color="?attr/colorOnSurfaceVariant" />
</selector>

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="?colorPrimaryContainer" android:state_checked="true" />
<item android:color="?colorSurfaceVariant" android:state_checked="false" />
</selector>

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="?colorPrimary" android:state_checked="true" />
<item android:color="?colorOnSurfaceVariant" android:state_checked="false" />
</selector>

View File

@@ -0,0 +1,11 @@
<vector
xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:tint="?colorControlNormal"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@android:color/white"
android:pathData="M9,16.17L4.83,12l-1.42,1.41L9,19 21,7l-1.41,-1.41L9,16.17z" />
</vector>

View File

@@ -1,5 +1,7 @@
<vector android:height="24dp" android:tint="#FFFFFF" <rotate
android:viewportHeight="24" android:viewportWidth="24" xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> android:drawable="@drawable/abc_ic_arrow_drop_right_black_24dp"
<path android:fillColor="@android:color/white" android:pathData="M12,8l-6,6 1.41,1.41L12,10.83l4.59,4.58L18,14z"/> android:fromDegrees="-90"
</vector> android:pivotX="50%"
android:pivotY="50%"
android:toDegrees="-90" />

View File

@@ -1,11 +1,7 @@
<vector <rotate
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp" android:drawable="@drawable/abc_ic_arrow_drop_right_black_24dp"
android:height="24dp" android:fromDegrees="90"
android:tint="#FFFFFF" android:pivotX="50%"
android:viewportWidth="24" android:pivotY="50%"
android:viewportHeight="24"> android:toDegrees="90" />
<path
android:fillColor="@android:color/white"
android:pathData="M16.59,8.59L12,13.17 7.41,8.59 6,10l6,6 6,-6z" />
</vector>

View File

@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:bottom="4dp"
android:left="4dp"
android:right="4dp"
android:top="4dp">
<shape android:shape="oval">
<solid android:color="#000000" />
<size
android:width="20dp"
android:height="20dp" />
</shape>
</item>
</layer-list>

View File

@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape android:shape="rectangle">
<solid android:color="#000000" />
<corners android:radius="56dp" />
<size
android:width="64dp"
android:height="28dp" />
</shape>
</item>
</layer-list>

View File

@@ -14,11 +14,21 @@
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"> app:layout_constraintTop_toTopOf="parent">
<com.google.android.material.appbar.MaterialToolbar <com.google.android.material.appbar.CollapsingToolbarLayout
android:id="@id/toolbar" android:id="@+id/collapsingToolbarLayout"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="@dimen/toolbar_height_expanded"
app:layout_scrollFlags="scroll|enterAlways" /> app:toolbarId="@id/toolbar"
app:layout_scrollFlags="scroll|exitUntilCollapsed">
<com.google.android.material.appbar.MaterialToolbar
android:id="@id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:layout_collapseMode="pin" />
</com.google.android.material.appbar.CollapsingToolbarLayout>
</com.google.android.material.appbar.AppBarLayout> </com.google.android.material.appbar.AppBarLayout>

View File

@@ -31,9 +31,9 @@
android:id="@+id/appbar" android:id="@+id/appbar"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
app:elevation="0dp"
android:paddingLeft="16dp" android:paddingLeft="16dp"
android:paddingRight="16dp" android:paddingRight="16dp"
app:elevation="0dp"
app:liftOnScroll="false"> app:liftOnScroll="false">
<FrameLayout <FrameLayout
@@ -41,7 +41,9 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="54dp" android:layout_height="54dp"
android:layout_marginVertical="8dp" android:layout_marginVertical="8dp"
android:background="@drawable/toolbar_background"> android:background="@drawable/toolbar_background"
android:theme="@style/ThemeOverlay.Kotatsu.MainToolbar"
app:layout_scrollFlags="scroll|enterAlways">
<com.google.android.material.appbar.MaterialToolbar <com.google.android.material.appbar.MaterialToolbar
android:id="@id/toolbar" android:id="@id/toolbar"

View File

@@ -69,11 +69,15 @@
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" /> app:layout_constraintStart_toStartOf="parent" />
<androidx.constraintlayout.widget.Guideline <View
android:id="@+id/guideline" android:id="@+id/guideline"
android:layout_width="wrap_content" android:layout_width="1dp"
android:layout_height="wrap_content" android:layout_height="0dp"
android:orientation="vertical" android:background="?colorOutline"
app:layout_constraintGuide_percent="0.6" /> app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.6"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/appbar" />
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -8,14 +8,24 @@
<com.google.android.material.appbar.AppBarLayout <com.google.android.material.appbar.AppBarLayout
android:id="@+id/appbar" android:id="@+id/appbar"
android:fitsSystemWindows="true"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content"> android:layout_height="wrap_content">
<com.google.android.material.appbar.MaterialToolbar <com.google.android.material.appbar.CollapsingToolbarLayout
android:id="@+id/toolbar" android:id="@+id/collapsingToolbarLayout"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize" android:layout_height="@dimen/toolbar_height_expanded"
android:theme="?attr/actionBarTheme" /> app:layout_scrollFlags="scroll|exitUntilCollapsed"
app:toolbarId="@id/toolbar">
<com.google.android.material.appbar.MaterialToolbar
android:id="@id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:layout_collapseMode="pin" />
</com.google.android.material.appbar.CollapsingToolbarLayout>
</com.google.android.material.appbar.AppBarLayout> </com.google.android.material.appbar.AppBarLayout>

View File

@@ -10,14 +10,22 @@
android:id="@+id/appbar" android:id="@+id/appbar"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:fitsSystemWindows="true" android:fitsSystemWindows="true">
app:elevation="0dp">
<com.google.android.material.appbar.MaterialToolbar <com.google.android.material.appbar.CollapsingToolbarLayout
android:id="@+id/toolbar" android:id="@+id/collapsingToolbarLayout"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize" android:layout_height="@dimen/toolbar_height_expanded"
android:theme="?attr/actionBarTheme"/> app:layout_scrollFlags="scroll|exitUntilCollapsed"
app:toolbarId="@id/toolbar">
<com.google.android.material.appbar.MaterialToolbar
android:id="@id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:layout_collapseMode="pin" />
</com.google.android.material.appbar.CollapsingToolbarLayout>
</com.google.android.material.appbar.AppBarLayout> </com.google.android.material.appbar.AppBarLayout>

View File

@@ -15,16 +15,16 @@
android:id="@id/container" android:id="@id/container"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
tools:layout="@layout/fragment_list" app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior"
app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior" /> tools:layout="@layout/fragment_list" />
<com.google.android.material.appbar.AppBarLayout <com.google.android.material.appbar.AppBarLayout
android:id="@+id/appbar" android:id="@+id/appbar"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:background="@null"
android:paddingLeft="16dp" android:paddingLeft="16dp"
android:paddingRight="16dp" android:paddingRight="16dp"
android:background="@null"
android:stateListAnimator="@null"> android:stateListAnimator="@null">
<FrameLayout <FrameLayout
@@ -32,7 +32,9 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="48dp" android:layout_height="48dp"
android:layout_marginVertical="8dp" android:layout_marginVertical="8dp"
android:background="@drawable/toolbar_background"> android:background="@drawable/toolbar_background"
android:theme="@style/ThemeOverlay.Kotatsu.MainToolbar"
app:layout_scrollFlags="scroll|enterAlways">
<com.google.android.material.appbar.MaterialToolbar <com.google.android.material.appbar.MaterialToolbar
android:id="@id/toolbar" android:id="@id/toolbar"

View File

@@ -22,6 +22,7 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center_vertical" android:layout_gravity="center_vertical"
app:iconifiedByDefault="false" app:iconifiedByDefault="false"
app:queryBackground="@null"
app:searchHintIcon="@null" app:searchHintIcon="@null"
app:searchIcon="@null" /> app:searchIcon="@null" />

View File

@@ -14,7 +14,7 @@
android:id="@id/toolbar" android:id="@id/toolbar"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize" android:layout_height="?attr/actionBarSize"
android:theme="?attr/actionBarTheme" /> app:layout_scrollFlags="scroll|enterAlways" />
</com.google.android.material.appbar.AppBarLayout> </com.google.android.material.appbar.AppBarLayout>

View File

@@ -8,14 +8,23 @@
<com.google.android.material.appbar.AppBarLayout <com.google.android.material.appbar.AppBarLayout
android:id="@+id/appbar" android:id="@+id/appbar"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content"> android:layout_height="wrap_content"
android:fitsSystemWindows="true">
<com.google.android.material.appbar.MaterialToolbar <com.google.android.material.appbar.CollapsingToolbarLayout
android:id="@id/toolbar" android:id="@+id/collapsingToolbarLayout"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize" android:layout_height="@dimen/toolbar_height_expanded"
android:theme="?attr/actionBarTheme" app:layout_scrollFlags="scroll|exitUntilCollapsed"
app:layout_scrollFlags="noScroll"/> app:toolbarId="@id/toolbar">
<com.google.android.material.appbar.MaterialToolbar
android:id="@id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:layout_collapseMode="pin" />
</com.google.android.material.appbar.CollapsingToolbarLayout>
</com.google.android.material.appbar.AppBarLayout> </com.google.android.material.appbar.AppBarLayout>
@@ -23,6 +32,6 @@
android:id="@id/container" android:id="@id/container"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior"/> app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior" />
</androidx.coordinatorlayout.widget.CoordinatorLayout> </androidx.coordinatorlayout.widget.CoordinatorLayout>

View File

@@ -10,11 +10,19 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content"> android:layout_height="wrap_content">
<com.google.android.material.appbar.MaterialToolbar <com.google.android.material.appbar.CollapsingToolbarLayout
android:id="@id/toolbar"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="@dimen/toolbar_height_expanded"
app:layout_scrollFlags="noScroll" /> app:toolbarId="@id/toolbar"
app:layout_scrollFlags="scroll|exitUntilCollapsed">
<com.google.android.material.appbar.MaterialToolbar
android:id="@id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:layout_collapseMode="pin" />
</com.google.android.material.appbar.CollapsingToolbarLayout>
</com.google.android.material.appbar.AppBarLayout> </com.google.android.material.appbar.AppBarLayout>

View File

@@ -14,7 +14,7 @@
android:id="@+id/textView_number" android:id="@+id/textView_number"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="12dp" android:layout_marginStart="?android:listPreferredItemPaddingStart"
android:background="@drawable/bg_badge_default" android:background="@drawable/bg_badge_default"
android:gravity="center" android:gravity="center"
android:minWidth="26dp" android:minWidth="26dp"
@@ -26,8 +26,8 @@
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginVertical="8dp" android:layout_marginVertical="8dp"
android:layout_marginStart="16dp" android:layout_marginStart="?android:listPreferredItemPaddingStart"
android:layout_marginEnd="12dp" android:layout_marginEnd="?android:listPreferredItemPaddingEnd"
android:layout_weight="1" android:layout_weight="1"
android:orientation="vertical"> android:orientation="vertical">
@@ -37,7 +37,7 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:ellipsize="end" android:ellipsize="end"
android:singleLine="true" android:singleLine="true"
android:textAppearance="?attr/textAppearanceBodyMedium" android:textAppearance="?attr/textAppearanceBodyLarge"
tools:text="@tools:sample/lorem[15]" /> tools:text="@tools:sample/lorem[15]" />
<TextView <TextView
@@ -46,6 +46,7 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:ellipsize="end" android:ellipsize="end"
android:singleLine="true" android:singleLine="true"
android:layout_marginTop="2dp"
android:textAppearance="?attr/textAppearanceBodySmall" android:textAppearance="?attr/textAppearanceBodySmall"
tools:text="05.10.2021 • Scanlator" /> tools:text="05.10.2021 • Scanlator" />
</LinearLayout> </LinearLayout>
@@ -54,7 +55,7 @@
android:id="@+id/imageView_new" android:id="@+id/imageView_new"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginEnd="12dp" android:layout_marginEnd="?android:listPreferredItemPaddingEnd"
android:src="@drawable/ic_new" android:src="@drawable/ic_new"
app:tint="?colorError" /> app:tint="?colorError" />
@@ -62,7 +63,7 @@
android:id="@+id/imageView_downloaded" android:id="@+id/imageView_downloaded"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginEnd="12dp" android:layout_marginEnd="?android:listPreferredItemPaddingEnd"
android:src="@drawable/ic_save_ok" /> android:src="@drawable/ic_save_ok" />
</LinearLayout> </LinearLayout>

View File

@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<org.koitharu.kotatsu.base.ui.widgets.ListItemTextView
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"
android:layout_height="?android:listPreferredItemHeightSmall"
android:drawablePadding="?android:listPreferredItemPaddingStart"
android:paddingStart="?android:listPreferredItemPaddingStart"
android:paddingEnd="?android:listPreferredItemPaddingEnd"
android:textAppearance="?attr/textAppearanceButton"
app:rippleColor="?colorSecondaryContainer"
tools:text="@tools:sample/full_names" />

View File

@@ -12,5 +12,5 @@
android:paddingEnd="?android:listPreferredItemPaddingEnd" android:paddingEnd="?android:listPreferredItemPaddingEnd"
android:textAppearance="?attr/textAppearanceBodyMedium" android:textAppearance="?attr/textAppearanceBodyMedium"
app:drawableEndCompat="@drawable/ic_expand_collapse" app:drawableEndCompat="@drawable/ic_expand_collapse"
app:drawableTint="?android:textColorPrimary" app:drawableTint="?android:colorControlNormal"
tools:text="@tools:sample/full_names" /> tools:text="@tools:sample/full_names" />

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<LinearLayout <FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
@@ -14,23 +14,20 @@
android:id="@+id/textView_title" android:id="@+id/textView_title"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center_vertical|start"
android:singleLine="true" android:singleLine="true"
android:textAppearance="@style/TextAppearance.Kotatsu.SectionHeader" android:textAppearance="@style/TextAppearance.Kotatsu.SectionHeader2"
tools:text="@tools:sample/lorem[2]" /> tools:text="@tools:sample/lorem[2]" />
<TextView <TextView
android:id="@+id/badge" android:id="@+id/badge"
style="?textAppearanceLabelSmall"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="12dp" android:layout_gravity="center_vertical|end"
android:background="@drawable/badge" android:singleLine="true"
android:paddingHorizontal="6dp"
android:paddingVertical="2dp"
android:textColor="?attr/colorOnTertiary"
android:textSize="12sp"
android:textStyle="bold"
android:visibility="gone" android:visibility="gone"
tools:text="54" tools:text="54"
tools:visibility="visible" /> tools:visibility="visible" />
</LinearLayout> </FrameLayout>

View File

@@ -3,9 +3,10 @@
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="?android:listPreferredItemHeightSmall" android:layout_height="wrap_content"
android:background="?android:windowBackground" android:background="?android:windowBackground"
android:gravity="center_vertical" android:gravity="center_vertical"
android:minHeight="58dp"
android:orientation="horizontal"> android:orientation="horizontal">
<ImageView <ImageView
@@ -16,17 +17,35 @@
android:scaleType="center" android:scaleType="center"
android:src="@drawable/ic_reorder_handle" /> android:src="@drawable/ic_reorder_handle" />
<TextView <LinearLayout
android:id="@+id/textView_title"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginVertical="8dp"
android:layout_marginStart="?android:listPreferredItemPaddingStart"
android:layout_marginEnd="?android:listPreferredItemPaddingEnd"
android:layout_weight="1" android:layout_weight="1"
android:ellipsize="marquee" android:orientation="vertical">
android:fadingEdge="horizontal"
android:singleLine="true" <TextView
android:textAppearance="?android:attr/textAppearanceMedium" android:id="@+id/textView_title"
android:textColor="?android:attr/textColorPrimary" android:layout_width="match_parent"
tools:text="@tools:sample/lorem[1]" /> android:layout_height="wrap_content"
android:ellipsize="end"
android:singleLine="true"
android:textAppearance="?attr/textAppearanceBodyLarge"
tools:text="@tools:sample/lorem[15]" />
<TextView
android:id="@+id/textView_description"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="2dp"
android:ellipsize="end"
android:singleLine="true"
android:textAppearance="?attr/textAppearanceBodySmall"
tools:text="English" />
</LinearLayout>
<com.google.android.material.switchmaterial.SwitchMaterial <com.google.android.material.switchmaterial.SwitchMaterial
android:id="@+id/switch_toggle" android:id="@+id/switch_toggle"

View File

@@ -37,6 +37,7 @@
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginBottom="4dp" android:layout_marginBottom="4dp"
android:layout_marginEnd="4dp"
android:layout_weight="1" android:layout_weight="1"
android:ellipsize="end" android:ellipsize="end"
android:maxLines="2" android:maxLines="2"
@@ -61,7 +62,7 @@
<TextView <TextView
android:id="@+id/textView_chapters" android:id="@+id/textView_chapters"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="0dp"
android:layout_weight="1" android:layout_weight="1"
android:ellipsize="none" android:ellipsize="none"
android:lineSpacingExtra="4sp" android:lineSpacingExtra="4sp"

View File

@@ -27,7 +27,6 @@
android:layout_height="match_parent" android:layout_height="match_parent"
android:clipToPadding="false" android:clipToPadding="false"
android:orientation="vertical" android:orientation="vertical"
app:fastScrollEnabled="true"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
tools:listitem="@layout/item_category_checkable" /> tools:listitem="@layout/item_checkable_new" />
</LinearLayout> </LinearLayout>

View File

@@ -2,6 +2,7 @@
<resources> <resources>
<attr name="sliderPreferenceStyle" /> <attr name="sliderPreferenceStyle" />
<attr name="listItemTextViewStyle" />
<declare-styleable name="Theme"> <declare-styleable name="Theme">
<attr name="navigationBarDividerColor" format="color" /> <attr name="navigationBarDividerColor" format="color" />
@@ -20,4 +21,17 @@
<attr name="android:stepSize" /> <attr name="android:stepSize" />
</declare-styleable> </declare-styleable>
<declare-styleable name="ListItemTextView">
<attr name="shapeAppearance" />
<attr name="shapeAppearanceOverlay" />
<attr name="backgroundTint" />
<attr name="rippleColor" />
<attr name="checkedDrawableStart" format="reference" />
<attr name="checkedDrawableEnd" format="reference" />
<attr name="android:insetTop" />
<attr name="android:insetBottom" />
<attr name="android:insetLeft" />
<attr name="android:insetRight" />
</declare-styleable>
</resources> </resources>

View File

@@ -7,12 +7,13 @@
<!-- Navigation --> <!-- Navigation -->
<dimen name="nav_header_logo_size">36dp</dimen> <dimen name="nav_header_logo_size">36dp</dimen>
<dimen name="toolbar_height_expanded">172dp</dimen>
<dimen name="grid_spacing">8dp</dimen> <dimen name="grid_spacing">8dp</dimen>
<dimen name="list_spacing">8dp</dimen> <dimen name="list_spacing">8dp</dimen>
<dimen name="grid_spacing_outer">2dp</dimen> <dimen name="grid_spacing_outer">2dp</dimen>
<dimen name="manga_list_item_height">86dp</dimen> <dimen name="manga_list_item_height">86dp</dimen>
<dimen name="manga_list_details_item_height">120dp</dimen> <dimen name="manga_list_details_item_height">120dp</dimen>
<dimen name="chapter_list_item_height">56dp</dimen> <dimen name="chapter_list_item_height">62dp</dimen>
<dimen name="preferred_grid_width">120dp</dimen> <dimen name="preferred_grid_width">120dp</dimen>
<dimen name="header_height">48dp</dimen> <dimen name="header_height">48dp</dimen>
<dimen name="list_footer_height_inner">36dp</dimen> <dimen name="list_footer_height_inner">36dp</dimen>

View File

@@ -268,4 +268,5 @@
<string name="preload_pages">Preload pages</string> <string name="preload_pages">Preload pages</string>
<string name="logged_in_as">Logged in as %s</string> <string name="logged_in_as">Logged in as %s</string>
<string name="nsfw">18+</string> <string name="nsfw">18+</string>
<string name="various_languages">Various languages</string>
</resources> </resources>

View File

@@ -61,6 +61,10 @@
</style> </style>
<style name="Widget.Kotatsu.Switch" parent="Widget.Material3.CompoundButton.Switch"> <style name="Widget.Kotatsu.Switch" parent="Widget.Material3.CompoundButton.Switch">
<item name="android:thumb">@drawable/switch_thumb</item>
<item name="thumbTint">@color/selector_switch_thumb</item>
<item name="track">@drawable/switch_track</item>
<item name="trackTint">@color/selector_switch_track</item>
<item name="materialThemeOverlay">@style/ThemeOverlay.Kotatsu.Switch</item> <item name="materialThemeOverlay">@style/ThemeOverlay.Kotatsu.Switch</item>
</style> </style>
@@ -72,6 +76,18 @@
<item name="android:scrollbarStyle">outsideOverlay</item> <item name="android:scrollbarStyle">outsideOverlay</item>
</style> </style>
<style name="Widget.Kotatsu.ListItemTextView" parent="">
<item name="android:textColor">@color/list_item_text_color</item>
<item name="backgroundTint">@color/list_item_background_color</item>
<item name="checkedDrawableStart">@drawable/ic_check</item>
<item name="shapeAppearanceOverlay">@style/ShapeAppearanceOverlay.Material3.NavigationView.Item</item>
<item name="android:gravity">center_vertical|start</item>
<item name="android:insetRight">6dp</item>
<item name="android:insetLeft">6dp</item>
<item name="android:insetTop">2dp</item>
<item name="android:insetBottom">2dp</item>
</style>
<style name="ThemeOverlay.Kotatsu.Switch" parent=""> <style name="ThemeOverlay.Kotatsu.Switch" parent="">
<item name="elevationOverlayEnabled">@bool/elevation_overlay_enabled</item> <item name="elevationOverlayEnabled">@bool/elevation_overlay_enabled</item>
</style> </style>
@@ -98,6 +114,11 @@
<item name="android:textColor">?android:attr/textColorSecondary</item> <item name="android:textColor">?android:attr/textColorSecondary</item>
</style> </style>
<style name="TextAppearance.Kotatsu.SectionHeader2" parent="TextAppearance.Material3.LabelSmall">
<item name="android:textColor">?colorPrimary</item>
<item name="android:textAllCaps">true</item>
</style>
<!-- Shapes --> <!-- Shapes -->
<style name="ShapeAppearanceOverlay.Kotatsu.Cover" parent=""> <style name="ShapeAppearanceOverlay.Kotatsu.Cover" parent="">

View File

@@ -68,6 +68,7 @@
<item name="switchStyle">@style/Widget.Kotatsu.Switch</item> <item name="switchStyle">@style/Widget.Kotatsu.Switch</item>
<item name="materialCardViewStyle">@style/Widget.Material3.CardView.Filled</item> <item name="materialCardViewStyle">@style/Widget.Material3.CardView.Filled</item>
<item name="recyclerViewStyle">@style/Widget.Kotatsu.RecyclerView</item> <item name="recyclerViewStyle">@style/Widget.Kotatsu.RecyclerView</item>
<item name="listItemTextViewStyle">@style/Widget.Kotatsu.ListItemTextView</item>
<!-- Preference text appearance --> <!-- Preference text appearance -->
<item name="android:textAppearanceListItem">?attr/textAppearanceBodyLarge</item> <item name="android:textAppearanceListItem">?attr/textAppearanceBodyLarge</item>

View File

@@ -15,7 +15,7 @@
app:persistent="false" app:persistent="false"
app:summary="@string/check_for_updates" /> app:summary="@string/check_for_updates" />
<SwitchPreference <SwitchPreferenceCompat
app:defaultValue="true" app:defaultValue="true"
app:iconSpaceReserved="false" app:iconSpaceReserved="false"
app:isPreferenceVisible="false" app:isPreferenceVisible="false"

View File

@@ -12,14 +12,14 @@
app:iconSpaceReserved="false" app:iconSpaceReserved="false"
app:useSimpleSummaryProvider="true" /> app:useSimpleSummaryProvider="true" />
<SwitchPreference <SwitchPreferenceCompat
android:defaultValue="false" android:defaultValue="false"
android:key="dynamic_theme" android:key="dynamic_theme"
android:summary="@string/dynamic_theme_summary" android:summary="@string/dynamic_theme_summary"
android:title="@string/dynamic_theme" android:title="@string/dynamic_theme"
app:iconSpaceReserved="false" /> app:iconSpaceReserved="false" />
<SwitchPreference <SwitchPreferenceCompat
android:defaultValue="false" android:defaultValue="false"
android:key="amoled_theme" android:key="amoled_theme"
android:summary="@string/black_dark_theme_summary" android:summary="@string/black_dark_theme_summary"
@@ -31,12 +31,6 @@
android:title="@string/date_format" android:title="@string/date_format"
app:iconSpaceReserved="false" /> app:iconSpaceReserved="false" />
<SwitchPreferenceCompat
android:defaultValue="true"
android:key="hide_toolbar"
android:title="@string/hide_toolbar"
app:iconSpaceReserved="false" />
<ListPreference <ListPreference
android:entries="@array/list_modes" android:entries="@array/list_modes"
android:key="list_mode_2" android:key="list_mode_2"

View File

@@ -11,7 +11,7 @@
android:title="@string/track_sources" android:title="@string/track_sources"
app:iconSpaceReserved="false" /> app:iconSpaceReserved="false" />
<SwitchPreference <SwitchPreferenceCompat
android:defaultValue="true" android:defaultValue="true"
android:key="tracker_notifications" android:key="tracker_notifications"
android:summary="@string/show_notification_new_chapters" android:summary="@string/show_notification_new_chapters"