Edge-to-edge ui
This commit is contained in:
@@ -7,13 +7,18 @@ import android.view.View
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.appcompat.widget.Toolbar
|
||||
import androidx.core.app.ActivityCompat
|
||||
import androidx.core.graphics.Insets
|
||||
import androidx.core.view.OnApplyWindowInsetsListener
|
||||
import androidx.core.view.ViewCompat
|
||||
import androidx.core.view.WindowCompat
|
||||
import androidx.core.view.WindowInsetsCompat
|
||||
import androidx.viewbinding.ViewBinding
|
||||
import org.koin.android.ext.android.get
|
||||
import org.koitharu.kotatsu.BuildConfig
|
||||
import org.koitharu.kotatsu.R
|
||||
import org.koitharu.kotatsu.core.prefs.AppSettings
|
||||
|
||||
abstract class BaseActivity<B : ViewBinding> : AppCompatActivity() {
|
||||
abstract class BaseActivity<B : ViewBinding> : AppCompatActivity(), OnApplyWindowInsetsListener {
|
||||
|
||||
protected lateinit var binding: B
|
||||
private set
|
||||
@@ -23,6 +28,7 @@ abstract class BaseActivity<B : ViewBinding> : AppCompatActivity() {
|
||||
setTheme(R.style.AppTheme_Amoled)
|
||||
}
|
||||
super.onCreate(savedInstanceState)
|
||||
WindowCompat.setDecorFitsSystemWindows(window, false)
|
||||
}
|
||||
|
||||
@Deprecated("Use ViewBinding", level = DeprecationLevel.ERROR)
|
||||
@@ -41,10 +47,12 @@ abstract class BaseActivity<B : ViewBinding> : AppCompatActivity() {
|
||||
this.binding = binding
|
||||
super.setContentView(binding.root)
|
||||
(binding.root.findViewById<View>(R.id.toolbar) as? Toolbar)?.let(this::setSupportActionBar)
|
||||
ViewCompat.setOnApplyWindowInsetsListener(binding.root, this)
|
||||
}
|
||||
|
||||
private fun setupToolbar() {
|
||||
(findViewById<View>(R.id.toolbar) as? Toolbar)?.let(this::setSupportActionBar)
|
||||
override fun onApplyWindowInsets(v: View, insets: WindowInsetsCompat): WindowInsetsCompat {
|
||||
onWindowInsetsChanged(insets.getInsets(WindowInsetsCompat.Type.systemBars()))
|
||||
return insets
|
||||
}
|
||||
|
||||
override fun onOptionsItemSelected(item: MenuItem) = if (item.itemId == android.R.id.home) {
|
||||
@@ -59,4 +67,11 @@ abstract class BaseActivity<B : ViewBinding> : AppCompatActivity() {
|
||||
}
|
||||
return super.onKeyDown(keyCode, event)
|
||||
}
|
||||
|
||||
protected abstract fun onWindowInsetsChanged(insets: Insets)
|
||||
|
||||
private fun setupToolbar() {
|
||||
(findViewById<View>(R.id.toolbar) as? Toolbar)?.let(this::setSupportActionBar)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -5,10 +5,14 @@ import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
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.fragment.app.Fragment
|
||||
import androidx.viewbinding.ViewBinding
|
||||
|
||||
abstract class BaseFragment<B : ViewBinding> : Fragment() {
|
||||
abstract class BaseFragment<B : ViewBinding> : Fragment(), OnApplyWindowInsetsListener {
|
||||
|
||||
private var viewBinding: B? = null
|
||||
|
||||
@@ -25,6 +29,11 @@ abstract class BaseFragment<B : ViewBinding> : Fragment() {
|
||||
return binding.root
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
ViewCompat.setOnApplyWindowInsetsListener(view, this)
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
viewBinding = null
|
||||
super.onDestroyView()
|
||||
@@ -39,7 +48,14 @@ abstract class BaseFragment<B : ViewBinding> : Fragment() {
|
||||
}
|
||||
}
|
||||
|
||||
override fun onApplyWindowInsets(v: View?, insets: WindowInsetsCompat): WindowInsetsCompat {
|
||||
onWindowInsetsChanged(insets.getInsets(WindowInsetsCompat.Type.systemBars()))
|
||||
return insets
|
||||
}
|
||||
|
||||
protected fun bindingOrNull() = viewBinding
|
||||
|
||||
protected abstract fun onInflateView(inflater: LayoutInflater, container: ViewGroup?): B
|
||||
|
||||
protected abstract fun onWindowInsetsChanged(insets: Insets)
|
||||
}
|
||||
|
||||
@@ -3,16 +3,22 @@ package org.koitharu.kotatsu.base.ui
|
||||
import android.graphics.Color
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import android.view.WindowManager
|
||||
import androidx.core.view.WindowInsetsCompat
|
||||
import androidx.core.view.WindowInsetsControllerCompat
|
||||
import androidx.viewbinding.ViewBinding
|
||||
|
||||
|
||||
abstract class BaseFullscreenActivity<B : ViewBinding> : BaseActivity<B>() {
|
||||
|
||||
private lateinit var insetsControllerCompat: WindowInsetsControllerCompat
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
with(window) {
|
||||
insetsControllerCompat = WindowInsetsControllerCompat(this, decorView)
|
||||
insetsControllerCompat.systemBarsBehavior =
|
||||
WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
|
||||
statusBarColor = Color.TRANSPARENT
|
||||
navigationBarColor = Color.TRANSPARENT
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
|
||||
@@ -24,20 +30,11 @@ abstract class BaseFullscreenActivity<B : ViewBinding> : BaseActivity<B>() {
|
||||
}
|
||||
|
||||
protected fun hideSystemUI() {
|
||||
window.decorView.systemUiVisibility = (
|
||||
View.SYSTEM_UI_FLAG_LAYOUT_STABLE
|
||||
or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
|
||||
or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
|
||||
or View.SYSTEM_UI_FLAG_HIDE_NAVIGATION // прячем панель навигации
|
||||
or View.SYSTEM_UI_FLAG_FULLSCREEN // прячем строку состояния
|
||||
or View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
|
||||
)
|
||||
insetsControllerCompat.hide(WindowInsetsCompat.Type.systemBars())
|
||||
|
||||
}
|
||||
|
||||
protected fun showSystemUI() {
|
||||
window.decorView.systemUiVisibility =
|
||||
(View.SYSTEM_UI_FLAG_LAYOUT_STABLE or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
|
||||
or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN)
|
||||
insetsControllerCompat.show(WindowInsetsCompat.Type.systemBars())
|
||||
}
|
||||
}
|
||||
@@ -1,17 +1,39 @@
|
||||
package org.koitharu.kotatsu.base.ui
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import androidx.annotation.StringRes
|
||||
import androidx.core.view.OnApplyWindowInsetsListener
|
||||
import androidx.core.view.ViewCompat
|
||||
import androidx.core.view.WindowInsetsCompat
|
||||
import androidx.core.view.updatePadding
|
||||
import androidx.preference.PreferenceFragmentCompat
|
||||
import org.koin.android.ext.android.inject
|
||||
import org.koitharu.kotatsu.core.prefs.AppSettings
|
||||
|
||||
abstract class BasePreferenceFragment(@StringRes private val titleId: Int) :
|
||||
PreferenceFragmentCompat() {
|
||||
PreferenceFragmentCompat(), OnApplyWindowInsetsListener {
|
||||
|
||||
protected val settings by inject<AppSettings>()
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
listView.clipToPadding = false
|
||||
ViewCompat.setOnApplyWindowInsetsListener(view, this)
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
activity?.setTitle(titleId)
|
||||
}
|
||||
|
||||
override fun onApplyWindowInsets(v: View?, insets: WindowInsetsCompat): WindowInsetsCompat {
|
||||
val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars())
|
||||
listView.updatePadding(
|
||||
left = systemBars.left,
|
||||
right = systemBars.right,
|
||||
bottom = systemBars.bottom
|
||||
)
|
||||
return WindowInsetsCompat.CONSUMED
|
||||
}
|
||||
}
|
||||
@@ -8,7 +8,9 @@ import android.net.Uri
|
||||
import android.os.Bundle
|
||||
import android.view.Menu
|
||||
import android.view.MenuItem
|
||||
import androidx.core.graphics.Insets
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.core.view.updatePadding
|
||||
import org.koitharu.kotatsu.R
|
||||
import org.koitharu.kotatsu.base.ui.BaseActivity
|
||||
import org.koitharu.kotatsu.databinding.ActivityBrowserBinding
|
||||
@@ -85,6 +87,11 @@ class BrowserActivity : BaseActivity<ActivityBrowserBinding>(), BrowserCallback
|
||||
supportActionBar?.subtitle = subtitle
|
||||
}
|
||||
|
||||
override fun onWindowInsetsChanged(insets: Insets) {
|
||||
binding.appbar.updatePadding(top = insets.top)
|
||||
binding.webView.updatePadding(bottom = insets.bottom)
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
fun newIntent(context: Context, url: String) = Intent(context, BrowserActivity::class.java)
|
||||
|
||||
@@ -5,7 +5,9 @@ import android.os.Bundle
|
||||
import android.view.*
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.appcompat.view.ActionMode
|
||||
import androidx.core.graphics.Insets
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.core.view.updatePadding
|
||||
import androidx.recyclerview.widget.DividerItemDecoration
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import org.koin.androidx.viewmodel.ext.android.sharedViewModel
|
||||
@@ -149,4 +151,12 @@ class ChaptersFragment : BaseFragment<FragmentChaptersBinding>(),
|
||||
binding.recyclerViewChapters.invalidateItemDecorations()
|
||||
actionMode = null
|
||||
}
|
||||
|
||||
override fun onWindowInsetsChanged(insets: Insets) {
|
||||
binding.recyclerViewChapters.updatePadding(
|
||||
left = insets.left,
|
||||
right = insets.right,
|
||||
bottom = insets.bottom
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -9,9 +9,12 @@ import android.view.MenuItem
|
||||
import android.widget.Toast
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import androidx.appcompat.view.ActionMode
|
||||
import androidx.appcompat.widget.Toolbar
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.core.content.pm.ShortcutManagerCompat
|
||||
import androidx.core.graphics.Insets
|
||||
import androidx.core.net.toFile
|
||||
import androidx.core.view.updatePadding
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import com.google.android.material.snackbar.Snackbar
|
||||
import com.google.android.material.tabs.TabLayout
|
||||
@@ -77,6 +80,20 @@ class DetailsActivity : BaseActivity<ActivityDetailsBinding>(),
|
||||
}
|
||||
}
|
||||
|
||||
override fun onWindowInsetsChanged(insets: Insets) {
|
||||
binding.toolbar.updatePadding(
|
||||
top = insets.top,
|
||||
left = insets.left,
|
||||
right = insets.right
|
||||
)
|
||||
if (binding.tabs.parent !is Toolbar) {
|
||||
binding.tabs.updatePadding(
|
||||
left = insets.left,
|
||||
right = insets.right
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun onNewChaptersChanged(newChapters: Int) {
|
||||
val tab = binding.tabs.getTabAt(1) ?: return
|
||||
if (newChapters == 0) {
|
||||
|
||||
@@ -5,9 +5,11 @@ import android.text.Spanned
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.core.graphics.Insets
|
||||
import androidx.core.net.toUri
|
||||
import androidx.core.text.parseAsHtml
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.core.view.updatePadding
|
||||
import coil.ImageLoader
|
||||
import coil.util.CoilUtils
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
@@ -174,4 +176,12 @@ class DetailsFragment : BaseFragment<FragmentDetailsBinding>(), View.OnClickList
|
||||
else -> return false
|
||||
}
|
||||
}
|
||||
|
||||
override fun onWindowInsetsChanged(insets: Insets) {
|
||||
binding.root.updatePadding(
|
||||
left = insets.left,
|
||||
right = insets.right,
|
||||
bottom = insets.bottom
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,8 @@ package org.koitharu.kotatsu.favourites.ui
|
||||
import android.os.Bundle
|
||||
import android.os.Parcelable
|
||||
import android.view.*
|
||||
import androidx.core.graphics.Insets
|
||||
import androidx.core.view.updatePadding
|
||||
import com.google.android.material.snackbar.Snackbar
|
||||
import com.google.android.material.tabs.TabLayoutMediator
|
||||
import org.koin.androidx.viewmodel.ext.android.viewModel
|
||||
@@ -66,6 +68,13 @@ class FavouritesContainerFragment : BaseFragment<FragmentFavouritesBinding>(),
|
||||
outState.putParcelable(KEY_ADAPTER_STATE, adapterState)
|
||||
}
|
||||
|
||||
override fun onWindowInsetsChanged(insets: Insets) {
|
||||
binding.tabs.updatePadding(
|
||||
left = insets.left,
|
||||
right = insets.right
|
||||
)
|
||||
}
|
||||
|
||||
private fun onCategoriesChanged(categories: List<FavouriteCategory>) {
|
||||
val data = ArrayList<FavouriteCategory>(categories.size + 1)
|
||||
data += FavouriteCategory(0L, getString(R.string.all_favourites), -1, Date())
|
||||
|
||||
@@ -6,7 +6,11 @@ import android.content.res.ColorStateList
|
||||
import android.graphics.Color
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.core.graphics.Insets
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.core.view.updateLayoutParams
|
||||
import androidx.core.view.updatePadding
|
||||
import androidx.recyclerview.widget.DividerItemDecoration
|
||||
import androidx.recyclerview.widget.ItemTouchHelper
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
@@ -70,6 +74,24 @@ class CategoriesActivity : BaseActivity<ActivityCategoriesBinding>(),
|
||||
return true
|
||||
}
|
||||
|
||||
override fun onWindowInsetsChanged(insets: Insets) {
|
||||
binding.fabAdd.updateLayoutParams<ViewGroup.MarginLayoutParams> {
|
||||
rightMargin = topMargin + insets.right
|
||||
leftMargin = topMargin + insets.left
|
||||
bottomMargin = topMargin + insets.bottom
|
||||
}
|
||||
binding.recyclerView.updatePadding(
|
||||
left = insets.left,
|
||||
right = insets.right,
|
||||
bottom = insets.bottom
|
||||
)
|
||||
binding.toolbar.updatePadding(
|
||||
left = insets.left,
|
||||
right = insets.right,
|
||||
top = insets.top
|
||||
)
|
||||
}
|
||||
|
||||
private fun onCategoriesChanged(categories: List<FavouriteCategory>) {
|
||||
// TODO check if not moved
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.SeekBar
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.fragment.app.FragmentManager
|
||||
import org.koin.android.ext.android.inject
|
||||
import org.koitharu.kotatsu.R
|
||||
@@ -44,6 +45,8 @@ class ListModeSelectDialog : AlertDialogFragment<DialogListModeBinding>(), View.
|
||||
binding.buttonList.isChecked = mode == ListMode.LIST
|
||||
binding.buttonListDetailed.isChecked = mode == ListMode.DETAILED_LIST
|
||||
binding.buttonGrid.isChecked = mode == ListMode.GRID
|
||||
binding.textViewGridTitle.isVisible = mode == ListMode.GRID
|
||||
binding.seekbarGrid.isVisible = mode == ListMode.GRID
|
||||
|
||||
with(binding.seekbarGrid) {
|
||||
progress = pendingGridSize - 50
|
||||
@@ -71,6 +74,8 @@ class ListModeSelectDialog : AlertDialogFragment<DialogListModeBinding>(), View.
|
||||
R.id.button_list_detailed -> mode = ListMode.DETAILED_LIST
|
||||
R.id.button_grid -> mode = ListMode.GRID
|
||||
}
|
||||
binding.textViewGridTitle.isVisible = mode == ListMode.GRID
|
||||
binding.seekbarGrid.isVisible = mode == ListMode.GRID
|
||||
settings.listMode = mode
|
||||
}
|
||||
|
||||
|
||||
@@ -4,9 +4,11 @@ import android.os.Bundle
|
||||
import android.view.*
|
||||
import androidx.annotation.CallSuper
|
||||
import androidx.appcompat.widget.PopupMenu
|
||||
import androidx.core.graphics.Insets
|
||||
import androidx.core.view.GravityCompat
|
||||
import androidx.core.view.isGone
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.core.view.updatePadding
|
||||
import androidx.drawerlayout.widget.DrawerLayout
|
||||
import androidx.recyclerview.widget.DividerItemDecoration
|
||||
import androidx.recyclerview.widget.GridLayoutManager
|
||||
@@ -195,6 +197,19 @@ abstract class MangaListFragment : BaseFragment<FragmentListBinding>(),
|
||||
binding.drawer?.closeDrawers()
|
||||
}
|
||||
|
||||
override fun onWindowInsetsChanged(insets: Insets) {
|
||||
binding.recyclerView.updatePadding(
|
||||
bottom = insets.bottom
|
||||
)
|
||||
binding.recyclerViewFilter.updatePadding(
|
||||
bottom = insets.bottom
|
||||
)
|
||||
binding.root.updatePadding(
|
||||
left = insets.left,
|
||||
right = insets.right
|
||||
)
|
||||
}
|
||||
|
||||
private fun onGridScaleChanged(scale: Float) {
|
||||
spanSizeLookup.invalidateCache()
|
||||
spanResolver.setGridSize(scale, binding.recyclerView)
|
||||
|
||||
@@ -3,10 +3,12 @@ package org.koitharu.kotatsu.main
|
||||
import org.koin.androidx.viewmodel.dsl.viewModel
|
||||
import org.koin.dsl.module
|
||||
import org.koitharu.kotatsu.main.ui.MainViewModel
|
||||
import org.koitharu.kotatsu.main.ui.protect.AppProtectHelper
|
||||
import org.koitharu.kotatsu.main.ui.protect.ProtectViewModel
|
||||
|
||||
val mainModule
|
||||
get() = module {
|
||||
single { AppProtectHelper(get()) }
|
||||
viewModel { MainViewModel(get(), get()) }
|
||||
viewModel { ProtectViewModel(get()) }
|
||||
}
|
||||
@@ -9,12 +9,15 @@ import android.os.Bundle
|
||||
import android.view.Menu
|
||||
import android.view.MenuItem
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.appcompat.app.ActionBarDrawerToggle
|
||||
import androidx.core.graphics.Insets
|
||||
import androidx.core.view.*
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.swiperefreshlayout.widget.CircularProgressDrawable
|
||||
import com.google.android.material.navigation.NavigationView
|
||||
import com.google.android.material.snackbar.Snackbar
|
||||
import org.koin.android.ext.android.inject
|
||||
import org.koin.androidx.viewmodel.ext.android.viewModel
|
||||
import org.koitharu.kotatsu.R
|
||||
import org.koitharu.kotatsu.base.ui.BaseActivity
|
||||
@@ -42,6 +45,7 @@ class MainActivity : BaseActivity<ActivityMainBinding>(),
|
||||
View.OnClickListener {
|
||||
|
||||
private val viewModel by viewModel<MainViewModel>()
|
||||
private val protectHelper by inject<AppProtectHelper>()
|
||||
|
||||
private lateinit var drawerToggle: ActionBarDrawerToggle
|
||||
private var closeable: Closeable? = null
|
||||
@@ -72,7 +76,8 @@ class MainActivity : BaseActivity<ActivityMainBinding>(),
|
||||
} ?: run {
|
||||
openDefaultSection()
|
||||
}
|
||||
if (AppProtectHelper.check(this)) {
|
||||
if (protectHelper.check(this)) {
|
||||
finish()
|
||||
return
|
||||
}
|
||||
TrackWorker.setup(applicationContext)
|
||||
@@ -86,7 +91,7 @@ class MainActivity : BaseActivity<ActivityMainBinding>(),
|
||||
|
||||
override fun onDestroy() {
|
||||
closeable?.close()
|
||||
AppProtectHelper.lock()
|
||||
protectHelper.lock()
|
||||
super.onDestroy()
|
||||
}
|
||||
|
||||
@@ -159,6 +164,19 @@ class MainActivity : BaseActivity<ActivityMainBinding>(),
|
||||
return true
|
||||
}
|
||||
|
||||
override fun onWindowInsetsChanged(insets: Insets) {
|
||||
binding.toolbar.updatePadding(
|
||||
top = insets.top,
|
||||
left = insets.left,
|
||||
right = insets.right
|
||||
)
|
||||
binding.fab.updateLayoutParams<ViewGroup.MarginLayoutParams> {
|
||||
bottomMargin = insets.bottom + topMargin
|
||||
leftMargin = insets.left + topMargin
|
||||
rightMargin = insets.right + topMargin
|
||||
}
|
||||
}
|
||||
|
||||
private fun onOpenReader(manga: Manga) {
|
||||
val options = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
ActivityOptions.makeClipRevealAnimation(
|
||||
|
||||
@@ -2,22 +2,18 @@ package org.koitharu.kotatsu.main.ui.protect
|
||||
|
||||
import android.app.Activity
|
||||
import android.content.Intent
|
||||
import org.koin.core.component.KoinComponent
|
||||
import org.koin.core.component.inject
|
||||
import org.koitharu.kotatsu.core.prefs.AppSettings
|
||||
import org.koitharu.kotatsu.main.ui.MainActivity
|
||||
|
||||
@Deprecated("TODO not object")
|
||||
object AppProtectHelper : KoinComponent {
|
||||
class AppProtectHelper(private val settings: AppSettings) {
|
||||
|
||||
val settings by inject<AppSettings>()
|
||||
private var isUnlocked = settings.appPassword.isNullOrEmpty()
|
||||
|
||||
fun unlock(activity: Activity) {
|
||||
isUnlocked = true
|
||||
with(activity) {
|
||||
startActivity(Intent(this, MainActivity::class.java))
|
||||
finishAfterTransition()
|
||||
startActivity(Intent(this, MainActivity::class.java)
|
||||
.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,10 +23,8 @@ object AppProtectHelper : KoinComponent {
|
||||
|
||||
fun check(activity: Activity): Boolean {
|
||||
return if (!isUnlocked) {
|
||||
with(activity) {
|
||||
startActivity(ProtectActivity.newIntent(this))
|
||||
finishAfterTransition()
|
||||
}
|
||||
activity.startActivity(ProtectActivity.newIntent(activity)
|
||||
.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP))
|
||||
true
|
||||
} else {
|
||||
false
|
||||
|
||||
@@ -10,6 +10,9 @@ import android.view.Menu
|
||||
import android.view.MenuItem
|
||||
import android.view.inputmethod.EditorInfo
|
||||
import android.widget.TextView
|
||||
import androidx.core.graphics.Insets
|
||||
import androidx.core.view.updatePadding
|
||||
import org.koin.android.ext.android.inject
|
||||
import org.koin.androidx.viewmodel.ext.android.viewModel
|
||||
import org.koitharu.kotatsu.R
|
||||
import org.koitharu.kotatsu.base.ui.BaseActivity
|
||||
@@ -20,6 +23,7 @@ class ProtectActivity : BaseActivity<ActivityProtectBinding>(), TextView.OnEdito
|
||||
TextWatcher {
|
||||
|
||||
private val viewModel by viewModel<ProtectViewModel>()
|
||||
private val appProtectHelper by inject<AppProtectHelper>()
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
@@ -49,6 +53,14 @@ class ProtectActivity : BaseActivity<ActivityProtectBinding>(), TextView.OnEdito
|
||||
else -> super.onOptionsItemSelected(item)
|
||||
}
|
||||
|
||||
override fun onWindowInsetsChanged(insets: Insets) {
|
||||
binding.toolbar.updatePadding(
|
||||
left = insets.left,
|
||||
right = insets.right,
|
||||
top = insets.top
|
||||
)
|
||||
}
|
||||
|
||||
override fun onEditorAction(v: TextView?, actionId: Int, event: KeyEvent?): Boolean {
|
||||
return if (actionId == EditorInfo.IME_ACTION_DONE) {
|
||||
viewModel.tryUnlock(binding.editPassword.text.toString().orEmpty())
|
||||
@@ -67,7 +79,7 @@ class ProtectActivity : BaseActivity<ActivityProtectBinding>(), TextView.OnEdito
|
||||
}
|
||||
|
||||
private fun onUnlockSuccess(unit: Unit) {
|
||||
AppProtectHelper.unlock(this)
|
||||
appProtectHelper.unlock(this)
|
||||
}
|
||||
|
||||
private fun onError(e: Throwable) {
|
||||
|
||||
@@ -54,8 +54,7 @@ import org.koitharu.kotatsu.utils.ext.showAnimated
|
||||
class ReaderActivity : BaseFullscreenActivity<ActivityReaderBinding>(),
|
||||
ChaptersDialog.OnChapterChangeListener,
|
||||
GridTouchHelper.OnGridTouchListener, OnPageSelectListener, ReaderConfigDialog.Callback,
|
||||
ActivityResultCallback<Boolean>, OnApplyWindowInsetsListener,
|
||||
ReaderControlDelegate.OnInteractionListener {
|
||||
ActivityResultCallback<Boolean>, ReaderControlDelegate.OnInteractionListener {
|
||||
|
||||
private val viewModel by viewModel<ReaderViewModel> {
|
||||
parametersOf(MangaIntent.from(intent), intent?.getParcelableExtra<ReaderState>(EXTRA_STATE))
|
||||
@@ -64,6 +63,7 @@ class ReaderActivity : BaseFullscreenActivity<ActivityReaderBinding>(),
|
||||
private lateinit var touchHelper: GridTouchHelper
|
||||
private lateinit var orientationHelper: ScreenOrientationHelper
|
||||
private lateinit var controlDelegate: ReaderControlDelegate
|
||||
private var gestureInsets: Insets = Insets.NONE
|
||||
|
||||
private val reader
|
||||
get() = supportFragmentManager.findFragmentById(R.id.container) as? BaseReader<*>
|
||||
@@ -78,8 +78,6 @@ class ReaderActivity : BaseFullscreenActivity<ActivityReaderBinding>(),
|
||||
binding.toolbarBottom.inflateMenu(R.menu.opt_reader_bottom)
|
||||
binding.toolbarBottom.setOnMenuItemClickListener(::onOptionsItemSelected)
|
||||
|
||||
ViewCompat.setOnApplyWindowInsetsListener(binding.rootLayout, this)
|
||||
|
||||
orientationHelper.observeAutoOrientation()
|
||||
.onEach {
|
||||
binding.toolbarBottom.menu.findItem(R.id.action_screen_rotate).isVisible = !it
|
||||
@@ -230,12 +228,17 @@ class ReaderActivity : BaseFullscreenActivity<ActivityReaderBinding>(),
|
||||
}
|
||||
|
||||
override fun onProcessTouch(rawX: Int, rawY: Int): Boolean {
|
||||
return if (binding.appbarTop.hasGlobalPoint(rawX, rawY)
|
||||
|| binding.appbarBottom.hasGlobalPoint(rawX, rawY)
|
||||
return if (
|
||||
rawX <= gestureInsets.left ||
|
||||
rawY <= gestureInsets.top ||
|
||||
rawX >= binding.root.width - gestureInsets.right ||
|
||||
rawY >= binding.root.height - gestureInsets.bottom ||
|
||||
binding.appbarTop.hasGlobalPoint(rawX, rawY) ||
|
||||
binding.appbarBottom.hasGlobalPoint(rawX, rawY)
|
||||
) {
|
||||
false
|
||||
} else {
|
||||
val targets = binding.rootLayout.hitTest(rawX, rawY)
|
||||
val targets = binding.root.hitTest(rawX, rawY)
|
||||
targets.none { it.hasOnClickListeners() }
|
||||
}
|
||||
}
|
||||
@@ -273,6 +276,8 @@ class ReaderActivity : BaseFullscreenActivity<ActivityReaderBinding>(),
|
||||
viewModel.switchMode(mode)
|
||||
}
|
||||
|
||||
override fun onWindowInsetsChanged(insets: Insets) = Unit
|
||||
|
||||
private fun onPageSaved(uri: Uri?) {
|
||||
if (uri != null) {
|
||||
Snackbar.make(binding.container, R.string.page_saved, Snackbar.LENGTH_LONG)
|
||||
@@ -308,6 +313,7 @@ class ReaderActivity : BaseFullscreenActivity<ActivityReaderBinding>(),
|
||||
}
|
||||
|
||||
override fun onApplyWindowInsets(v: View, insets: WindowInsetsCompat): WindowInsetsCompat {
|
||||
gestureInsets = insets.getInsets(WindowInsetsCompat.Type.systemGestures())
|
||||
val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars())
|
||||
binding.appbarTop.updatePadding(
|
||||
top = systemBars.top,
|
||||
|
||||
@@ -3,6 +3,8 @@ package org.koitharu.kotatsu.reader.ui
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import androidx.core.graphics.Insets
|
||||
import androidx.core.view.updatePadding
|
||||
import androidx.fragment.app.commit
|
||||
import org.koitharu.kotatsu.BuildConfig
|
||||
import org.koitharu.kotatsu.R
|
||||
@@ -29,6 +31,14 @@ class SimpleSettingsActivity : BaseActivity<ActivitySettingsSimpleBinding>() {
|
||||
}
|
||||
}
|
||||
|
||||
override fun onWindowInsetsChanged(insets: Insets) {
|
||||
binding.toolbar.updatePadding(
|
||||
top = insets.top,
|
||||
left = insets.left,
|
||||
right = insets.right
|
||||
)
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
private const val ACTION_READER =
|
||||
|
||||
@@ -2,6 +2,7 @@ package org.koitharu.kotatsu.reader.ui.pager
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import androidx.core.graphics.Insets
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.viewbinding.ViewBinding
|
||||
import org.koin.android.ext.android.get
|
||||
@@ -42,6 +43,8 @@ abstract class BaseReader<B : ViewBinding> : BaseFragment<B>() {
|
||||
outState.putParcelable(KEY_STATE, lastReaderState)
|
||||
}
|
||||
|
||||
override fun onWindowInsetsChanged(insets: Insets) = Unit
|
||||
|
||||
abstract fun switchPageBy(delta: Int)
|
||||
|
||||
abstract fun switchPageTo(position: Int, smooth: Boolean)
|
||||
|
||||
@@ -5,6 +5,8 @@ import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.os.Parcelable
|
||||
import androidx.appcompat.widget.SearchView
|
||||
import androidx.core.graphics.Insets
|
||||
import androidx.core.view.updatePadding
|
||||
import org.koitharu.kotatsu.R
|
||||
import org.koitharu.kotatsu.base.ui.BaseActivity
|
||||
import org.koitharu.kotatsu.core.model.MangaSource
|
||||
@@ -44,6 +46,14 @@ class SearchActivity : BaseActivity<ActivitySearchBinding>(), SearchView.OnQuery
|
||||
super.onDestroy()
|
||||
}
|
||||
|
||||
override fun onWindowInsetsChanged(insets: Insets) {
|
||||
binding.toolbar.updatePadding(
|
||||
top = insets.top,
|
||||
left = insets.left,
|
||||
right = insets.right
|
||||
)
|
||||
}
|
||||
|
||||
override fun onQueryTextSubmit(query: String?): Boolean {
|
||||
return if (!query.isNullOrBlank()) {
|
||||
title = query
|
||||
|
||||
@@ -3,6 +3,8 @@ package org.koitharu.kotatsu.search.ui.global
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import androidx.core.graphics.Insets
|
||||
import androidx.core.view.updatePadding
|
||||
import org.koitharu.kotatsu.R
|
||||
import org.koitharu.kotatsu.base.ui.BaseActivity
|
||||
import org.koitharu.kotatsu.databinding.ActivitySearchGlobalBinding
|
||||
@@ -28,6 +30,14 @@ class GlobalSearchActivity : BaseActivity<ActivitySearchGlobalBinding>() {
|
||||
.commit()
|
||||
}
|
||||
|
||||
override fun onWindowInsetsChanged(insets: Insets) {
|
||||
binding.toolbar.updatePadding(
|
||||
top = insets.top,
|
||||
left = insets.left,
|
||||
right = insets.right
|
||||
)
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
private const val EXTRA_QUERY = "query"
|
||||
|
||||
@@ -52,6 +52,8 @@ class MainSettingsFragment : BasePreferenceFragment(R.string.settings),
|
||||
MultiSummaryProvider(R.string.gestures_only)
|
||||
findPreference<MultiSelectListPreference>(AppSettings.KEY_TRACK_SOURCES)?.summaryProvider =
|
||||
MultiSummaryProvider(R.string.dont_check)
|
||||
findPreference<Preference>(AppSettings.KEY_GRID_SIZE)?.isEnabled =
|
||||
settings.listMode == ListMode.GRID
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
@@ -91,6 +93,10 @@ class MainSettingsFragment : BasePreferenceFragment(R.string.settings),
|
||||
?: getString(R.string.not_available)
|
||||
}
|
||||
}
|
||||
AppSettings.KEY_LIST_MODE -> {
|
||||
findPreference<Preference>(AppSettings.KEY_GRID_SIZE)?.isEnabled =
|
||||
settings.listMode == ListMode.GRID
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
package org.koitharu.kotatsu.settings
|
||||
|
||||
import android.content.Context
|
||||
import android.media.RingtoneManager
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import androidx.preference.Preference
|
||||
import org.koin.android.ext.android.get
|
||||
import org.koitharu.kotatsu.R
|
||||
import org.koitharu.kotatsu.base.ui.BasePreferenceFragment
|
||||
import org.koitharu.kotatsu.core.prefs.AppSettings
|
||||
@@ -12,6 +14,15 @@ import org.koitharu.kotatsu.utils.ext.toUriOrNull
|
||||
|
||||
class NotificationSettingsLegacyFragment : BasePreferenceFragment(R.string.notifications) {
|
||||
|
||||
private val ringtonePickContract = registerForActivityResult(
|
||||
RingtonePickContract(get<Context>().getString(R.string.notification_sound))
|
||||
) { uri ->
|
||||
settings.notificationSound = uri?.toString().orEmpty()
|
||||
findPreference<Preference>(AppSettings.KEY_NOTIFICATIONS_SOUND)?.run {
|
||||
summary = RingtoneManager.getRingtone(context, uri).getTitle(context)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
|
||||
addPreferencesFromResource(R.xml.pref_notifications)
|
||||
}
|
||||
@@ -27,12 +38,7 @@ class NotificationSettingsLegacyFragment : BasePreferenceFragment(R.string.notif
|
||||
override fun onPreferenceTreeClick(preference: Preference?): Boolean {
|
||||
return when (preference?.key) {
|
||||
AppSettings.KEY_NOTIFICATIONS_SOUND -> {
|
||||
registerForActivityResult(RingtonePickContract(preference.title.toString())) { uri ->
|
||||
settings.notificationSound = uri?.toString().orEmpty()
|
||||
findPreference<Preference>(AppSettings.KEY_NOTIFICATIONS_SOUND)?.run {
|
||||
summary = RingtoneManager.getRingtone(context, uri).getTitle(context)
|
||||
}
|
||||
}.launch(settings.notificationSound.toUriOrNull())
|
||||
ringtonePickContract.launch(settings.notificationSound.toUriOrNull())
|
||||
true
|
||||
}
|
||||
else -> super.onPreferenceTreeClick(preference)
|
||||
|
||||
@@ -3,6 +3,8 @@ package org.koitharu.kotatsu.settings
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import androidx.core.graphics.Insets
|
||||
import androidx.core.view.updatePadding
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.commit
|
||||
import androidx.preference.Preference
|
||||
@@ -56,6 +58,14 @@ class SettingsActivity : BaseActivity<ActivitySettingsBinding>(),
|
||||
}
|
||||
}
|
||||
|
||||
override fun onWindowInsetsChanged(insets: Insets) {
|
||||
binding.toolbar.updatePadding(
|
||||
top = insets.top,
|
||||
left = insets.left,
|
||||
right = insets.right
|
||||
)
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
fun newIntent(context: Context) = Intent(context, SettingsActivity::class.java)
|
||||
|
||||
@@ -4,6 +4,8 @@ import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.core.graphics.Insets
|
||||
import androidx.core.view.updatePadding
|
||||
import androidx.recyclerview.widget.DividerItemDecoration
|
||||
import androidx.recyclerview.widget.ItemTouchHelper
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
@@ -49,6 +51,14 @@ class SourcesSettingsFragment : BaseFragment<FragmentSettingsSourcesBinding>(),
|
||||
super.onDestroyView()
|
||||
}
|
||||
|
||||
override fun onWindowInsetsChanged(insets: Insets) {
|
||||
binding.recyclerView.updatePadding(
|
||||
bottom = insets.bottom,
|
||||
left = insets.left,
|
||||
right = insets.right
|
||||
)
|
||||
}
|
||||
|
||||
override fun onItemClick(item: MangaSource, view: View) {
|
||||
(activity as? SettingsActivity)?.openMangaSourceSettings(item)
|
||||
}
|
||||
|
||||
@@ -2,7 +2,8 @@ package org.koitharu.kotatsu.tracker.ui
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.*
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.core.graphics.Insets
|
||||
import androidx.core.view.updatePadding
|
||||
import com.google.android.material.snackbar.Snackbar
|
||||
import org.koin.android.ext.android.get
|
||||
import org.koin.androidx.viewmodel.ext.android.viewModel
|
||||
@@ -18,7 +19,6 @@ import org.koitharu.kotatsu.list.ui.model.ListModel
|
||||
import org.koitharu.kotatsu.tracker.ui.adapter.FeedAdapter
|
||||
import org.koitharu.kotatsu.tracker.work.TrackWorker
|
||||
import org.koitharu.kotatsu.utils.ext.getDisplayMessage
|
||||
import org.koitharu.kotatsu.utils.ext.hasItems
|
||||
|
||||
class FeedFragment : BaseFragment<FragmentFeedBinding>(), PaginationScrollListener.Callback,
|
||||
OnListItemClickListener<Manga> {
|
||||
@@ -52,9 +52,7 @@ class FeedFragment : BaseFragment<FragmentFeedBinding>(), PaginationScrollListen
|
||||
}
|
||||
|
||||
viewModel.content.observe(viewLifecycleOwner, this::onListChanged)
|
||||
viewModel.isLoading.observe(viewLifecycleOwner, this::onLoadingStateChanged)
|
||||
viewModel.onError.observe(viewLifecycleOwner, this::onError)
|
||||
viewModel.isEmptyState.observe(viewLifecycleOwner, this::onEmptyStateChanged)
|
||||
}
|
||||
|
||||
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
|
||||
@@ -80,41 +78,24 @@ class FeedFragment : BaseFragment<FragmentFeedBinding>(), PaginationScrollListen
|
||||
super.onDestroyView()
|
||||
}
|
||||
|
||||
override fun onWindowInsetsChanged(insets: Insets) {
|
||||
binding.recyclerView.updatePadding(
|
||||
left = insets.left,
|
||||
right = insets.right,
|
||||
bottom = insets.bottom
|
||||
)
|
||||
}
|
||||
|
||||
private fun onListChanged(list: List<ListModel>) {
|
||||
feedAdapter?.items = list
|
||||
}
|
||||
|
||||
private fun onError(e: Throwable) {
|
||||
if (binding.recyclerView.hasItems) {
|
||||
Snackbar.make(
|
||||
binding.recyclerView,
|
||||
e.getDisplayMessage(resources),
|
||||
Snackbar.LENGTH_SHORT
|
||||
).show()
|
||||
} else {
|
||||
with(binding.textViewHolder) {
|
||||
text = e.getDisplayMessage(resources)
|
||||
setCompoundDrawablesRelativeWithIntrinsicBounds(
|
||||
0,
|
||||
R.drawable.ic_error_large,
|
||||
0,
|
||||
0
|
||||
)
|
||||
isVisible = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun onLoadingStateChanged(isLoading: Boolean) {
|
||||
val hasItems = binding.recyclerView.hasItems
|
||||
binding.progressBar.isVisible = isLoading && !hasItems
|
||||
}
|
||||
|
||||
private fun onEmptyStateChanged(isEmpty: Boolean) {
|
||||
if (isEmpty) {
|
||||
setUpEmptyListHolder()
|
||||
}
|
||||
binding.layoutHolder.isVisible = isEmpty
|
||||
Snackbar.make(
|
||||
binding.recyclerView,
|
||||
e.getDisplayMessage(resources),
|
||||
Snackbar.LENGTH_SHORT
|
||||
).show()
|
||||
}
|
||||
|
||||
override fun onScrolledToEnd() {
|
||||
@@ -125,13 +106,6 @@ class FeedFragment : BaseFragment<FragmentFeedBinding>(), PaginationScrollListen
|
||||
startActivity(DetailsActivity.newIntent(context ?: return, item))
|
||||
}
|
||||
|
||||
private fun setUpEmptyListHolder() {
|
||||
with(binding.textViewHolder) {
|
||||
setCompoundDrawablesRelativeWithIntrinsicBounds(null, null, null, null)
|
||||
setText(R.string.text_feed_holder)
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
fun newInstance() = FeedFragment()
|
||||
|
||||
@@ -9,8 +9,10 @@ import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.combine
|
||||
import kotlinx.coroutines.flow.filterNotNull
|
||||
import kotlinx.coroutines.flow.flowOn
|
||||
import org.koitharu.kotatsu.R
|
||||
import org.koitharu.kotatsu.base.ui.BaseViewModel
|
||||
import org.koitharu.kotatsu.core.model.TrackingLogItem
|
||||
import org.koitharu.kotatsu.list.ui.model.EmptyState
|
||||
import org.koitharu.kotatsu.list.ui.model.LoadingFooter
|
||||
import org.koitharu.kotatsu.list.ui.model.LoadingState
|
||||
import org.koitharu.kotatsu.tracker.domain.TrackingRepository
|
||||
@@ -34,7 +36,11 @@ class FeedViewModel(
|
||||
},
|
||||
hasNextPage
|
||||
) { list, isHasNextPage ->
|
||||
if (isHasNextPage && list.isNotEmpty()) list + LoadingFooter else list
|
||||
when {
|
||||
list.isEmpty() -> listOf(EmptyState(R.string.text_feed_holder))
|
||||
isHasNextPage -> list + LoadingFooter
|
||||
else -> list
|
||||
}
|
||||
}.flowOn(Dispatchers.Default).asLiveData(viewModelScope.coroutineContext, listOf(LoadingState))
|
||||
|
||||
init {
|
||||
|
||||
@@ -9,7 +9,11 @@ import android.os.Bundle
|
||||
import android.view.Menu
|
||||
import android.view.MenuItem
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.core.graphics.Insets
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.core.view.updateLayoutParams
|
||||
import androidx.core.view.updatePadding
|
||||
import androidx.recyclerview.widget.DividerItemDecoration
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.google.android.material.snackbar.Snackbar
|
||||
@@ -77,6 +81,24 @@ class ShelfConfigActivity : BaseActivity<ActivityCategoriesBinding>(), OnListIte
|
||||
viewModel.checkedId = item.id
|
||||
}
|
||||
|
||||
override fun onWindowInsetsChanged(insets: Insets) {
|
||||
binding.fabAdd.updateLayoutParams<ViewGroup.MarginLayoutParams> {
|
||||
rightMargin = topMargin + insets.right
|
||||
leftMargin = topMargin + insets.left
|
||||
bottomMargin = topMargin + insets.bottom
|
||||
}
|
||||
binding.recyclerView.updatePadding(
|
||||
left = insets.left,
|
||||
right = insets.right,
|
||||
bottom = insets.bottom
|
||||
)
|
||||
binding.toolbar.updatePadding(
|
||||
left = insets.left,
|
||||
right = insets.right,
|
||||
top = insets.top
|
||||
)
|
||||
}
|
||||
|
||||
private fun onContentChanged(categories: List<CategoryItem>) {
|
||||
adapter.items = categories
|
||||
}
|
||||
|
||||
44
app/src/main/res/layout-w600dp/activity_details.xml
Normal file
44
app/src/main/res/layout-w600dp/activity_details.xml
Normal file
@@ -0,0 +1,44 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||
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="match_parent"
|
||||
tools:context=".details.ui.DetailsActivity">
|
||||
|
||||
<com.google.android.material.appbar.AppBarLayout
|
||||
android:id="@+id/appbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?colorPrimary"
|
||||
android:theme="@style/AppToolbarTheme">
|
||||
|
||||
<com.google.android.material.appbar.MaterialToolbar
|
||||
android:id="@id/toolbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_scrollFlags="scroll|enterAlways"
|
||||
app:popupTheme="@style/AppPopupTheme">
|
||||
|
||||
<com.google.android.material.tabs.TabLayout
|
||||
android:id="@+id/tabs"
|
||||
style="@style/Widget.MaterialComponents.TabLayout.Colored"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="end"
|
||||
android:background="@android:color/transparent"
|
||||
app:tabGravity="start"
|
||||
app:tabMode="scrollable" />
|
||||
|
||||
</com.google.android.material.appbar.MaterialToolbar>
|
||||
|
||||
</com.google.android.material.appbar.AppBarLayout>
|
||||
|
||||
<androidx.viewpager2.widget.ViewPager2
|
||||
android:id="@+id/pager"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior" />
|
||||
|
||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||
@@ -3,6 +3,7 @@
|
||||
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:clipToPadding="false"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?colorPrimary"
|
||||
android:fitsSystemWindows="true"
|
||||
android:theme="@style/AppToolbarTheme"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?colorPrimary"
|
||||
android:fitsSystemWindows="true"
|
||||
android:theme="@style/AppToolbarTheme">
|
||||
|
||||
<com.google.android.material.appbar.MaterialToolbar
|
||||
@@ -28,6 +27,7 @@
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
android:scrollbars="vertical"
|
||||
android:clipToPadding="false"
|
||||
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
|
||||
app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior" />
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
tools:context=".details.ui.DetailsActivity">
|
||||
|
||||
<com.google.android.material.appbar.AppBarLayout
|
||||
android:id="@+id/appbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?colorPrimary"
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="16dp"
|
||||
android:contentDescription="@string/_continue"
|
||||
android:src="@drawable/ic_read_fill"
|
||||
android:visibility="gone"
|
||||
app:backgroundTint="?colorAccent"
|
||||
@@ -56,6 +57,7 @@
|
||||
android:layout_width="260dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_gravity="start"
|
||||
app:insetForeground="@android:color/transparent"
|
||||
app:menu="@menu/nav_drawer" />
|
||||
|
||||
</androidx.drawerlayout.widget.DrawerLayout>
|
||||
@@ -2,7 +2,6 @@
|
||||
<FrameLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:id="@+id/rootLayout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:keepScreenOn="true">
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?colorPrimary"
|
||||
android:fitsSystemWindows="true"
|
||||
android:theme="@style/AppToolbarTheme">
|
||||
|
||||
<com.google.android.material.appbar.MaterialToolbar
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
android:id="@+id/appbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:fitsSystemWindows="true"
|
||||
android:background="?colorPrimary"
|
||||
android:theme="@style/AppToolbarTheme">
|
||||
|
||||
|
||||
@@ -7,19 +7,20 @@
|
||||
android:orientation="vertical">
|
||||
|
||||
<com.google.android.material.appbar.AppBarLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/appbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?colorPrimary"
|
||||
android:theme="@style/AppToolbarTheme">
|
||||
android:theme="@style/AppToolbarTheme">
|
||||
|
||||
<com.google.android.material.appbar.MaterialToolbar
|
||||
android:id="@id/toolbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_scrollFlags="scroll|enterAlways"
|
||||
app:popupTheme="@style/AppPopupTheme" />
|
||||
<com.google.android.material.appbar.MaterialToolbar
|
||||
android:id="@id/toolbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_scrollFlags="scroll|enterAlways"
|
||||
app:popupTheme="@style/AppPopupTheme" />
|
||||
|
||||
</com.google.android.material.appbar.AppBarLayout>
|
||||
</com.google.android.material.appbar.AppBarLayout>
|
||||
|
||||
<androidx.fragment.app.FragmentContainerView
|
||||
android:id="@id/container"
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?colorPrimary"
|
||||
android:fitsSystemWindows="true"
|
||||
android:theme="@style/AppToolbarTheme">
|
||||
|
||||
<com.google.android.material.appbar.MaterialToolbar
|
||||
|
||||
@@ -22,8 +22,10 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:imeOptions="actionDone"
|
||||
android:paddingStart="0dp"
|
||||
android:paddingTop="28dp"
|
||||
android:paddingEnd="0dp"
|
||||
android:singleLine="true"
|
||||
tools:hint="@tools:sample/cities"
|
||||
tools:text="@tools:sample/lorem[2]" />
|
||||
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:animateLayoutChanges="true"
|
||||
android:orientation="vertical">
|
||||
|
||||
<com.google.android.material.button.MaterialButtonToggleGroup
|
||||
@@ -42,13 +43,16 @@
|
||||
</com.google.android.material.button.MaterialButtonToggleGroup>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/textView_grid_title"
|
||||
style="?android:attr/windowTitleStyle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingLeft="?attr/dialogPreferredPadding"
|
||||
android:paddingRight="?attr/dialogPreferredPadding"
|
||||
android:singleLine="true"
|
||||
android:text="@string/grid_size" />
|
||||
android:text="@string/grid_size"
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<SeekBar
|
||||
android:id="@+id/seekbar_grid"
|
||||
@@ -56,6 +60,8 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="16dp"
|
||||
android:max="100"
|
||||
tools:progress="50" />
|
||||
android:visibility="gone"
|
||||
tools:progress="50"
|
||||
tools:visibility="visible" />
|
||||
|
||||
</LinearLayout>
|
||||
@@ -3,6 +3,7 @@
|
||||
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:clipToPadding="false"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
|
||||
@@ -1,47 +1,18 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<FrameLayout
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
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:id="@+id/recyclerView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/recyclerView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
android:scrollbars="vertical"
|
||||
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
|
||||
tools:listitem="@layout/item_manga_list" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/layout_holder"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:layout_marginStart="20dp"
|
||||
android:layout_marginEnd="20dp"
|
||||
android:gravity="center_horizontal"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/textView_holder"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:gravity="center"
|
||||
android:textAppearance="?android:textAppearanceMedium"
|
||||
android:textColor="?android:textColorSecondary"
|
||||
tools:text="@tools:sample/lorem[3]" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/progressBar"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:indeterminate="true" />
|
||||
|
||||
</FrameLayout>
|
||||
android:layout_height="match_parent"
|
||||
android:clipToPadding="false"
|
||||
android:orientation="vertical"
|
||||
android:scrollbars="vertical"
|
||||
app:fastScrollEnabled="true"
|
||||
app:fastScrollHorizontalThumbDrawable="@drawable/list_thumb"
|
||||
app:fastScrollHorizontalTrackDrawable="@drawable/list_track"
|
||||
app:fastScrollVerticalThumbDrawable="@drawable/list_thumb"
|
||||
app:fastScrollVerticalTrackDrawable="@drawable/list_track"
|
||||
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
|
||||
tools:listitem="@layout/item_tracklog" />
|
||||
@@ -21,6 +21,7 @@
|
||||
android:id="@+id/recyclerView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:clipToPadding="false"
|
||||
android:orientation="vertical"
|
||||
android:scrollbars="vertical"
|
||||
app:fastScrollEnabled="true"
|
||||
@@ -39,6 +40,7 @@
|
||||
android:layout_height="match_parent"
|
||||
android:layout_gravity="end"
|
||||
android:background="?android:windowBackground"
|
||||
android:clipToPadding="false"
|
||||
android:orientation="vertical"
|
||||
android:scrollbars="vertical"
|
||||
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
android:id="@+id/recyclerView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:clipToPadding="false"
|
||||
android:orientation="vertical"
|
||||
android:scrollbars="vertical"
|
||||
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
|
||||
|
||||
@@ -1,14 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<com.google.android.material.card.MaterialCardView
|
||||
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="wrap_content"
|
||||
app:cardElevation="0dp"
|
||||
app:cardMaxElevation="0dp"
|
||||
app:strokeColor="?colorOnSurface"
|
||||
app:strokeWidth="1px">
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
|
||||
@@ -4,11 +4,7 @@
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/manga_list_details_item_height"
|
||||
app:cardElevation="0dp"
|
||||
app:cardMaxElevation="0dp"
|
||||
app:strokeColor="?colorOnSurface"
|
||||
app:strokeWidth="1px">
|
||||
android:layout_height="@dimen/manga_list_details_item_height">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
|
||||
@@ -1,15 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<com.google.android.material.card.MaterialCardView
|
||||
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="wrap_content"
|
||||
app:cardBackgroundColor="?android:windowBackground"
|
||||
app:cardElevation="0dp"
|
||||
app:cardMaxElevation="0dp"
|
||||
app:strokeColor="?android:colorControlNormal"
|
||||
app:strokeWidth="1px">
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="match_parent"
|
||||
|
||||
12
app/src/main/res/values-v29/themes.xml
Normal file
12
app/src/main/res/values-v29/themes.xml
Normal file
@@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<style name="BaseAppTheme" parent="Theme.MaterialComponents.DayNight.NoActionBar">
|
||||
<item name="windowActionModeOverlay">true</item>
|
||||
<item name="actionModeCloseDrawable">@drawable/ic_cross</item>
|
||||
<item name="actionModeStyle">@style/AppActionMode</item>
|
||||
<item name="preferenceTheme">@style/PreferenceThemeOverlay</item>
|
||||
<item name="badgeStyle">@style/Widget.MaterialComponents.Badge</item>
|
||||
<item name="android:statusBarColor">@color/status_bar</item>
|
||||
<item name="android:navigationBarColor">@android:color/transparent</item>
|
||||
</style>
|
||||
</resources>
|
||||
@@ -8,4 +8,5 @@
|
||||
<color name="grey_dark">#212121</color>
|
||||
<color name="dim">#99000000</color>
|
||||
<color name="error">#D32F2F</color>
|
||||
<color name="status_bar">#33000000</color>
|
||||
</resources>
|
||||
@@ -6,6 +6,7 @@
|
||||
<item name="actionModeStyle">@style/AppActionMode</item>
|
||||
<item name="preferenceTheme">@style/PreferenceThemeOverlay</item>
|
||||
<item name="badgeStyle">@style/Widget.MaterialComponents.Badge</item>
|
||||
<item name="android:statusBarColor">@color/status_bar</item>
|
||||
</style>
|
||||
|
||||
<style name="AppTheme" parent="BaseAppTheme">
|
||||
|
||||
Reference in New Issue
Block a user