Using a dialog for the full cover transition in manga details

which will optimize the blur by a lot

(also adding in the manga detail button styles from upstream, not using it for anything but save/share)
This commit is contained in:
Jays2Kings 2021-07-20 13:07:30 -04:00
parent 3c8e30606e
commit a0bc45af46
7 changed files with 387 additions and 262 deletions

View File

@ -0,0 +1,251 @@
package eu.kanade.tachiyomi.ui.manga
import android.animation.AnimatorSet
import android.animation.ValueAnimator
import android.app.Dialog
import android.graphics.Color
import android.graphics.Rect
import android.graphics.drawable.Drawable
import android.os.Build
import android.view.LayoutInflater
import android.view.View
import android.view.animation.DecelerateInterpolator
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.animation.addListener
import androidx.transition.ChangeBounds
import androidx.transition.ChangeImageTransform
import androidx.transition.TransitionManager
import androidx.transition.TransitionSet
import com.google.android.material.shape.CornerFamily
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.databinding.FullCoverDialogBinding
import eu.kanade.tachiyomi.util.system.dpToPx
import eu.kanade.tachiyomi.util.view.animateBlur
import eu.kanade.tachiyomi.util.view.updateLayoutParams
import uy.kohesive.injekt.injectLazy
class FullCoverDialog(val controller: MangaDetailsController, drawable: Drawable, val thumbView: View) :
Dialog(controller.activity!!, R.style.FullCoverDialogTheme) {
val activity = controller.activity
val binding = FullCoverDialogBinding.inflate(LayoutInflater.from(context), null, false)
val preferences: PreferencesHelper by injectLazy()
private val ratio = 5f.dpToPx
private val fullRatio = 0f
val shortAnimationDuration = (
activity?.resources?.getInteger(
android.R.integer.config_shortAnimTime
) ?: 0
).toLong()
init {
setContentView(binding.root)
binding.touchOutside.setOnClickListener {
onBackPressed()
}
binding.mangaCoverFull.setOnClickListener {
onBackPressed()
}
binding.btnSave.setOnClickListener {
controller.saveCover()
}
binding.btnShare.setOnClickListener {
controller.shareCover()
}
val expandedImageView = binding.mangaCoverFull
expandedImageView.shapeAppearanceModel =
expandedImageView.shapeAppearanceModel.toBuilder()
.setAllCorners(CornerFamily.ROUNDED, ratio)
.build()
expandedImageView.setImageDrawable(drawable)
val rect = Rect()
thumbView.getGlobalVisibleRect(rect)
val topInset = activity?.window?.decorView?.rootWindowInsets?.systemWindowInsetTop ?: 0
val leftInset = activity?.window?.decorView?.rootWindowInsets?.systemWindowInsetLeft ?: 0
val rightInset = activity?.window?.decorView?.rootWindowInsets?.systemWindowInsetRight ?: 0
expandedImageView.updateLayoutParams<ConstraintLayout.LayoutParams> {
height = thumbView.height
width = thumbView.width
topMargin = rect.top - topInset
leftMargin = rect.left - leftInset
rightMargin = rect.right - rightInset
bottomMargin = rect.bottom
horizontalBias = 0.0f
verticalBias = 0.0f
}
expandedImageView.requestLayout()
binding.btnShare.alpha = 0f
binding.btnSave.alpha = 0f
expandedImageView.post {
// Hide the thumbnail and show the zoomed-in view. When the animation
// begins, it will position the zoomed-in view in the place of the
// thumbnail.
thumbView.alpha = 0f
val defMargin = 16.dpToPx
if (Build.VERSION.SDK_INT >= 31) {
activity?.window?.decorView?.animateBlur(1f, 20f, 50)?.start()
}
expandedImageView.updateLayoutParams<ConstraintLayout.LayoutParams> {
height = 0
width = 0
topMargin = defMargin
leftMargin = defMargin
rightMargin = defMargin
bottomMargin = defMargin
horizontalBias = 0.5f
verticalBias = 0.5f
}
// TransitionSet for the full cover because using animation for this SUCKS
val transitionSet = TransitionSet()
val bound = ChangeBounds()
transitionSet.addTransition(bound)
val changeImageTransform = ChangeImageTransform()
transitionSet.addTransition(changeImageTransform)
transitionSet.duration = shortAnimationDuration
TransitionManager.beginDelayedTransition(binding.root, transitionSet)
AnimatorSet().apply {
val radiusAnimator = ValueAnimator.ofFloat(ratio, fullRatio).apply {
addUpdateListener {
val value = it.animatedValue as Float
expandedImageView.shapeAppearanceModel =
expandedImageView.shapeAppearanceModel.toBuilder()
.setAllCorners(CornerFamily.ROUNDED, value)
.build()
}
duration = shortAnimationDuration
}
val saveAnimator = ValueAnimator.ofFloat(binding.btnShare.alpha, 1f).apply {
addUpdateListener {
binding.btnShare.alpha = it.animatedValue as Float
binding.btnSave.alpha = it.animatedValue as Float
}
}
playTogether(radiusAnimator, saveAnimator)
duration = shortAnimationDuration
interpolator = DecelerateInterpolator()
start()
}
}
window?.let { window ->
window.navigationBarColor = Color.TRANSPARENT
window.decorView.fitsSystemWindows = true
window.decorView.systemUiVisibility = window.decorView.systemUiVisibility
.rem(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
window.decorView.systemUiVisibility = window.decorView.systemUiVisibility
.rem(View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR)
}
}
}
override fun cancel() {
super.cancel()
thumbView.alpha = 1f
}
override fun dismiss() {
super.dismiss()
thumbView.alpha = 1f
}
private fun animateBack() {
val rect2 = Rect()
thumbView.getGlobalVisibleRect(rect2)
binding.mangaCoverFull.isClickable = false
binding.touchOutside.isClickable = false
val expandedImageView = binding.mangaCoverFull
val topInset = activity?.window?.decorView?.rootWindowInsets?.systemWindowInsetTop ?: 0
val leftInset = activity?.window?.decorView?.rootWindowInsets?.systemWindowInsetLeft ?: 0
val rightInset = activity?.window?.decorView?.rootWindowInsets?.systemWindowInsetRight ?: 0
expandedImageView.updateLayoutParams<ConstraintLayout.LayoutParams> {
height = thumbView.height
width = thumbView.width
topMargin = rect2.top - topInset
leftMargin = rect2.left - leftInset
rightMargin = rect2.right - rightInset
bottomMargin = rect2.bottom
horizontalBias = 0.0f
verticalBias = 0.0f
}
// Zoom out back to tc thumbnail
val transitionSet2 = TransitionSet()
val bound2 = ChangeBounds()
transitionSet2.addTransition(bound2)
val changeImageTransform2 = ChangeImageTransform()
transitionSet2.addTransition(changeImageTransform2)
transitionSet2.duration = shortAnimationDuration
TransitionManager.beginDelayedTransition(binding.root, transitionSet2)
if (Build.VERSION.SDK_INT >= 31) {
activity?.window?.decorView?.animateBlur(20f, 0.1f, 50, true)?.apply {
startDelay = shortAnimationDuration - 100
}?.start()
}
val attrs = window?.attributes
val ogDim = attrs?.dimAmount ?: 0.25f
// AnimationSet for backdrop because idk how to use TransitionSet
AnimatorSet().apply {
val radiusAnimator = ValueAnimator.ofFloat(fullRatio, ratio).apply {
addUpdateListener {
val value = it.animatedValue as Float
expandedImageView.shapeAppearanceModel =
expandedImageView.shapeAppearanceModel.toBuilder()
.setAllCorners(CornerFamily.ROUNDED, value)
.build()
}
}
val dimAnimator = ValueAnimator.ofFloat(ogDim, 0f).apply {
addUpdateListener {
window?.setDimAmount(it.animatedValue as Float)
}
}
val saveAnimator = ValueAnimator.ofFloat(binding.btnShare.alpha, 0f).apply {
addUpdateListener {
binding.btnShare.alpha = it.animatedValue as Float
binding.btnSave.alpha = it.animatedValue as Float
}
}
playTogether(radiusAnimator, dimAnimator, saveAnimator)
addListener(
onEnd = {
TransitionManager.endTransitions(binding.root)
thumbView.alpha = 1f
expandedImageView.post {
dismiss()
}
},
onCancel = {
TransitionManager.endTransitions(binding.root)
thumbView.alpha = 1f
expandedImageView.post {
dismiss()
}
}
)
interpolator = DecelerateInterpolator()
duration = shortAnimationDuration
}.start()
}
override fun onBackPressed() {
if (binding.mangaCoverFull.isClickable) {
animateBack()
}
}
}

