From 0b07e83e3cbf56c9da5c899bf0be18ec4f3cd360 Mon Sep 17 00:00:00 2001 From: Koitharu Date: Fri, 11 Mar 2022 19:22:31 +0200 Subject: [PATCH 1/6] Enhance tablet ui --- .../kotatsu/details/ui/ChaptersFragment.kt | 21 +++- .../kotatsu/details/ui/DetailsActivity.kt | 34 +++---- .../kotatsu/details/ui/DetailsFragment.kt | 20 +++- .../koitharu/kotatsu/main/ui/MainActivity.kt | 72 +++++++------- .../koitharu/kotatsu/utils/ext/InsetsExt.kt | 20 ++++ .../activity_details.xml | 0 .../layout-w720dp-land/activity_details.xml | 55 +++++++++++ .../res/layout-w720dp-land/activity_main.xml | 96 +++++++++++++++++++ app/src/main/res/layout/activity_main.xml | 2 +- app/src/main/res/values-w980dp/dimens.xml | 6 ++ app/src/main/res/values/dimens.xml | 4 + 11 files changed, 267 insertions(+), 63 deletions(-) create mode 100644 app/src/main/java/org/koitharu/kotatsu/utils/ext/InsetsExt.kt rename app/src/main/res/{layout-w600dp => layout-land}/activity_details.xml (100%) create mode 100644 app/src/main/res/layout-w720dp-land/activity_details.xml create mode 100644 app/src/main/res/layout-w720dp-land/activity_main.xml create mode 100644 app/src/main/res/values-w980dp/dimens.xml diff --git a/app/src/main/java/org/koitharu/kotatsu/details/ui/ChaptersFragment.kt b/app/src/main/java/org/koitharu/kotatsu/details/ui/ChaptersFragment.kt index 6ea44a8ac..4f4d1e1a5 100644 --- a/app/src/main/java/org/koitharu/kotatsu/details/ui/ChaptersFragment.kt +++ b/app/src/main/java/org/koitharu/kotatsu/details/ui/ChaptersFragment.kt @@ -9,6 +9,8 @@ import androidx.appcompat.view.ActionMode import androidx.core.graphics.Insets import androidx.core.view.isVisible import androidx.core.view.updatePadding +import androidx.core.view.updatePaddingRelative +import androidx.fragment.app.FragmentContainerView import androidx.recyclerview.widget.RecyclerView import com.google.android.material.divider.MaterialDividerItemDecoration import org.koin.androidx.viewmodel.ext.android.sharedViewModel @@ -24,6 +26,7 @@ import org.koitharu.kotatsu.details.ui.model.ChapterListItem import org.koitharu.kotatsu.download.ui.service.DownloadService import org.koitharu.kotatsu.reader.ui.ReaderActivity import org.koitharu.kotatsu.reader.ui.ReaderState +import org.koitharu.kotatsu.utils.ext.getEnd class ChaptersFragment : BaseFragment(), OnListItemClickListener, @@ -200,11 +203,19 @@ class ChaptersFragment : BaseFragment(), } override fun onWindowInsetsChanged(insets: Insets) { - binding.recyclerViewChapters.updatePadding( - left = insets.left, - right = insets.right, - bottom = insets.bottom + binding.spinnerBranches.height - ) + val root = binding.root + if (root.parent is FragmentContainerView) { + binding.recyclerViewChapters.updatePaddingRelative( + end = insets.getEnd(root), + bottom = insets.bottom + binding.spinnerBranches.height, + ) + } else { + binding.recyclerViewChapters.updatePadding( + left = insets.left, + right = insets.right, + bottom = insets.bottom + binding.spinnerBranches.height, + ) + } } private fun onChaptersChanged(list: List) { diff --git a/app/src/main/java/org/koitharu/kotatsu/details/ui/DetailsActivity.kt b/app/src/main/java/org/koitharu/kotatsu/details/ui/DetailsActivity.kt index d8cb87ecf..7bea427f3 100644 --- a/app/src/main/java/org/koitharu/kotatsu/details/ui/DetailsActivity.kt +++ b/app/src/main/java/org/koitharu/kotatsu/details/ui/DetailsActivity.kt @@ -17,14 +17,12 @@ import androidx.core.view.updateLayoutParams import androidx.core.view.updatePadding import androidx.lifecycle.lifecycleScope import com.google.android.material.dialog.MaterialAlertDialogBuilder -import com.google.android.material.snackbar.Snackbar import com.google.android.material.tabs.TabLayout import com.google.android.material.tabs.TabLayoutMediator import kotlinx.coroutines.launch import org.koin.android.ext.android.get import org.koin.androidx.viewmodel.ext.android.viewModel import org.koin.core.parameter.parametersOf -import org.koitharu.kotatsu.BuildConfig import org.koitharu.kotatsu.R import org.koitharu.kotatsu.base.domain.MangaIntent import org.koitharu.kotatsu.base.ui.BaseActivity @@ -43,8 +41,7 @@ import org.koitharu.kotatsu.utils.ShareHelper import org.koitharu.kotatsu.utils.ext.buildAlertDialog import org.koitharu.kotatsu.utils.ext.getDisplayMessage -class DetailsActivity : BaseActivity(), - TabLayoutMediator.TabConfigurationStrategy { +class DetailsActivity : BaseActivity(), TabLayoutMediator.TabConfigurationStrategy { private val viewModel by viewModel { parametersOf(MangaIntent(intent)) @@ -54,8 +51,11 @@ class DetailsActivity : BaseActivity(), super.onCreate(savedInstanceState) setContentView(ActivityDetailsBinding.inflate(layoutInflater)) supportActionBar?.setDisplayHomeAsUpEnabled(true) - binding.pager.adapter = MangaDetailsAdapter(this) - TabLayoutMediator(binding.tabs, binding.pager, this).attach() + val pager = binding.pager + if (pager != null) { + pager.adapter = MangaDetailsAdapter(this) + TabLayoutMediator(checkNotNull(binding.tabs), pager, this).attach() + } viewModel.manga.observe(this, ::onMangaUpdated) viewModel.newChaptersCount.observe(this, ::onNewChaptersChanged) @@ -105,8 +105,9 @@ class DetailsActivity : BaseActivity(), topMargin = insets.top } } - if (binding.tabs.parent !is Toolbar) { - binding.tabs.updatePadding( + val tabs = binding.tabs + if (tabs != null && tabs.parent !is Toolbar) { + tabs.updatePadding( left = insets.left, right = insets.right ) @@ -114,7 +115,7 @@ class DetailsActivity : BaseActivity(), } private fun onNewChaptersChanged(newChapters: Int) { - val tab = binding.tabs.getTabAt(1) ?: return + val tab = binding.tabs?.getTabAt(1) ?: return if (newChapters == 0) { tab.removeBadge() } else { @@ -208,11 +209,7 @@ class DetailsActivity : BaseActivity(), viewModel.manga.value?.let { lifecycleScope.launch { if (!get().requestPinShortcut(it)) { - Snackbar.make( - binding.pager, - R.string.operation_not_supported, - Snackbar.LENGTH_SHORT - ).show() + binding.snackbar.show(getString(R.string.operation_not_supported)) } } } @@ -231,19 +228,18 @@ class DetailsActivity : BaseActivity(), override fun onSupportActionModeStarted(mode: ActionMode) { super.onSupportActionModeStarted(mode) - binding.pager.isUserInputEnabled = false + binding.pager?.isUserInputEnabled = false } override fun onSupportActionModeFinished(mode: ActionMode) { super.onSupportActionModeFinished(mode) - binding.pager.isUserInputEnabled = true + binding.pager?.isUserInputEnabled = true } fun showChapterMissingDialog(chapterId: Long) { val remoteManga = viewModel.getRemoteManga() if (remoteManga == null) { - Snackbar.make(binding.pager, R.string.chapter_is_missing, Snackbar.LENGTH_LONG) - .show() + binding.snackbar.show(getString( R.string.chapter_is_missing)) return } buildAlertDialog(this) { @@ -268,8 +264,6 @@ class DetailsActivity : BaseActivity(), companion object { - const val ACTION_MANGA_VIEW = "${BuildConfig.APPLICATION_ID}.action.VIEW_MANGA" - fun newIntent(context: Context, manga: Manga): Intent { return Intent(context, DetailsActivity::class.java) .putExtra(MangaIntent.KEY_MANGA, manga) diff --git a/app/src/main/java/org/koitharu/kotatsu/details/ui/DetailsFragment.kt b/app/src/main/java/org/koitharu/kotatsu/details/ui/DetailsFragment.kt index 3cd328ce2..47993dd60 100644 --- a/app/src/main/java/org/koitharu/kotatsu/details/ui/DetailsFragment.kt +++ b/app/src/main/java/org/koitharu/kotatsu/details/ui/DetailsFragment.kt @@ -13,6 +13,8 @@ import androidx.core.net.toUri import androidx.core.text.parseAsHtml import androidx.core.view.isVisible import androidx.core.view.updatePadding +import androidx.core.view.updatePaddingRelative +import androidx.fragment.app.FragmentContainerView import coil.ImageLoader import coil.request.ImageRequest import coil.util.CoilUtils @@ -232,11 +234,19 @@ class DetailsFragment : BaseFragment(), View.OnClickList } override fun onWindowInsetsChanged(insets: Insets) { - binding.root.updatePadding( - left = insets.left, - right = insets.right, - bottom = insets.bottom - ) + val root = binding.root + if (root.parent is FragmentContainerView) { + root.updatePaddingRelative( + start = insets.getStart(root), + bottom = insets.bottom, + ) + } else { + root.updatePadding( + left = insets.left, + right = insets.right, + bottom = insets.bottom, + ) + } } private fun bindTags(manga: Manga) { diff --git a/app/src/main/java/org/koitharu/kotatsu/main/ui/MainActivity.kt b/app/src/main/java/org/koitharu/kotatsu/main/ui/MainActivity.kt index 3a3cea458..474ea72ba 100644 --- a/app/src/main/java/org/koitharu/kotatsu/main/ui/MainActivity.kt +++ b/app/src/main/java/org/koitharu/kotatsu/main/ui/MainActivity.kt @@ -53,10 +53,7 @@ import org.koitharu.kotatsu.suggestions.ui.SuggestionsFragment import org.koitharu.kotatsu.suggestions.ui.SuggestionsWorker import org.koitharu.kotatsu.tracker.ui.FeedFragment import org.koitharu.kotatsu.tracker.work.TrackWorker -import org.koitharu.kotatsu.utils.ext.getDisplayMessage -import org.koitharu.kotatsu.utils.ext.hideKeyboard -import org.koitharu.kotatsu.utils.ext.measureHeight -import org.koitharu.kotatsu.utils.ext.resolveDp +import org.koitharu.kotatsu.utils.ext.* private const val TAG_PRIMARY = "primary" private const val TAG_SEARCH = "search" @@ -69,7 +66,8 @@ class MainActivity : BaseActivity(), private val searchSuggestionViewModel by viewModel() private lateinit var navHeaderBinding: NavigationHeaderBinding - private lateinit var drawerToggle: ActionBarDrawerToggle + private var drawerToggle: ActionBarDrawerToggle? = null + private var drawer: DrawerLayout? = null override val appBar: AppBarLayout get() = binding.appbar @@ -78,24 +76,31 @@ class MainActivity : BaseActivity(), super.onCreate(savedInstanceState) setContentView(ActivityMainBinding.inflate(layoutInflater)) navHeaderBinding = NavigationHeaderBinding.inflate(layoutInflater) - drawerToggle = ActionBarDrawerToggle( - this, - binding.drawer, - binding.toolbar, - R.string.open_menu, - R.string.close_menu - ) - drawerToggle.setHomeAsUpIndicator(ContextCompat.getDrawable(this, R.drawable.ic_arrow_back)) - drawerToggle.setToolbarNavigationClickListener { - binding.searchView.hideKeyboard() - onBackPressed() + drawer = binding.root as? DrawerLayout + drawerToggle = drawer?.let { + ActionBarDrawerToggle( + this, + it, + binding.toolbar, + R.string.open_menu, + R.string.close_menu + ).apply { + setHomeAsUpIndicator(ContextCompat.getDrawable(this@MainActivity, R.drawable.ic_arrow_back)) + setToolbarNavigationClickListener { + binding.searchView.hideKeyboard() + onBackPressed() + } + it.addDrawerListener(this) + supportActionBar?.setDisplayHomeAsUpEnabled(true) + } } - binding.drawer.addDrawerListener(drawerToggle) - supportActionBar?.setDisplayHomeAsUpEnabled(true) with(binding.searchView) { onFocusChangeListener = this@MainActivity searchSuggestionListener = this@MainActivity + if (drawer == null) { + drawableStart = ContextCompat.getDrawable(context, R.drawable.ic_search) + } } with(binding.navigationView) { @@ -132,26 +137,27 @@ class MainActivity : BaseActivity(), override fun onRestoreInstanceState(savedInstanceState: Bundle) { super.onRestoreInstanceState(savedInstanceState) - drawerToggle.isDrawerIndicatorEnabled = - binding.drawer.getDrawerLockMode(GravityCompat.START) == DrawerLayout.LOCK_MODE_UNLOCKED + drawerToggle?.isDrawerIndicatorEnabled = + drawer?.getDrawerLockMode(GravityCompat.START) == DrawerLayout.LOCK_MODE_UNLOCKED } override fun onPostCreate(savedInstanceState: Bundle?) { super.onPostCreate(savedInstanceState) - drawerToggle.syncState() + drawerToggle?.syncState() } override fun onConfigurationChanged(newConfig: Configuration) { super.onConfigurationChanged(newConfig) - drawerToggle.onConfigurationChanged(newConfig) + drawerToggle?.onConfigurationChanged(newConfig) } override fun onBackPressed() { val fragment = supportFragmentManager.findFragmentByTag(TAG_SEARCH) binding.searchView.clearFocus() when { - binding.drawer.isDrawerOpen(binding.navigationView) -> binding.drawer.closeDrawer( - binding.navigationView) + drawer?.isDrawerOpen(binding.navigationView) == true -> { + drawer?.closeDrawer(binding.navigationView) + } fragment != null -> supportFragmentManager.commit { remove(fragment) setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE) @@ -162,7 +168,7 @@ class MainActivity : BaseActivity(), } override fun onOptionsItemSelected(item: MenuItem): Boolean { - return drawerToggle.onOptionsItemSelected(item) || when (item.itemId) { + return drawerToggle?.onOptionsItemSelected(item) == true || when (item.itemId) { else -> super.onOptionsItemSelected(item) } } @@ -208,7 +214,7 @@ class MainActivity : BaseActivity(), else -> return false } } - binding.drawer.closeDrawers() + drawer?.closeDrawers() return true } @@ -221,8 +227,10 @@ class MainActivity : BaseActivity(), leftMargin = insets.left + topMargin rightMargin = insets.right + topMargin } - binding.container.updateLayoutParams { - topMargin = -(binding.appbar.measureHeight()) + if (drawer != null) { + binding.container.updateLayoutParams { + topMargin = -(binding.appbar.measureHeight()) + } } } @@ -354,13 +362,13 @@ class MainActivity : BaseActivity(), } private fun onSearchOpened() { - binding.drawer.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED) - drawerToggle.isDrawerIndicatorEnabled = false + drawer?.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED) + drawerToggle?.isDrawerIndicatorEnabled = false } private fun onSearchClosed() { - binding.drawer.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED) - drawerToggle.isDrawerIndicatorEnabled = true + drawer?.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED) + drawerToggle?.isDrawerIndicatorEnabled = true } private fun onFirstStart() { diff --git a/app/src/main/java/org/koitharu/kotatsu/utils/ext/InsetsExt.kt b/app/src/main/java/org/koitharu/kotatsu/utils/ext/InsetsExt.kt new file mode 100644 index 000000000..7276dab57 --- /dev/null +++ b/app/src/main/java/org/koitharu/kotatsu/utils/ext/InsetsExt.kt @@ -0,0 +1,20 @@ +package org.koitharu.kotatsu.utils.ext + +import android.view.View +import androidx.core.graphics.Insets + +fun Insets.getStart(view: View): Int { + return if (view.layoutDirection == View.LAYOUT_DIRECTION_RTL) { + right + } else { + left + } +} + +fun Insets.getEnd(view: View): Int { + return if (view.layoutDirection == View.LAYOUT_DIRECTION_RTL) { + left + } else { + right + } +} \ No newline at end of file diff --git a/app/src/main/res/layout-w600dp/activity_details.xml b/app/src/main/res/layout-land/activity_details.xml similarity index 100% rename from app/src/main/res/layout-w600dp/activity_details.xml rename to app/src/main/res/layout-land/activity_details.xml diff --git a/app/src/main/res/layout-w720dp-land/activity_details.xml b/app/src/main/res/layout-w720dp-land/activity_details.xml new file mode 100644 index 000000000..bcf33f71a --- /dev/null +++ b/app/src/main/res/layout-w720dp-land/activity_details.xml @@ -0,0 +1,55 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout-w720dp-land/activity_main.xml b/app/src/main/res/layout-w720dp-land/activity_main.xml new file mode 100644 index 000000000..63b80ee61 --- /dev/null +++ b/app/src/main/res/layout-w720dp-land/activity_main.xml @@ -0,0 +1,96 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index 446d1ae2f..85c1bc8c4 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -3,7 +3,6 @@ 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/drawer" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".main.ui.MainActivity"> @@ -16,6 +15,7 @@ android:id="@id/container" android:layout_width="match_parent" android:layout_height="match_parent" + tools:layout="@layout/fragment_list" app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior" /> + + + 760 + + \ No newline at end of file diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml index 734613783..e2c130bde 100644 --- a/app/src/main/res/values/dimens.xml +++ b/app/src/main/res/values/dimens.xml @@ -21,4 +21,8 @@ + + + 600 + \ No newline at end of file From 52dbd70c2f99638fdce228abac1d8e65279fa242 Mon Sep 17 00:00:00 2001 From: Zakhar Timoshenko Date: Fri, 11 Mar 2022 21:50:49 +0300 Subject: [PATCH 2/6] Some adjustments --- .../koitharu/kotatsu/main/ui/MainActivity.kt | 6 ++-- .../res/layout-w720dp-land/activity_main.xml | 31 ++++++++----------- app/src/main/res/layout/activity_main.xml | 6 +--- 3 files changed, 16 insertions(+), 27 deletions(-) diff --git a/app/src/main/java/org/koitharu/kotatsu/main/ui/MainActivity.kt b/app/src/main/java/org/koitharu/kotatsu/main/ui/MainActivity.kt index 474ea72ba..989159104 100644 --- a/app/src/main/java/org/koitharu/kotatsu/main/ui/MainActivity.kt +++ b/app/src/main/java/org/koitharu/kotatsu/main/ui/MainActivity.kt @@ -227,10 +227,8 @@ class MainActivity : BaseActivity(), leftMargin = insets.left + topMargin rightMargin = insets.right + topMargin } - if (drawer != null) { - binding.container.updateLayoutParams { - topMargin = -(binding.appbar.measureHeight()) - } + binding.container.updateLayoutParams { + topMargin = -(binding.appbar.measureHeight()) } } diff --git a/app/src/main/res/layout-w720dp-land/activity_main.xml b/app/src/main/res/layout-w720dp-land/activity_main.xml index 63b80ee61..df67c21a0 100644 --- a/app/src/main/res/layout-w720dp-land/activity_main.xml +++ b/app/src/main/res/layout-w720dp-land/activity_main.xml @@ -11,26 +11,33 @@ android:id="@+id/navigationView" android:layout_width="260dp" android:layout_height="match_parent" + android:fitsSystemWindows="false" app:drawerLayoutCornerSize="0dp" app:elevation="0dp" - android:fitsSystemWindows="false" app:menu="@menu/nav_drawer" /> + + + app:elevation="0dp" + app:liftOnScroll="false"> + android:focusableInTouchMode="true"> @@ -69,13 +71,6 @@ - - + app:contentInsetStartWithNavigation="0dp"> From 88a3589f1d9bc9bb154aee075d2406b85905e3bc Mon Sep 17 00:00:00 2001 From: Koitharu Date: Sun, 13 Mar 2022 09:53:31 +0200 Subject: [PATCH 3/6] Fix MainActivity insets --- .../koitharu/kotatsu/base/ui/BaseActivity.kt | 2 +- .../koitharu/kotatsu/base/ui/BaseFragment.kt | 11 ++++++-- .../kotatsu/details/ui/ChaptersFragment.kt | 16 ++--------- .../kotatsu/details/ui/DetailsActivity.kt | 22 ++++----------- .../kotatsu/details/ui/DetailsFragment.kt | 18 ++---------- .../kotatsu/list/ui/MangaListFragment.kt | 8 ++++-- .../koitharu/kotatsu/main/ui/MainActivity.kt | 28 ++++++++----------- .../main/ui/NavigationViewInsetsListener.kt | 24 ++++++++++++++++ .../res/layout-w720dp-land/activity_main.xml | 7 ++--- app/src/main/res/layout/activity_main.xml | 7 ++--- 10 files changed, 69 insertions(+), 74 deletions(-) create mode 100644 app/src/main/java/org/koitharu/kotatsu/main/ui/NavigationViewInsetsListener.kt diff --git a/app/src/main/java/org/koitharu/kotatsu/base/ui/BaseActivity.kt b/app/src/main/java/org/koitharu/kotatsu/base/ui/BaseActivity.kt index c14d81151..a6fc2c466 100644 --- a/app/src/main/java/org/koitharu/kotatsu/base/ui/BaseActivity.kt +++ b/app/src/main/java/org/koitharu/kotatsu/base/ui/BaseActivity.kt @@ -31,7 +31,7 @@ abstract class BaseActivity : AppCompatActivity(), OnApplyWindo @Suppress("LeakingThis") protected val exceptionResolver = ExceptionResolver(this) - private var lastInsets: Insets = Insets.NONE + private var lastInsets: Insets? = null override fun onCreate(savedInstanceState: Bundle?) { val settings = get() diff --git a/app/src/main/java/org/koitharu/kotatsu/base/ui/BaseFragment.kt b/app/src/main/java/org/koitharu/kotatsu/base/ui/BaseFragment.kt index 25ca6a503..f7b90fa01 100644 --- a/app/src/main/java/org/koitharu/kotatsu/base/ui/BaseFragment.kt +++ b/app/src/main/java/org/koitharu/kotatsu/base/ui/BaseFragment.kt @@ -9,6 +9,7 @@ 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.viewbinding.ViewBinding import org.koitharu.kotatsu.core.exceptions.resolve.ExceptionResolver @@ -23,7 +24,7 @@ abstract class BaseFragment : Fragment(), OnApplyWindowInsetsLi @Suppress("LeakingThis") protected val exceptionResolver = ExceptionResolver(this) - private var lastInsets: Insets = Insets.NONE + private var lastInsets: Insets? = null override fun onCreateView( inflater: LayoutInflater, @@ -37,12 +38,18 @@ abstract class BaseFragment : Fragment(), OnApplyWindowInsetsLi override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - lastInsets = Insets.NONE ViewCompat.setOnApplyWindowInsetsListener(view, this) + view.doOnNextLayout { + // Listener may not be called + if (lastInsets == null) { + onWindowInsetsChanged(Insets.NONE) + } + } } override fun onDestroyView() { viewBinding = null + lastInsets = null super.onDestroyView() } diff --git a/app/src/main/java/org/koitharu/kotatsu/details/ui/ChaptersFragment.kt b/app/src/main/java/org/koitharu/kotatsu/details/ui/ChaptersFragment.kt index 4f4d1e1a5..4e66273a4 100644 --- a/app/src/main/java/org/koitharu/kotatsu/details/ui/ChaptersFragment.kt +++ b/app/src/main/java/org/koitharu/kotatsu/details/ui/ChaptersFragment.kt @@ -203,19 +203,9 @@ class ChaptersFragment : BaseFragment(), } override fun onWindowInsetsChanged(insets: Insets) { - val root = binding.root - if (root.parent is FragmentContainerView) { - binding.recyclerViewChapters.updatePaddingRelative( - end = insets.getEnd(root), - bottom = insets.bottom + binding.spinnerBranches.height, - ) - } else { - binding.recyclerViewChapters.updatePadding( - left = insets.left, - right = insets.right, - bottom = insets.bottom + binding.spinnerBranches.height, - ) - } + binding.recyclerViewChapters.updatePadding( + bottom = insets.bottom + binding.spinnerBranches.height, + ) } private fun onChaptersChanged(list: List) { diff --git a/app/src/main/java/org/koitharu/kotatsu/details/ui/DetailsActivity.kt b/app/src/main/java/org/koitharu/kotatsu/details/ui/DetailsActivity.kt index 7bea427f3..10c22b67a 100644 --- a/app/src/main/java/org/koitharu/kotatsu/details/ui/DetailsActivity.kt +++ b/app/src/main/java/org/koitharu/kotatsu/details/ui/DetailsActivity.kt @@ -9,7 +9,6 @@ import android.view.MenuItem import android.view.ViewGroup import android.widget.Toast import androidx.appcompat.view.ActionMode -import androidx.appcompat.widget.Toolbar import androidx.core.content.pm.ShortcutManagerCompat import androidx.core.graphics.Insets import androidx.core.net.toFile @@ -96,22 +95,13 @@ class DetailsActivity : BaseActivity(), TabLayoutMediato binding.snackbar.updatePadding( bottom = insets.bottom ) - with(binding.toolbar) { - updatePadding( - left = insets.left, - right = insets.right - ) - updateLayoutParams { - topMargin = insets.top - } - } - val tabs = binding.tabs - if (tabs != null && tabs.parent !is Toolbar) { - tabs.updatePadding( - left = insets.left, - right = insets.right - ) + binding.toolbar.updateLayoutParams { + topMargin = insets.top } + binding.root.updatePadding( + left = insets.left, + right = insets.right + ) } private fun onNewChaptersChanged(newChapters: Int) { diff --git a/app/src/main/java/org/koitharu/kotatsu/details/ui/DetailsFragment.kt b/app/src/main/java/org/koitharu/kotatsu/details/ui/DetailsFragment.kt index 47993dd60..0b271ef64 100644 --- a/app/src/main/java/org/koitharu/kotatsu/details/ui/DetailsFragment.kt +++ b/app/src/main/java/org/koitharu/kotatsu/details/ui/DetailsFragment.kt @@ -13,8 +13,6 @@ import androidx.core.net.toUri import androidx.core.text.parseAsHtml import androidx.core.view.isVisible import androidx.core.view.updatePadding -import androidx.core.view.updatePaddingRelative -import androidx.fragment.app.FragmentContainerView import coil.ImageLoader import coil.request.ImageRequest import coil.util.CoilUtils @@ -234,19 +232,9 @@ class DetailsFragment : BaseFragment(), View.OnClickList } override fun onWindowInsetsChanged(insets: Insets) { - val root = binding.root - if (root.parent is FragmentContainerView) { - root.updatePaddingRelative( - start = insets.getStart(root), - bottom = insets.bottom, - ) - } else { - root.updatePadding( - left = insets.left, - right = insets.right, - bottom = insets.bottom, - ) - } + binding.root.updatePadding( + bottom = insets.bottom, + ) } private fun bindTags(manga: Manga) { diff --git a/app/src/main/java/org/koitharu/kotatsu/list/ui/MangaListFragment.kt b/app/src/main/java/org/koitharu/kotatsu/list/ui/MangaListFragment.kt index 70b2d8c93..796a479f3 100644 --- a/app/src/main/java/org/koitharu/kotatsu/list/ui/MangaListFragment.kt +++ b/app/src/main/java/org/koitharu/kotatsu/list/ui/MangaListFragment.kt @@ -176,17 +176,19 @@ abstract class MangaListFragment : BaseFragment(), val headerHeight = (activity as? AppBarOwner)?.appBar?.measureHeight() ?: insets.top binding.root.updatePadding( left = insets.left, - right = insets.right + right = insets.right, ) if (activity is MainActivity) { + val topOffsetDiff = binding.recyclerView.paddingTop - headerHeight binding.recyclerView.updatePadding( top = headerHeight, - bottom = insets.bottom + bottom = insets.bottom, ) + binding.recyclerView.scrollBy(0, topOffsetDiff) binding.swipeRefreshLayout.setProgressViewOffset( true, headerHeight + resources.resolveDp(-72), - headerHeight + resources.resolveDp(10) + headerHeight + resources.resolveDp(10), ) } } diff --git a/app/src/main/java/org/koitharu/kotatsu/main/ui/MainActivity.kt b/app/src/main/java/org/koitharu/kotatsu/main/ui/MainActivity.kt index 989159104..be471f458 100644 --- a/app/src/main/java/org/koitharu/kotatsu/main/ui/MainActivity.kt +++ b/app/src/main/java/org/koitharu/kotatsu/main/ui/MainActivity.kt @@ -10,13 +10,15 @@ import android.view.ViewGroup.MarginLayoutParams import androidx.appcompat.app.ActionBarDrawerToggle import androidx.core.content.ContextCompat import androidx.core.graphics.Insets -import androidx.core.view.* +import androidx.core.view.GravityCompat +import androidx.core.view.ViewCompat +import androidx.core.view.updateLayoutParams +import androidx.core.view.updatePadding import androidx.drawerlayout.widget.DrawerLayout import androidx.fragment.app.Fragment import androidx.fragment.app.FragmentTransaction import androidx.fragment.app.commit import androidx.lifecycle.lifecycleScope -import androidx.recyclerview.widget.RecyclerView import androidx.swiperefreshlayout.widget.CircularProgressDrawable import com.google.android.material.appbar.AppBarLayout import com.google.android.material.dialog.MaterialAlertDialogBuilder @@ -104,15 +106,7 @@ class MainActivity : BaseActivity(), } with(binding.navigationView) { - val menuView = - findViewById(com.google.android.material.R.id.design_navigation_view) - ViewCompat.setOnApplyWindowInsetsListener(navHeaderBinding.root) { v, insets -> - val systemWindowInsets = insets.getInsets(WindowInsetsCompat.Type.systemBars()) - v.updatePadding(top = systemWindowInsets.top) - // NavigationView doesn't dispatch insets to the menu view, so pad the bottom here. - menuView.updatePadding(bottom = systemWindowInsets.bottom) - insets - } + ViewCompat.setOnApplyWindowInsetsListener(this, NavigationViewInsetsListener()) addHeaderView(navHeaderBinding.root) setNavigationItemSelectedListener(this@MainActivity) } @@ -219,14 +213,16 @@ class MainActivity : BaseActivity(), } override fun onWindowInsetsChanged(insets: Insets) { - binding.toolbarCard.updateLayoutParams { - topMargin = insets.top + resources.resolveDp(8) - } binding.fab.updateLayoutParams { bottomMargin = insets.bottom + topMargin - leftMargin = insets.left + topMargin - rightMargin = insets.right + topMargin } + binding.toolbarCard.updateLayoutParams { + topMargin = insets.top + bottomMargin + } + binding.root.updatePadding( + left = insets.left, + right = insets.right, + ) binding.container.updateLayoutParams { topMargin = -(binding.appbar.measureHeight()) } diff --git a/app/src/main/java/org/koitharu/kotatsu/main/ui/NavigationViewInsetsListener.kt b/app/src/main/java/org/koitharu/kotatsu/main/ui/NavigationViewInsetsListener.kt new file mode 100644 index 000000000..f3a66a8fa --- /dev/null +++ b/app/src/main/java/org/koitharu/kotatsu/main/ui/NavigationViewInsetsListener.kt @@ -0,0 +1,24 @@ +package org.koitharu.kotatsu.main.ui + +import android.view.View +import androidx.core.view.OnApplyWindowInsetsListener +import androidx.core.view.WindowInsetsCompat +import androidx.core.view.updatePadding +import java.lang.ref.WeakReference +import com.google.android.material.R as materialR + +class NavigationViewInsetsListener : OnApplyWindowInsetsListener { + + private var menuViewRef: WeakReference? = null + + override fun onApplyWindowInsets(v: View, insets: WindowInsetsCompat): WindowInsetsCompat { + val menuView = menuViewRef?.get() ?: v.findViewById(materialR.id.design_navigation_view).also { + menuViewRef = WeakReference(it) + } + val systemWindowInsets = insets.getInsets(WindowInsetsCompat.Type.systemBars()) + v.updatePadding(top = systemWindowInsets.top) + // NavigationView doesn't dispatch insets to the menu view, so pad the bottom here. + menuView.updatePadding(bottom = systemWindowInsets.bottom) + return WindowInsetsCompat.CONSUMED + } +} \ No newline at end of file diff --git a/app/src/main/res/layout-w720dp-land/activity_main.xml b/app/src/main/res/layout-w720dp-land/activity_main.xml index df67c21a0..c2b7c9e5c 100644 --- a/app/src/main/res/layout-w720dp-land/activity_main.xml +++ b/app/src/main/res/layout-w720dp-land/activity_main.xml @@ -32,16 +32,15 @@ android:layout_width="match_parent" android:layout_height="wrap_content" app:elevation="0dp" + android:paddingLeft="16dp" + android:paddingRight="16dp" app:liftOnScroll="false"> @@ -29,10 +31,7 @@ android:id="@+id/toolbar_card" android:layout_width="match_parent" android:layout_height="48dp" - android:layout_marginStart="16dp" - android:layout_marginTop="8dp" - android:layout_marginEnd="16dp" - android:layout_marginBottom="8dp" + android:layout_marginVertical="8dp" android:background="@drawable/toolbar_background"> Date: Sun, 13 Mar 2022 17:10:34 +0200 Subject: [PATCH 4/6] Improve details activity layout --- .../core/parser/site/ComickFunRepository.kt | 2 +- .../kotatsu/details/ui/ChaptersFragment.kt | 40 ++-- .../kotatsu/details/ui/DetailsActivity.kt | 36 +++- .../koitharu/kotatsu/main/ui/MainActivity.kt | 1 + .../main/res/layout-land/activity_details.xml | 49 ----- .../main/res/layout-land/dialog_list_mode.xml | 81 +++++++ .../layout-w600dp-port/fragment_details.xml | 198 ------------------ .../fragment_details.xml | 44 ++-- .../layout-w720dp-land/activity_details.xml | 55 ----- .../res/layout-w720dp/activity_details.xml | 79 +++++++ .../res/layout-w720dp/fragment_chapters.xml | 28 +++ app/src/main/res/layout/activity_details.xml | 27 +-- app/src/main/res/values-w980dp/dimens.xml | 6 - app/src/main/res/values/dimens.xml | 7 - 14 files changed, 281 insertions(+), 372 deletions(-) delete mode 100644 app/src/main/res/layout-land/activity_details.xml create mode 100644 app/src/main/res/layout-land/dialog_list_mode.xml delete mode 100644 app/src/main/res/layout-w600dp-port/fragment_details.xml rename app/src/main/res/{layout-w600dp-land => layout-w600dp}/fragment_details.xml (92%) delete mode 100644 app/src/main/res/layout-w720dp-land/activity_details.xml create mode 100644 app/src/main/res/layout-w720dp/activity_details.xml create mode 100644 app/src/main/res/layout-w720dp/fragment_chapters.xml delete mode 100644 app/src/main/res/values-w980dp/dimens.xml diff --git a/app/src/main/java/org/koitharu/kotatsu/core/parser/site/ComickFunRepository.kt b/app/src/main/java/org/koitharu/kotatsu/core/parser/site/ComickFunRepository.kt index bd0b858f1..3d19907c8 100644 --- a/app/src/main/java/org/koitharu/kotatsu/core/parser/site/ComickFunRepository.kt +++ b/app/src/main/java/org/koitharu/kotatsu/core/parser/site/ComickFunRepository.kt @@ -77,7 +77,7 @@ class ComickFunRepository(loaderContext: MangaLoaderContext) : RemoteMangaReposi altTitle = null, url = slug, publicUrl = "https://$domain/comic/$slug", - rating = jo.getDouble("rating").toFloat() / 10f, + rating = jo.optDouble("rating", -10.0).toFloat() / 10f, isNsfw = false, coverUrl = jo.getString("cover_url"), largeCoverUrl = null, diff --git a/app/src/main/java/org/koitharu/kotatsu/details/ui/ChaptersFragment.kt b/app/src/main/java/org/koitharu/kotatsu/details/ui/ChaptersFragment.kt index 4e66273a4..0048e8fe5 100644 --- a/app/src/main/java/org/koitharu/kotatsu/details/ui/ChaptersFragment.kt +++ b/app/src/main/java/org/koitharu/kotatsu/details/ui/ChaptersFragment.kt @@ -4,13 +4,12 @@ import android.app.ActivityOptions import android.os.Bundle import android.view.* import android.widget.AdapterView +import android.widget.Spinner 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.core.view.updatePaddingRelative -import androidx.fragment.app.FragmentContainerView import androidx.recyclerview.widget.RecyclerView import com.google.android.material.divider.MaterialDividerItemDecoration import org.koin.androidx.viewmodel.ext.android.sharedViewModel @@ -26,7 +25,6 @@ import org.koitharu.kotatsu.details.ui.model.ChapterListItem import org.koitharu.kotatsu.download.ui.service.DownloadService import org.koitharu.kotatsu.reader.ui.ReaderActivity import org.koitharu.kotatsu.reader.ui.ReaderState -import org.koitharu.kotatsu.utils.ext.getEnd class ChaptersFragment : BaseFragment(), OnListItemClickListener, @@ -59,21 +57,9 @@ class ChaptersFragment : BaseFragment(), setHasFixedSize(true) adapter = chaptersAdapter } - val branchesAdapter = BranchesAdapter() - binding.spinnerBranches.adapter = branchesAdapter - binding.spinnerBranches.onItemSelectedListener = this - + binding.spinnerBranches?.let(::initSpinner) viewModel.isLoading.observe(viewLifecycleOwner, this::onLoadingStateChanged) viewModel.chapters.observe(viewLifecycleOwner, this::onChaptersChanged) - viewModel.branches.observe(viewLifecycleOwner) { - branchesAdapter.setItems(it) - binding.spinnerBranches.isVisible = it.size > 1 - } - viewModel.selectedBranchIndex.observe(viewLifecycleOwner) { - if (it != -1 && it != binding.spinnerBranches.selectedItemPosition) { - binding.spinnerBranches.setSelection(it) - } - } viewModel.isChaptersReversed.observe(viewLifecycleOwner) { activity?.invalidateOptionsMenu() } @@ -82,7 +68,7 @@ class ChaptersFragment : BaseFragment(), override fun onDestroyView() { chaptersAdapter = null selectionDecoration = null - binding.spinnerBranches.adapter = null + binding.spinnerBranches?.adapter = null super.onDestroyView() } @@ -169,7 +155,8 @@ class ChaptersFragment : BaseFragment(), } override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) { - viewModel.setSelectedBranch(binding.spinnerBranches.selectedItem as String?) + val spinner = binding.spinnerBranches ?: return + viewModel.setSelectedBranch(spinner.selectedItem as String?) } override fun onNothingSelected(parent: AdapterView<*>?) = Unit @@ -204,10 +191,25 @@ class ChaptersFragment : BaseFragment(), override fun onWindowInsetsChanged(insets: Insets) { binding.recyclerViewChapters.updatePadding( - bottom = insets.bottom + binding.spinnerBranches.height, + bottom = insets.bottom + (binding.spinnerBranches?.height ?: 0), ) } + private fun initSpinner(spinner: Spinner) { + val branchesAdapter = BranchesAdapter() + spinner.adapter = branchesAdapter + spinner.onItemSelectedListener = this + viewModel.branches.observe(viewLifecycleOwner) { + branchesAdapter.setItems(it) + spinner.isVisible = it.size > 1 + } + viewModel.selectedBranchIndex.observe(viewLifecycleOwner) { + if (it != -1 && it != spinner.selectedItemPosition) { + spinner.setSelection(it) + } + } + } + private fun onChaptersChanged(list: List) { chaptersAdapter?.items = list } diff --git a/app/src/main/java/org/koitharu/kotatsu/details/ui/DetailsActivity.kt b/app/src/main/java/org/koitharu/kotatsu/details/ui/DetailsActivity.kt index 10c22b67a..24bf3130b 100644 --- a/app/src/main/java/org/koitharu/kotatsu/details/ui/DetailsActivity.kt +++ b/app/src/main/java/org/koitharu/kotatsu/details/ui/DetailsActivity.kt @@ -6,12 +6,16 @@ import android.net.Uri import android.os.Bundle import android.view.Menu import android.view.MenuItem +import android.view.View import android.view.ViewGroup +import android.widget.AdapterView +import android.widget.Spinner import android.widget.Toast import androidx.appcompat.view.ActionMode import androidx.core.content.pm.ShortcutManagerCompat import androidx.core.graphics.Insets import androidx.core.net.toFile +import androidx.core.view.isVisible import androidx.core.view.updateLayoutParams import androidx.core.view.updatePadding import androidx.lifecycle.lifecycleScope @@ -32,6 +36,7 @@ import org.koitharu.kotatsu.core.model.Manga import org.koitharu.kotatsu.core.model.MangaSource import org.koitharu.kotatsu.core.os.ShortcutsRepository import org.koitharu.kotatsu.databinding.ActivityDetailsBinding +import org.koitharu.kotatsu.details.ui.adapter.BranchesAdapter import org.koitharu.kotatsu.download.ui.service.DownloadService import org.koitharu.kotatsu.reader.ui.ReaderActivity import org.koitharu.kotatsu.reader.ui.ReaderState @@ -40,7 +45,8 @@ import org.koitharu.kotatsu.utils.ShareHelper import org.koitharu.kotatsu.utils.ext.buildAlertDialog import org.koitharu.kotatsu.utils.ext.getDisplayMessage -class DetailsActivity : BaseActivity(), TabLayoutMediator.TabConfigurationStrategy { +class DetailsActivity : BaseActivity(), TabLayoutMediator.TabConfigurationStrategy, + AdapterView.OnItemSelectedListener { private val viewModel by viewModel { parametersOf(MangaIntent(intent)) @@ -49,12 +55,16 @@ class DetailsActivity : BaseActivity(), TabLayoutMediato override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(ActivityDetailsBinding.inflate(layoutInflater)) - supportActionBar?.setDisplayHomeAsUpEnabled(true) + supportActionBar?.run { + setDisplayHomeAsUpEnabled(true) + setDisplayShowTitleEnabled(false) + } val pager = binding.pager if (pager != null) { pager.adapter = MangaDetailsAdapter(this) TabLayoutMediator(checkNotNull(binding.tabs), pager, this).attach() } + binding.spinnerBranches?.let(::initSpinner) viewModel.manga.observe(this, ::onMangaUpdated) viewModel.newChaptersCount.observe(this, ::onNewChaptersChanged) @@ -226,6 +236,13 @@ class DetailsActivity : BaseActivity(), TabLayoutMediato binding.pager?.isUserInputEnabled = true } + override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) { + val spinner = binding.spinnerBranches ?: return + viewModel.setSelectedBranch(spinner.selectedItem as String?) + } + + override fun onNothingSelected(parent: AdapterView<*>?) = Unit + fun showChapterMissingDialog(chapterId: Long) { val remoteManga = viewModel.getRemoteManga() if (remoteManga == null) { @@ -252,6 +269,21 @@ class DetailsActivity : BaseActivity(), TabLayoutMediato }.show() } + private fun initSpinner(spinner: Spinner) { + val branchesAdapter = BranchesAdapter() + spinner.adapter = branchesAdapter + spinner.onItemSelectedListener = this + viewModel.branches.observe(this) { + branchesAdapter.setItems(it) + spinner.isVisible = it.size > 1 + } + viewModel.selectedBranchIndex.observe(this) { + if (it != -1 && it != spinner.selectedItemPosition) { + spinner.setSelection(it) + } + } + } + companion object { fun newIntent(context: Context, manga: Manga): Intent { diff --git a/app/src/main/java/org/koitharu/kotatsu/main/ui/MainActivity.kt b/app/src/main/java/org/koitharu/kotatsu/main/ui/MainActivity.kt index be471f458..b8d8cb999 100644 --- a/app/src/main/java/org/koitharu/kotatsu/main/ui/MainActivity.kt +++ b/app/src/main/java/org/koitharu/kotatsu/main/ui/MainActivity.kt @@ -209,6 +209,7 @@ class MainActivity : BaseActivity(), } } drawer?.closeDrawers() + appBar.setExpanded(true) return true } diff --git a/app/src/main/res/layout-land/activity_details.xml b/app/src/main/res/layout-land/activity_details.xml deleted file mode 100644 index 6bf664eea..000000000 --- a/app/src/main/res/layout-land/activity_details.xml +++ /dev/null @@ -1,49 +0,0 @@ - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/layout-land/dialog_list_mode.xml b/app/src/main/res/layout-land/dialog_list_mode.xml new file mode 100644 index 000000000..f103a0ac3 --- /dev/null +++ b/app/src/main/res/layout-land/dialog_list_mode.xml @@ -0,0 +1,81 @@ + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout-w600dp-port/fragment_details.xml b/app/src/main/res/layout-w600dp-port/fragment_details.xml deleted file mode 100644 index c42301de6..000000000 --- a/app/src/main/res/layout-w600dp-port/fragment_details.xml +++ /dev/null @@ -1,198 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/layout-w600dp-land/fragment_details.xml b/app/src/main/res/layout-w600dp/fragment_details.xml similarity index 92% rename from app/src/main/res/layout-w600dp-land/fragment_details.xml rename to app/src/main/res/layout-w600dp/fragment_details.xml index 55df1bb95..d751d0c6c 100644 --- a/app/src/main/res/layout-w600dp-land/fragment_details.xml +++ b/app/src/main/res/layout-w600dp/fragment_details.xml @@ -17,8 +17,8 @@ android:id="@+id/imageView_cover" android:layout_width="0dp" android:layout_height="wrap_content" - android:layout_marginStart="16dp" - android:layout_marginTop="16dp" + android:layout_marginStart="8dp" + android:layout_marginTop="8dp" android:foreground="?selectableItemBackground" android:scaleType="centerCrop" android:transitionName="cover" @@ -35,9 +35,9 @@ android:id="@+id/textView_title" android:layout_width="0dp" android:layout_height="wrap_content" - android:layout_marginStart="16dp" - android:layout_marginTop="16dp" - android:layout_marginEnd="16dp" + android:layout_marginStart="8dp" + android:layout_marginTop="8dp" + android:layout_marginEnd="8dp" android:ellipsize="end" android:maxLines="3" android:textAppearance="?attr/textAppearanceHeadlineSmall" @@ -50,9 +50,9 @@ android:id="@+id/textView_subtitle" android:layout_width="0dp" android:layout_height="wrap_content" - android:layout_marginStart="16dp" - android:layout_marginTop="6dp" - android:layout_marginEnd="16dp" + android:layout_marginStart="8dp" + android:layout_marginTop="4dp" + android:layout_marginEnd="8dp" android:ellipsize="end" android:maxLines="3" android:textAppearance="?attr/textAppearanceBodyMedium" @@ -65,11 +65,11 @@ android:id="@+id/textView_author" android:layout_width="0dp" android:layout_height="wrap_content" - android:layout_marginStart="12dp" + android:layout_marginStart="6dp" android:layout_marginTop="2dp" - android:layout_marginEnd="12dp" + android:layout_marginEnd="6dp" android:background="@drawable/list_selector" - android:padding="4dp" + android:padding="2dp" android:singleLine="true" android:textColor="?attr/colorTertiary" android:textStyle="bold" @@ -84,9 +84,9 @@ android:id="@+id/textView_state" android:layout_width="0dp" android:layout_height="wrap_content" - android:layout_marginStart="16dp" + android:layout_marginStart="8dp" android:layout_marginTop="4dp" - android:layout_marginEnd="16dp" + android:layout_marginEnd="8dp" android:drawablePadding="4dp" android:singleLine="true" android:textAppearance="?attr/textAppearanceBodySmall" @@ -96,12 +96,19 @@ tools:drawableStart="@drawable/ic_state_finished" tools:text="Finished" /> + + @@ -128,7 +135,6 @@ android:layout_width="0dp" android:layout_height="wrap_content" android:layout_marginStart="16dp" - android:layout_marginTop="16dp" android:layout_marginEnd="16dp" android:enabled="false" android:text="@string/read" @@ -140,14 +146,6 @@ app:layout_constraintTop_toBottomOf="@id/info_layout" tools:text="@string/_continue" /> - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/layout-w720dp/activity_details.xml b/app/src/main/res/layout-w720dp/activity_details.xml new file mode 100644 index 000000000..337b9ec77 --- /dev/null +++ b/app/src/main/res/layout-w720dp/activity_details.xml @@ -0,0 +1,79 @@ + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout-w720dp/fragment_chapters.xml b/app/src/main/res/layout-w720dp/fragment_chapters.xml new file mode 100644 index 000000000..386ce6fb0 --- /dev/null +++ b/app/src/main/res/layout-w720dp/fragment_chapters.xml @@ -0,0 +1,28 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_details.xml b/app/src/main/res/layout/activity_details.xml index 5a723948f..8190e9c82 100644 --- a/app/src/main/res/layout/activity_details.xml +++ b/app/src/main/res/layout/activity_details.xml @@ -3,7 +3,6 @@ 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/coordinator" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".details.ui.DetailsActivity"> @@ -12,24 +11,28 @@ android:id="@+id/appbar" android:layout_width="match_parent" android:layout_height="wrap_content" - app:liftOnScroll="false" - app:elevation="0dp"> + app:elevation="0dp" + app:liftOnScroll="false"> + app:layout_scrollFlags="scroll|enterAlways" + tools:ignore="PrivateResource"> - + + + diff --git a/app/src/main/res/values-w980dp/dimens.xml b/app/src/main/res/values-w980dp/dimens.xml deleted file mode 100644 index 32b68f0c3..000000000 --- a/app/src/main/res/values-w980dp/dimens.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - 760 - - \ No newline at end of file diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml index e2c130bde..5003ad1fc 100644 --- a/app/src/main/res/values/dimens.xml +++ b/app/src/main/res/values/dimens.xml @@ -18,11 +18,4 @@ 36dp 48dp 16dp - - - - - - 600 - \ No newline at end of file From 8b295f6a9301c0c65e24e8668ecffabc0d00f925 Mon Sep 17 00:00:00 2001 From: Koitharu Date: Sun, 13 Mar 2022 17:50:49 +0200 Subject: [PATCH 5/6] Fix dialogs width --- .../kotatsu/base/ui/BaseBottomSheet.kt | 2 +- .../kotatsu/reader/ui/ReaderActivity.kt | 10 ++- .../res/layout-w600dp/activity_reader.xml | 83 +++++++++++++++++++ app/src/main/res/values/themes.xml | 8 ++ 4 files changed, 98 insertions(+), 5 deletions(-) create mode 100644 app/src/main/res/layout-w600dp/activity_reader.xml diff --git a/app/src/main/java/org/koitharu/kotatsu/base/ui/BaseBottomSheet.kt b/app/src/main/java/org/koitharu/kotatsu/base/ui/BaseBottomSheet.kt index d65e031fa..b2146c3ba 100644 --- a/app/src/main/java/org/koitharu/kotatsu/base/ui/BaseBottomSheet.kt +++ b/app/src/main/java/org/koitharu/kotatsu/base/ui/BaseBottomSheet.kt @@ -42,7 +42,7 @@ abstract class BaseBottomSheet : BottomSheetDialogFragment() { override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { return if (resources.getBoolean(R.bool.is_tablet)) { - AppCompatDialog(context, theme) + AppCompatDialog(context, R.style.Theme_Kotatsu_Dialog) } else super.onCreateDialog(savedInstanceState) } diff --git a/app/src/main/java/org/koitharu/kotatsu/reader/ui/ReaderActivity.kt b/app/src/main/java/org/koitharu/kotatsu/reader/ui/ReaderActivity.kt index cd15c2bfa..791bc316f 100644 --- a/app/src/main/java/org/koitharu/kotatsu/reader/ui/ReaderActivity.kt +++ b/app/src/main/java/org/koitharu/kotatsu/reader/ui/ReaderActivity.kt @@ -241,7 +241,7 @@ class ReaderActivity : BaseFullscreenActivity(), rawX >= binding.root.width - gestureInsets.right || rawY >= binding.root.height - gestureInsets.bottom || binding.appbarTop.hasGlobalPoint(rawX, rawY) || - binding.appbarBottom.hasGlobalPoint(rawX, rawY) + binding.appbarBottom?.hasGlobalPoint(rawX, rawY) == true ) { false } else { @@ -318,11 +318,13 @@ class ReaderActivity : BaseFullscreenActivity(), if (binding.appbarTop.isVisible != isUiVisible) { val transition = TransitionSet() .setOrdering(TransitionSet.ORDERING_TOGETHER) - .addTransition(Slide(Gravity.BOTTOM).addTarget(binding.appbarBottom)) .addTransition(Slide(Gravity.TOP).addTarget(binding.appbarTop)) + binding.appbarBottom?.let { botomBar -> + transition.addTransition(Slide(Gravity.BOTTOM).addTarget(botomBar)) + } TransitionManager.beginDelayedTransition(binding.root, transition) binding.appbarTop.isVisible = isUiVisible - binding.appbarBottom.isVisible = isUiVisible + binding.appbarBottom?.isVisible = isUiVisible if (isUiVisible) { showSystemUI() } else { @@ -339,7 +341,7 @@ class ReaderActivity : BaseFullscreenActivity(), right = systemBars.right, left = systemBars.left ) - binding.appbarBottom.updatePadding( + binding.appbarBottom?.updatePadding( bottom = systemBars.bottom, right = systemBars.right, left = systemBars.left diff --git a/app/src/main/res/layout-w600dp/activity_reader.xml b/app/src/main/res/layout-w600dp/activity_reader.xml new file mode 100644 index 000000000..90a78c533 --- /dev/null +++ b/app/src/main/res/layout-w600dp/activity_reader.xml @@ -0,0 +1,83 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml index d1b29006e..a51ebf1e4 100644 --- a/app/src/main/res/values/themes.xml +++ b/app/src/main/res/values/themes.xml @@ -85,4 +85,12 @@ + From 150699f64d137912794fb64d40cf836f8c391d03 Mon Sep 17 00:00:00 2001 From: Koitharu Date: Sun, 13 Mar 2022 18:37:11 +0200 Subject: [PATCH 6/6] Improve thumbnails bs --- .../kotatsu/details/ui/ChaptersFragment.kt | 13 ++++++++++- .../kotatsu/reader/ui/ChaptersBottomSheet.kt | 11 ++------- .../ui/thumbnails/PagesThumbnailsSheet.kt | 23 ++++++++----------- .../ui/thumbnails/adapter/PageThumbnailAD.kt | 7 ++++-- .../adapter/SearchSuggestionsMangaListAD.kt | 4 ++-- .../utils/RecyclerViewScrollCallback.kt | 21 +++++++++++++++++ .../kotatsu/utils/ScrollResetCallback.kt | 13 ----------- .../koitharu/kotatsu/utils/ext/TextViewExt.kt | 9 ++++++++ app/src/main/res/drawable/bg_badge_empty.xml | 15 ++++++++++++ app/src/main/res/layout/item_page_thumb.xml | 16 +++++-------- 10 files changed, 81 insertions(+), 51 deletions(-) create mode 100644 app/src/main/java/org/koitharu/kotatsu/utils/RecyclerViewScrollCallback.kt delete mode 100644 app/src/main/java/org/koitharu/kotatsu/utils/ScrollResetCallback.kt create mode 100644 app/src/main/res/drawable/bg_badge_empty.xml diff --git a/app/src/main/java/org/koitharu/kotatsu/details/ui/ChaptersFragment.kt b/app/src/main/java/org/koitharu/kotatsu/details/ui/ChaptersFragment.kt index 0048e8fe5..ac2b0e163 100644 --- a/app/src/main/java/org/koitharu/kotatsu/details/ui/ChaptersFragment.kt +++ b/app/src/main/java/org/koitharu/kotatsu/details/ui/ChaptersFragment.kt @@ -25,6 +25,7 @@ import org.koitharu.kotatsu.details.ui.model.ChapterListItem import org.koitharu.kotatsu.download.ui.service.DownloadService import org.koitharu.kotatsu.reader.ui.ReaderActivity import org.koitharu.kotatsu.reader.ui.ReaderState +import org.koitharu.kotatsu.utils.RecyclerViewScrollCallback class ChaptersFragment : BaseFragment(), OnListItemClickListener, @@ -211,7 +212,17 @@ class ChaptersFragment : BaseFragment(), } private fun onChaptersChanged(list: List) { - chaptersAdapter?.items = list + val adapter = chaptersAdapter ?: return + if (adapter.itemCount == 0) { + val position = list.indexOfFirst { it.hasFlag(ChapterListItem.FLAG_CURRENT) } - 1 + if (position > 0) { + adapter.setItems(list, RecyclerViewScrollCallback(binding.recyclerViewChapters, position)) + } else { + adapter.items = list + } + } else { + adapter.items = list + } } private fun onLoadingStateChanged(isLoading: Boolean) { diff --git a/app/src/main/java/org/koitharu/kotatsu/reader/ui/ChaptersBottomSheet.kt b/app/src/main/java/org/koitharu/kotatsu/reader/ui/ChaptersBottomSheet.kt index 3b079255a..565538456 100644 --- a/app/src/main/java/org/koitharu/kotatsu/reader/ui/ChaptersBottomSheet.kt +++ b/app/src/main/java/org/koitharu/kotatsu/reader/ui/ChaptersBottomSheet.kt @@ -5,7 +5,6 @@ import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import androidx.fragment.app.FragmentManager -import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView import com.google.android.material.divider.MaterialDividerItemDecoration import org.koin.android.ext.android.get @@ -19,6 +18,7 @@ import org.koitharu.kotatsu.details.ui.adapter.ChaptersAdapter import org.koitharu.kotatsu.details.ui.model.ChapterListItem import org.koitharu.kotatsu.details.ui.model.toListItem import org.koitharu.kotatsu.utils.BottomSheetToolbarController +import org.koitharu.kotatsu.utils.RecyclerViewScrollCallback import org.koitharu.kotatsu.utils.ext.withArgs class ChaptersBottomSheet : BaseBottomSheet(), OnListItemClickListener { @@ -58,7 +58,7 @@ class ChaptersBottomSheet : BaseBottomSheet(), OnListItemC binding.recyclerView.adapter = ChaptersAdapter(this).also { adapter -> if (currentPosition >= 0) { val targetPosition = (currentPosition - 1).coerceAtLeast(0) - adapter.setItems(items, Scroller(binding.recyclerView, targetPosition)) + adapter.setItems(items, RecyclerViewScrollCallback(binding.recyclerView, targetPosition)) } else { adapter.items = items } @@ -77,13 +77,6 @@ class ChaptersBottomSheet : BaseBottomSheet(), OnListItemC fun onChapterChanged(chapter: MangaChapter) } - private class Scroller(private val recyclerView: RecyclerView, private val position: Int) : Runnable { - override fun run() { - val offset = recyclerView.resources.getDimensionPixelSize(R.dimen.chapter_list_item_height) / 2 - (recyclerView.layoutManager as LinearLayoutManager).scrollToPositionWithOffset(position, offset) - } - } - companion object { private const val ARG_CHAPTERS = "chapters" diff --git a/app/src/main/java/org/koitharu/kotatsu/reader/ui/thumbnails/PagesThumbnailsSheet.kt b/app/src/main/java/org/koitharu/kotatsu/reader/ui/thumbnails/PagesThumbnailsSheet.kt index 314b281dc..cbd82c22d 100644 --- a/app/src/main/java/org/koitharu/kotatsu/reader/ui/thumbnails/PagesThumbnailsSheet.kt +++ b/app/src/main/java/org/koitharu/kotatsu/reader/ui/thumbnails/PagesThumbnailsSheet.kt @@ -6,7 +6,7 @@ import android.view.View import android.view.ViewGroup import androidx.appcompat.widget.Toolbar import androidx.fragment.app.FragmentManager -import androidx.recyclerview.widget.RecyclerView +import androidx.recyclerview.widget.GridLayoutManager import com.google.android.material.bottomsheet.BottomSheetBehavior import org.koin.android.ext.android.get import org.koitharu.kotatsu.R @@ -28,6 +28,7 @@ class PagesThumbnailsSheet : BaseBottomSheet(), private lateinit var thumbnails: List private val spanResolver = MangaListSpanResolver() + private var currentPageIndex = -1 override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -36,12 +37,12 @@ class PagesThumbnailsSheet : BaseBottomSheet(), dismissAllowingStateLoss() return } - val current = arguments?.getInt(ARG_CURRENT, -1) ?: -1 + currentPageIndex = requireArguments().getInt(ARG_CURRENT, currentPageIndex) val repository = mangaRepositoryOf(pages.first().source) thumbnails = pages.mapIndexed { i, x -> PageThumbnail( number = i + 1, - isCurrent = i == current, + isCurrent = i == currentPageIndex, repository = repository, page = x ) @@ -68,11 +69,9 @@ class PagesThumbnailsSheet : BaseBottomSheet(), resources.getQuantityString(R.plurals.pages, thumbnails.size, thumbnails.size) } - val initialTopPosition = binding.recyclerView.top - with(binding.recyclerView) { addItemDecoration( - SpacingItemDecoration(view.resources.getDimensionPixelOffset(R.dimen.grid_spacing)) + SpacingItemDecoration(resources.getDimensionPixelOffset(R.dimen.grid_spacing)) ) adapter = PageThumbnailAdapter( thumbnails, @@ -81,16 +80,12 @@ class PagesThumbnailsSheet : BaseBottomSheet(), get(), this@PagesThumbnailsSheet ) - addOnScrollListener(object : RecyclerView.OnScrollListener() { - override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) = Unit - - override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) { - super.onScrolled(recyclerView, dx, dy) - binding.appbar.isLifted = getChildAt(0).top < initialTopPosition - } - }) addOnLayoutChangeListener(spanResolver) spanResolver.setGridSize(get().gridSize / 100f, this) + if (currentPageIndex > 0) { + val offset = resources.getDimensionPixelOffset(R.dimen.preferred_grid_width) + (layoutManager as GridLayoutManager).scrollToPositionWithOffset(currentPageIndex, offset) + } } } diff --git a/app/src/main/java/org/koitharu/kotatsu/reader/ui/thumbnails/adapter/PageThumbnailAD.kt b/app/src/main/java/org/koitharu/kotatsu/reader/ui/thumbnails/adapter/PageThumbnailAD.kt index 2ae446b4f..6f06eae33 100644 --- a/app/src/main/java/org/koitharu/kotatsu/reader/ui/thumbnails/adapter/PageThumbnailAD.kt +++ b/app/src/main/java/org/koitharu/kotatsu/reader/ui/thumbnails/adapter/PageThumbnailAD.kt @@ -14,6 +14,8 @@ import org.koitharu.kotatsu.local.data.PagesCache import org.koitharu.kotatsu.reader.ui.thumbnails.PageThumbnail import org.koitharu.kotatsu.utils.ext.IgnoreErrors import org.koitharu.kotatsu.utils.ext.referer +import org.koitharu.kotatsu.utils.ext.setTextColorAttr +import com.google.android.material.R as materialR fun pageThumbnailAD( coil: ImageLoader, @@ -31,7 +33,7 @@ fun pageThumbnailAD( height = (gridWidth * 13f / 18f).toInt() ) - binding.handle.setOnClickListener { + binding.root.setOnClickListener { clickListener.onItemClick(item.page, itemView) } @@ -39,7 +41,8 @@ fun pageThumbnailAD( job?.cancel() binding.imageViewThumb.setImageDrawable(null) with(binding.textViewNumber) { - setBackgroundResource(if (item.isCurrent) R.drawable.bg_badge_accent else R.drawable.bg_badge_default) + setBackgroundResource(if (item.isCurrent) R.drawable.bg_badge_accent else R.drawable.bg_badge_empty) + setTextColorAttr(if (item.isCurrent) materialR.attr.colorOnTertiary else android.R.attr.textColorPrimary) text = (item.number).toString() } job = scope.launch(Dispatchers.Default + IgnoreErrors) { diff --git a/app/src/main/java/org/koitharu/kotatsu/search/ui/suggestion/adapter/SearchSuggestionsMangaListAD.kt b/app/src/main/java/org/koitharu/kotatsu/search/ui/suggestion/adapter/SearchSuggestionsMangaListAD.kt index 9c3eb37b1..549baf947 100644 --- a/app/src/main/java/org/koitharu/kotatsu/search/ui/suggestion/adapter/SearchSuggestionsMangaListAD.kt +++ b/app/src/main/java/org/koitharu/kotatsu/search/ui/suggestion/adapter/SearchSuggestionsMangaListAD.kt @@ -15,7 +15,7 @@ import org.koitharu.kotatsu.core.model.Manga import org.koitharu.kotatsu.databinding.ItemSearchSuggestionMangaGridBinding import org.koitharu.kotatsu.search.ui.suggestion.SearchSuggestionListener import org.koitharu.kotatsu.search.ui.suggestion.model.SearchSuggestionItem -import org.koitharu.kotatsu.utils.ScrollResetCallback +import org.koitharu.kotatsu.utils.RecyclerViewScrollCallback import org.koitharu.kotatsu.utils.ext.enqueueWith import org.koitharu.kotatsu.utils.ext.newImageRequest @@ -37,7 +37,7 @@ fun searchSuggestionMangaListAD( right = recyclerView.paddingRight - spacing, ) recyclerView.addItemDecoration(SpacingItemDecoration(spacing)) - val scrollResetCallback = ScrollResetCallback(recyclerView) + val scrollResetCallback = RecyclerViewScrollCallback(recyclerView, 0) bind { adapter.setItems(item.items, scrollResetCallback) diff --git a/app/src/main/java/org/koitharu/kotatsu/utils/RecyclerViewScrollCallback.kt b/app/src/main/java/org/koitharu/kotatsu/utils/RecyclerViewScrollCallback.kt new file mode 100644 index 000000000..984867ae4 --- /dev/null +++ b/app/src/main/java/org/koitharu/kotatsu/utils/RecyclerViewScrollCallback.kt @@ -0,0 +1,21 @@ +package org.koitharu.kotatsu.utils + +import androidx.recyclerview.widget.LinearLayoutManager +import androidx.recyclerview.widget.RecyclerView +import java.lang.ref.WeakReference + +class RecyclerViewScrollCallback(recyclerView: RecyclerView, private val position: Int) : Runnable { + + private val recyclerViewRef = WeakReference(recyclerView) + + override fun run() { + val rv = recyclerViewRef.get() ?: return + val lm = rv.layoutManager ?: return + rv.stopScroll() + if (lm is LinearLayoutManager) { + lm.scrollToPositionWithOffset(position, 0) + } else { + lm.scrollToPosition(position) + } + } +} \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/utils/ScrollResetCallback.kt b/app/src/main/java/org/koitharu/kotatsu/utils/ScrollResetCallback.kt deleted file mode 100644 index 5a279f4ec..000000000 --- a/app/src/main/java/org/koitharu/kotatsu/utils/ScrollResetCallback.kt +++ /dev/null @@ -1,13 +0,0 @@ -package org.koitharu.kotatsu.utils - -import androidx.recyclerview.widget.RecyclerView -import java.lang.ref.WeakReference - -class ScrollResetCallback(recyclerView: RecyclerView) : Runnable { - - private val recyclerViewRef = WeakReference(recyclerView) - - override fun run() { - recyclerViewRef.get()?.scrollToPosition(0) - } -} \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/utils/ext/TextViewExt.kt b/app/src/main/java/org/koitharu/kotatsu/utils/ext/TextViewExt.kt index 05df723de..59620f2b0 100644 --- a/app/src/main/java/org/koitharu/kotatsu/utils/ext/TextViewExt.kt +++ b/app/src/main/java/org/koitharu/kotatsu/utils/ext/TextViewExt.kt @@ -3,7 +3,9 @@ package org.koitharu.kotatsu.utils.ext import android.graphics.drawable.Drawable import android.view.View import android.widget.TextView +import androidx.annotation.AttrRes import androidx.annotation.StringRes +import androidx.core.content.res.use import androidx.core.view.isGone var TextView.textAndVisible: CharSequence? @@ -35,4 +37,11 @@ fun TextView.setTextAndVisible(@StringRes textResId: Int) { setText(textResId) isGone = text.isNullOrEmpty() } +} + +fun TextView.setTextColorAttr(@AttrRes attrResId: Int) { + val colors = context.obtainStyledAttributes(intArrayOf(attrResId)).use { + it.getColorStateList(0) + } + setTextColor(colors) } \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_badge_empty.xml b/app/src/main/res/drawable/bg_badge_empty.xml new file mode 100644 index 000000000..55ad85bd1 --- /dev/null +++ b/app/src/main/res/drawable/bg_badge_empty.xml @@ -0,0 +1,15 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_page_thumb.xml b/app/src/main/res/layout/item_page_thumb.xml index 6d9924b86..2ed3ec94c 100644 --- a/app/src/main/res/layout/item_page_thumb.xml +++ b/app/src/main/res/layout/item_page_thumb.xml @@ -1,10 +1,12 @@ - + xmlns:app="http://schemas.android.com/apk/res-auto" + style="@style/Widget.Material3.CardView.Outlined" + app:cardBackgroundColor="?scrimBackground"> - - - \ No newline at end of file + \ No newline at end of file