View File

@ -1,9 +1,5 @@
package eu.kanade.tachiyomi.ui.manga package eu.kanade.tachiyomi.ui.manga
import android.animation.Animator
import android.animation.AnimatorListenerAdapter
import android.animation.AnimatorSet
import android.animation.ObjectAnimator
import android.animation.ValueAnimator import android.animation.ValueAnimator
import android.app.Activity import android.app.Activity
import android.content.ClipData import android.content.ClipData
@ -12,9 +8,6 @@ import android.content.Context
import android.content.Intent import android.content.Intent
import android.content.res.Configuration import android.content.res.Configuration
import android.graphics.Color import android.graphics.Color
import android.graphics.Rect
import android.graphics.RenderEffect
import android.graphics.Shader
import android.graphics.drawable.BitmapDrawable import android.graphics.drawable.BitmapDrawable
import android.os.Build import android.os.Build
import android.os.Bundle import android.os.Bundle
@ -25,7 +18,6 @@ import android.view.MenuItem
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.view.WindowInsets import android.view.WindowInsets
import android.view.animation.DecelerateInterpolator
import android.view.inputmethod.InputMethodManager import android.view.inputmethod.InputMethodManager
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.view.ActionMode import androidx.appcompat.view.ActionMode
@ -37,10 +29,6 @@ import androidx.palette.graphics.Palette
import androidx.recyclerview.widget.ItemTouchHelper import androidx.recyclerview.widget.ItemTouchHelper
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import androidx.transition.ChangeBounds
import androidx.transition.ChangeImageTransform
import androidx.transition.TransitionManager
import androidx.transition.TransitionSet
import coil.Coil import coil.Coil
import coil.imageLoader import coil.imageLoader
import coil.request.ImageRequest import coil.request.ImageRequest
@ -92,11 +80,9 @@ import eu.kanade.tachiyomi.util.isLocal
import eu.kanade.tachiyomi.util.moveCategories import eu.kanade.tachiyomi.util.moveCategories
import eu.kanade.tachiyomi.util.storage.getUriCompat import eu.kanade.tachiyomi.util.storage.getUriCompat
import eu.kanade.tachiyomi.util.system.ThemeUtil import eu.kanade.tachiyomi.util.system.ThemeUtil
import eu.kanade.tachiyomi.util.system.contextCompatDrawable
import eu.kanade.tachiyomi.util.system.dpToPx import eu.kanade.tachiyomi.util.system.dpToPx
import eu.kanade.tachiyomi.util.system.getPrefTheme import eu.kanade.tachiyomi.util.system.getPrefTheme
import eu.kanade.tachiyomi.util.system.getResourceColor import eu.kanade.tachiyomi.util.system.getResourceColor
import eu.kanade.tachiyomi.util.system.isInNightMode
import eu.kanade.tachiyomi.util.system.isOnline import eu.kanade.tachiyomi.util.system.isOnline
import eu.kanade.tachiyomi.util.system.isTablet import eu.kanade.tachiyomi.util.system.isTablet
import eu.kanade.tachiyomi.util.system.launchUI import eu.kanade.tachiyomi.util.system.launchUI
@ -187,9 +173,6 @@ class MangaDetailsController :
private var actionMode: ActionMode? = null private var actionMode: ActionMode? = null
// Hold a reference to the current animator, so that it can be canceled mid-way.
private var currentAnimator: Animator? = null
var headerHeight = 0 var headerHeight = 0
var fullCoverActive = false var fullCoverActive = false
@ -516,14 +499,6 @@ class MangaDetailsController :
activityBinding?.root?.clearFocus() activityBinding?.root?.clearFocus()
} }
} }
override fun handleBack(): Boolean {
if (binding.mangaCoverFull.visibility == View.VISIBLE) {
binding.mangaCoverFull.performClick()
return true
}
return super.handleBack()
}
//endregion //endregion
fun isNotOnline(showSnackbar: Boolean = true): Boolean { fun isNotOnline(showSnackbar: Boolean = true): Boolean {
@ -822,15 +797,6 @@ class MangaDetailsController :
//region action bar menu methods //region action bar menu methods
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) { override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
if (fullCoverActive) {
colorToolbar(isColor = false)
activityBinding?.toolbar?.navigationIcon =
view?.context?.contextCompatDrawable(R.drawable.ic_arrow_back_24dp)?.apply {
setTint(Color.WHITE)
}
inflater.inflate(R.menu.manga_details_cover, menu)
return
}
colorToolbar(binding.recycler.canScrollVertically(-1)) colorToolbar(binding.recycler.canScrollVertically(-1))
activityBinding?.toolbar?.navigationIcon = activityBinding?.toolbar?.navigationIcon =
activityBinding?.toolbar?.navigationIcon?.mutate()?.apply { activityBinding?.toolbar?.navigationIcon?.mutate()?.apply {
@ -921,34 +887,36 @@ class MangaDetailsController :
R.id.download_next, R.id.download_next_5, R.id.download_custom, R.id.download_unread, R.id.download_all -> downloadChapters( R.id.download_next, R.id.download_next_5, R.id.download_custom, R.id.download_unread, R.id.download_all -> downloadChapters(
item.itemId item.itemId
) )
R.id.save -> {
if (presenter.saveCover()) {
activity?.toast(R.string.cover_saved)
} else {
activity?.toast(R.string.error_saving_cover)
}
}
R.id.share -> {
val cover = presenter.shareCover()
if (cover != null) {
val stream = cover.getUriCompat(activity!!)
val intent = Intent(Intent.ACTION_SEND).apply {
putExtra(Intent.EXTRA_STREAM, stream)
flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_GRANT_READ_URI_PERMISSION
clipData = ClipData.newRawUri(null, stream)
type = "image/*"
}
startActivity(Intent.createChooser(intent, activity?.getString(R.string.share)))
} else {
activity?.toast(R.string.error_sharing_cover)
}
}
else -> return super.onOptionsItemSelected(item) else -> return super.onOptionsItemSelected(item)
} }
return true return true
} }
//endregion //endregion
fun saveCover() {
if (presenter.saveCover()) {
activity?.toast(R.string.cover_saved)
} else {
activity?.toast(R.string.error_saving_cover)
}
}
fun shareCover() {
val cover = presenter.shareCover()
if (cover != null) {
val stream = cover.getUriCompat(activity!!)
val intent = Intent(Intent.ACTION_SEND).apply {
putExtra(Intent.EXTRA_STREAM, stream)
flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_GRANT_READ_URI_PERMISSION
clipData = ClipData.newRawUri(null, stream)
type = "image/*"
}
startActivity(Intent.createChooser(intent, activity?.getString(R.string.share)))
} else {
activity?.toast(R.string.error_sharing_cover)
}
}
override fun prepareToShareManga() { override fun prepareToShareManga() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
val request = ImageRequest.Builder(activity!!).data(manga).target( val request = ImageRequest.Builder(activity!!).data(manga).target(
@ -1410,185 +1378,22 @@ class MangaDetailsController :
} }
override fun zoomImageFromThumb(thumbView: View) { override fun zoomImageFromThumb(thumbView: View) {
// If there's an animation in progress, cancel it immediately and proceed with this one. if (fullCoverActive) return
currentAnimator?.cancel()
// Load the high-resolution "zoomed-in" image.
val expandedImageView = binding.mangaCoverFull
val fullBackdrop = binding.fullBackdrop
// Hide the thumbnail and show the zoomed-in view. When the animation
// begins, it will position the zoomed-in view in the place of the
// thumbnail.
thumbView.alpha = 0f
expandedImageView.visibility = View.VISIBLE
fullBackdrop.visibility = View.VISIBLE
// Set the pivot point to 0 to match thumbnail
binding.swipeRefresh.isEnabled = false
val rect = Rect()
thumbView.getGlobalVisibleRect(rect)
expandedImageView.updateLayoutParams<ViewGroup.MarginLayoutParams> {
height = thumbView.height
width = thumbView.width
topMargin = rect.top
leftMargin = rect.left
rightMargin = rect.right
bottomMargin = rect.bottom
}
expandedImageView.requestLayout()
val activity = activity as? MainActivity ?: return
val currColor = activity.drawerArrow?.color
if (!activity.isInNightMode()) {
activityBinding?.appBar?.context?.setTheme(R.style.ThemeOverlay_AppCompat_Dark_ActionBar)
val iconPrimary = Color.WHITE
activityBinding?.toolbar?.setTitleTextColor(iconPrimary)
activity.drawerArrow?.color = iconPrimary
activityBinding?.toolbar?.overflowIcon?.setTint(iconPrimary)
activity.window.decorView.systemUiVisibility =
activity.window.decorView.systemUiVisibility.rem(
View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR
)
}
fullCoverActive = true fullCoverActive = true
activity.invalidateOptionsMenu() val expandedImageView = binding.mangaCoverFull
val fullCoverDialog = FullCoverDialog(
expandedImageView.post { this,
val defMargin = 16.dpToPx expandedImageView.drawable,
expandedImageView.updateLayoutParams<ViewGroup.MarginLayoutParams> { thumbView
height = ViewGroup.LayoutParams.MATCH_PARENT )
width = ViewGroup.LayoutParams.MATCH_PARENT fullCoverDialog.setOnDismissListener {
topMargin = defMargin + headerHeight fullCoverActive = false
leftMargin = defMargin
rightMargin = defMargin
bottomMargin = defMargin + binding.recycler.paddingBottom
}
val shortAnimationDuration = (
resources?.getInteger(
android.R.integer.config_shortAnimTime
) ?: 0
).toLong()
// TransitionSet for the full cover because using animation for this SUCKS
val transitionSet = TransitionSet()
val bound = ChangeBounds()
transitionSet.addTransition(bound)
val changeImageTransform = ChangeImageTransform()
transitionSet.addTransition(changeImageTransform)
transitionSet.duration = shortAnimationDuration
TransitionManager.beginDelayedTransition(binding.frameLayout, transitionSet)
// AnimationSet for backdrop because idk how to use TransitionSet
currentAnimator = AnimatorSet().apply {
play(
ObjectAnimator.ofFloat(fullBackdrop, View.ALPHA, 0f, 0.5f)
)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
binding.swipeRefresh.setRenderEffect(
RenderEffect.createBlurEffect(
15f,
15f,
Shader.TileMode.MIRROR
)
)
}
duration = shortAnimationDuration
interpolator = DecelerateInterpolator()
addListener(
object : AnimatorListenerAdapter() {
override fun onAnimationEnd(animation: Animator) {
TransitionManager.endTransitions(binding.frameLayout)
currentAnimator = null
}
override fun onAnimationCancel(animation: Animator) {
TransitionManager.endTransitions(binding.frameLayout)
currentAnimator = null
}
}
)
start()
}
expandedImageView.setOnClickListener {
currentAnimator?.cancel()
fullCoverActive = false
activity.invalidateOptionsMenu()
val rect2 = Rect()
thumbView.getGlobalVisibleRect(rect2)
expandedImageView.updateLayoutParams<ViewGroup.MarginLayoutParams> {
height = thumbView.height
width = thumbView.width
topMargin = rect2.top
leftMargin = rect2.left
rightMargin = rect2.right
bottomMargin = rect2.bottom
}
// Zoom out back to tc thumbnail
val transitionSet2 = TransitionSet()
val bound2 = ChangeBounds()
transitionSet2.addTransition(bound2)
val changeImageTransform2 = ChangeImageTransform()
transitionSet2.addTransition(changeImageTransform2)
transitionSet2.duration = shortAnimationDuration
TransitionManager.beginDelayedTransition(binding.frameLayout, transitionSet2)
// Animation to remove backdrop and hide the full cover
currentAnimator = AnimatorSet().apply {
play(ObjectAnimator.ofFloat(fullBackdrop, View.ALPHA, 0f))
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
binding.swipeRefresh.setRenderEffect(null)
}
duration = shortAnimationDuration
interpolator = DecelerateInterpolator()
if (!activity.isInNightMode()) {
activityBinding?.appBar?.context?.setTheme(
activity.getPrefTheme(presenter.preferences).styleRes
)
val iconPrimary = currColor ?: Color.WHITE
activityBinding?.toolbar?.setTitleTextColor(iconPrimary)
activity.drawerArrow?.color = iconPrimary
activityBinding?.toolbar?.overflowIcon?.setTint(iconPrimary)
activity.window.decorView.systemUiVisibility =
activity.window.decorView.systemUiVisibility.or(
View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR
)
}
addListener(
object : AnimatorListenerAdapter() {
override fun onAnimationEnd(animation: Animator) {
thumbView.alpha = 1f
expandedImageView.visibility = View.GONE
fullBackdrop.visibility = View.GONE
binding.swipeRefresh.isEnabled = true
currentAnimator = null
}
override fun onAnimationCancel(animation: Animator) {
thumbView.alpha = 1f
expandedImageView.visibility = View.GONE
fullBackdrop.visibility = View.GONE
binding.swipeRefresh.isEnabled = true
currentAnimator = null
}
}
)
start()
}
}
} }
fullCoverDialog.setOnCancelListener {
fullCoverActive = false
}
fullCoverDialog.show()
return
} }
companion object { companion object {

View File

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

View File

@ -0,0 +1,69 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:tools="http://schemas.android.com/tools"
android:background="@android:color/transparent"
tools:background="@color/gray_button"
xmlns:app="http://schemas.android.com/apk/res-auto">
<View
android:id="@+id/touch_outside"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:layout_width="0dp"
android:layout_height="0dp"/>
<com.google.android.material.imageview.ShapeableImageView
android:id="@+id/manga_cover_full"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:scaleType="fitCenter"
android:adjustViewBounds="true"
tools:src="@mipmap/ic_launcher"
android:contentDescription="@string/cover_of_image"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="16dp"
android:layout_marginBottom="16dp"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintVertical_bias="0.0"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toTopOf="@id/button_container" />
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/button_container"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintVertical_bias="1.0"
app:layout_constraintStart_toStartOf="parent"
android:layout_marginBottom="4dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="parent">
<com.google.android.material.button.MaterialButton
android:id="@+id/btn_save"
style="@style/Widget.Tachiyomi.Button.ActionButton.White"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@id/btn_share"
app:layout_constraintStart_toStartOf="parent"
android:text="@string/save"
app:icon="@drawable/ic_save_24dp" />
<com.google.android.material.button.MaterialButton
android:id="@+id/btn_share"
style="@style/Widget.Tachiyomi.Button.ActionButton.White"
app:layout_constraintStart_toEndOf="@id/btn_save"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:text="@string/share"
app:icon="@drawable/ic_share_24dp" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -73,17 +73,6 @@
android:layout_height="match_parent" android:layout_height="match_parent"
app:fastScrollerBubbleEnabled="true" /> app:fastScrollerBubbleEnabled="true" />
<View
android:id="@+id/full_backdrop"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:alpha="0"
android:clickable="true"
android:focusable="true"
android:foreground="@color/md_black_1000"
android:visibility="invisible"
tools:background="@color/md_black_1000" />
<ImageView <ImageView
android:id="@+id/manga_cover_full" android:id="@+id/manga_cover_full"
android:layout_width="match_parent" android:layout_width="match_parent"

View File

@ -1,18 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/save"
android:icon="@drawable/ic_save_24dp"
android:title="@string/save"
app:iconTint="@android:color/white"
app:showAsAction="ifRoom" />
<item
android:id="@+id/share"
android:icon="@drawable/ic_share_24dp"
android:title="@string/share"
app:iconTint="@android:color/white"
app:showAsAction="ifRoom" />
</menu>

View File

@ -197,6 +197,16 @@
<item name="android:windowExitAnimation">@anim/fade_out_short</item> <item name="android:windowExitAnimation">@anim/fade_out_short</item>
</style> </style>
<style name="FullCoverDialogTheme" parent="BottomSheetDialogTheme">
<item name="android:windowAnimationStyle">@style/Theme.Widget.Animation.Static</item>
</style>
<style name="Theme.Widget.Animation.Static" parent="android:Animation">
<item name="android:windowEnterAnimation">@null</item>
<item name="android:windowExitAnimation">@null</item>
<item name="android:exitFadeDuration">0</item>
</style>
<style name="Theme.Widget.TextInputLayout.OutlinedBox.Dense" parent="Widget.MaterialComponents.TextInputLayout.OutlinedBox.Dense"> <style name="Theme.Widget.TextInputLayout.OutlinedBox.Dense" parent="Widget.MaterialComponents.TextInputLayout.OutlinedBox.Dense">
<item name="boxStrokeColor">@color/text_input_stroke</item> <item name="boxStrokeColor">@color/text_input_stroke</item>
<item name="hintTextColor">?colorAccent</item> <item name="hintTextColor">?colorAccent</item>
@ -235,6 +245,20 @@
<!--==============--> <!--==============-->
<!--Widgets.Button--> <!--Widgets.Button-->
<!--==============--> <!--==============-->
<style name="Widget.Tachiyomi.Button.ActionButton" parent="Widget.MaterialComponents.Button.TextButton.Icon">
<item name="iconGravity">top</item>
<item name="iconTint">@color/button_action_selector</item>
<item name="iconPadding">4dp</item>
<item name="android:textAllCaps">false</item>
<item name="android:textColor">@color/button_action_selector</item>
<item name="android:textSize">12sp</item>
</style>
<style name="Widget.Tachiyomi.Button.ActionButton.White">
<item name="iconTint">@color/md_white_1000</item>
<item name="android:textColor">@color/md_white_1000</item>
</style>
<style name="Theme.Widget.Button" parent="Widget.AppCompat.Button" /> <style name="Theme.Widget.Button" parent="Widget.AppCompat.Button" />
<style name="Theme.Widget.Button.Colored" parent="Widget.MaterialComponents.Button"> <style name="Theme.Widget.Button.Colored" parent="Widget.MaterialComponents.Button">