diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryController.kt index 5661defaa..009a940fd 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryController.kt @@ -33,7 +33,6 @@ import eu.kanade.tachiyomi.ui.base.controller.TabbedController import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction import eu.kanade.tachiyomi.ui.browse.source.globalsearch.GlobalSearchController import eu.kanade.tachiyomi.ui.main.MainActivity -import eu.kanade.tachiyomi.ui.main.offsetAppbarHeight import eu.kanade.tachiyomi.ui.manga.MangaController import eu.kanade.tachiyomi.util.system.getResourceColor import eu.kanade.tachiyomi.util.system.toast @@ -201,7 +200,7 @@ class LibraryController( } .launchIn(scope) - binding.actionToolbar.offsetAppbarHeight(activity!!) + (activity!! as MainActivity).fixViewToBottom(binding.actionToolbar) } override fun onChangeStarted(handler: ControllerChangeHandler, type: ControllerChangeType) { diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/main/MainActivity.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/main/MainActivity.kt index 6947da2c8..94d490f8b 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/main/MainActivity.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/main/MainActivity.kt @@ -1,6 +1,5 @@ package eu.kanade.tachiyomi.ui.main -import android.app.Activity import android.app.SearchManager import android.content.Intent import android.os.Build @@ -21,7 +20,6 @@ import com.bluelinelabs.conductor.Router import com.bluelinelabs.conductor.RouterTransaction import com.google.android.material.appbar.AppBarLayout import com.google.android.material.behavior.HideBottomViewOnScrollBehavior -import com.google.android.material.tabs.TabLayout import eu.kanade.tachiyomi.BuildConfig import eu.kanade.tachiyomi.Migrations import eu.kanade.tachiyomi.R @@ -48,8 +46,6 @@ import eu.kanade.tachiyomi.ui.recent.updates.UpdatesController import eu.kanade.tachiyomi.util.lang.launchIO import eu.kanade.tachiyomi.util.lang.launchUI import eu.kanade.tachiyomi.util.view.applyInsets -import kotlinx.android.synthetic.main.main_activity.appbar -import kotlinx.android.synthetic.main.main_activity.tabs import kotlinx.coroutines.delay import kotlinx.coroutines.flow.launchIn import timber.log.Timber @@ -418,6 +414,19 @@ class MainActivity : BaseActivity() { } } + /** + * Used to manually offset a view within the activity's child views that might be cut off due to the + * collapsing AppBarLayout. + */ + fun fixViewToBottom(view: View) { + binding.appbar.addOnOffsetChangedListener( + AppBarLayout.OnOffsetChangedListener { appBarLayout, verticalOffset -> + val maxAbsOffset = appBarLayout.measuredHeight - binding.tabs.measuredHeight + view.translationY = -maxAbsOffset - verticalOffset.toFloat() + } + ) + } + private fun setBottomNavBehaviorOnScroll() { showBottomNav(visible = true) @@ -444,18 +453,3 @@ class MainActivity : BaseActivity() { const val INTENT_SEARCH_FILTER = "filter" } } - -/** - * Used to manually offset a view within the activity's child views that might be cut off due to the - * collapsing AppBarLayout. - */ -fun View.offsetAppbarHeight(activity: Activity) { - val appbar: AppBarLayout = activity.appbar - val tabs: TabLayout = activity.tabs - appbar.addOnOffsetChangedListener( - AppBarLayout.OnOffsetChangedListener { appBarLayout, verticalOffset -> - val maxAbsOffset = appBarLayout.measuredHeight - tabs.measuredHeight - translationY = -maxAbsOffset - verticalOffset.toFloat() - } - ) -} diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaController.kt index abc440688..146052350 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaController.kt @@ -54,7 +54,6 @@ import eu.kanade.tachiyomi.ui.library.ChangeMangaCategoriesDialog import eu.kanade.tachiyomi.ui.library.ChangeMangaCoverDialog import eu.kanade.tachiyomi.ui.library.LibraryController import eu.kanade.tachiyomi.ui.main.MainActivity -import eu.kanade.tachiyomi.ui.main.offsetAppbarHeight import eu.kanade.tachiyomi.ui.manga.chapter.ChapterItem import eu.kanade.tachiyomi.ui.manga.chapter.ChaptersAdapter import eu.kanade.tachiyomi.ui.manga.chapter.ChaptersSettingsSheet @@ -239,7 +238,7 @@ class MangaController : } .launchIn(scope) - binding.actionToolbar.offsetAppbarHeight(activity!!) + (activity!! as MainActivity).fixViewToBottom(binding.actionToolbar) settingsSheet = ChaptersSettingsSheet(router, presenter) { group -> if (group is ChaptersSettingsSheet.Filter.FilterGroup) { diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/ReaderTransitionView.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/ReaderTransitionView.kt index 453352b20..5b3090c3a 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/ReaderTransitionView.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/viewer/ReaderTransitionView.kt @@ -2,22 +2,22 @@ package eu.kanade.tachiyomi.ui.reader.viewer import android.content.Context import android.util.AttributeSet +import android.view.LayoutInflater import android.widget.LinearLayout import androidx.core.text.bold import androidx.core.text.buildSpannedString import androidx.core.view.isVisible import eu.kanade.tachiyomi.R +import eu.kanade.tachiyomi.databinding.ReaderTransitionViewBinding import eu.kanade.tachiyomi.ui.reader.model.ChapterTransition -import kotlinx.android.synthetic.main.reader_transition_view.view.lower_text -import kotlinx.android.synthetic.main.reader_transition_view.view.upper_text -import kotlinx.android.synthetic.main.reader_transition_view.view.warning -import kotlinx.android.synthetic.main.reader_transition_view.view.warning_text class ReaderTransitionView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) : LinearLayout(context, attrs) { + private val binding: ReaderTransitionViewBinding + init { - inflate(context, R.layout.reader_transition_view, this) + binding = ReaderTransitionViewBinding.inflate(LayoutInflater.from(context), this, true) layoutParams = LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT) } @@ -37,20 +37,20 @@ class ReaderTransitionView @JvmOverloads constructor(context: Context, attrs: At val prevChapter = transition.to val hasPrevChapter = prevChapter != null - lower_text.isVisible = hasPrevChapter + binding.lowerText.isVisible = hasPrevChapter if (hasPrevChapter) { - upper_text.textAlignment = TEXT_ALIGNMENT_TEXT_START - upper_text.text = buildSpannedString { + binding.upperText.textAlignment = TEXT_ALIGNMENT_TEXT_START + binding.upperText.text = buildSpannedString { bold { append(context.getString(R.string.transition_current)) } append("\n${transition.from.chapter.name}") } - lower_text.text = buildSpannedString { + binding.lowerText.text = buildSpannedString { bold { append(context.getString(R.string.transition_previous)) } append("\n${prevChapter!!.chapter.name}") } } else { - upper_text.textAlignment = TEXT_ALIGNMENT_CENTER - upper_text.text = context.getString(R.string.transition_no_previous) + binding.upperText.textAlignment = TEXT_ALIGNMENT_CENTER + binding.upperText.text = context.getString(R.string.transition_no_previous) } } @@ -61,26 +61,26 @@ class ReaderTransitionView @JvmOverloads constructor(context: Context, attrs: At val nextChapter = transition.to val hasNextChapter = nextChapter != null - lower_text.isVisible = hasNextChapter + binding.lowerText.isVisible = hasNextChapter if (hasNextChapter) { - upper_text.textAlignment = TEXT_ALIGNMENT_TEXT_START - upper_text.text = buildSpannedString { + binding.upperText.textAlignment = TEXT_ALIGNMENT_TEXT_START + binding.upperText.text = buildSpannedString { bold { append(context.getString(R.string.transition_finished)) } append("\n${transition.from.chapter.name}") } - lower_text.text = buildSpannedString { + binding.lowerText.text = buildSpannedString { bold { append(context.getString(R.string.transition_next)) } append("\n${nextChapter!!.chapter.name}") } } else { - upper_text.textAlignment = TEXT_ALIGNMENT_CENTER - upper_text.text = context.getString(R.string.transition_no_next) + binding.upperText.textAlignment = TEXT_ALIGNMENT_CENTER + binding.upperText.text = context.getString(R.string.transition_no_next) } } private fun missingChapterWarning(transition: ChapterTransition) { if (transition.to == null) { - warning.isVisible = false + binding.warning.isVisible = false return } @@ -90,7 +90,7 @@ class ReaderTransitionView @JvmOverloads constructor(context: Context, attrs: At } if (!hasMissingChapters) { - warning.isVisible = false + binding.warning.isVisible = false return } @@ -99,7 +99,7 @@ class ReaderTransitionView @JvmOverloads constructor(context: Context, attrs: At is ChapterTransition.Next -> calculateChapterDifference(transition.to, transition.from) } - warning_text.text = resources.getQuantityString(R.plurals.missing_chapters_warning, chapterDifference.toInt(), chapterDifference.toInt()) - warning.isVisible = true + binding.warningText.text = resources.getQuantityString(R.plurals.missing_chapters_warning, chapterDifference.toInt(), chapterDifference.toInt()) + binding.warning.isVisible = true } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/recent/updates/UpdatesController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/recent/updates/UpdatesController.kt index 196686544..37cffbc79 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/recent/updates/UpdatesController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/recent/updates/UpdatesController.kt @@ -23,7 +23,6 @@ import eu.kanade.tachiyomi.ui.base.controller.RootController import eu.kanade.tachiyomi.ui.base.controller.applyBottomInsetPadding import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction import eu.kanade.tachiyomi.ui.main.MainActivity -import eu.kanade.tachiyomi.ui.main.offsetAppbarHeight import eu.kanade.tachiyomi.ui.manga.MangaController import eu.kanade.tachiyomi.ui.reader.ReaderActivity import eu.kanade.tachiyomi.util.system.notificationManager @@ -109,7 +108,7 @@ class UpdatesController : } .launchIn(scope) - binding.actionToolbar.offsetAppbarHeight(activity!!) + (activity!! as MainActivity).fixViewToBottom(binding.actionToolbar) } override fun onDestroyView(view: View) { diff --git a/app/src/main/java/eu/kanade/tachiyomi/widget/ActionToolbar.kt b/app/src/main/java/eu/kanade/tachiyomi/widget/ActionToolbar.kt index 4b825cfd8..b00ed4ed3 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/widget/ActionToolbar.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/widget/ActionToolbar.kt @@ -2,6 +2,7 @@ package eu.kanade.tachiyomi.widget import android.content.Context import android.util.AttributeSet +import android.view.LayoutInflater import android.view.MenuItem import android.view.animation.Animation import android.view.animation.AnimationUtils @@ -11,8 +12,7 @@ import androidx.annotation.MenuRes import androidx.appcompat.view.ActionMode import androidx.core.view.isVisible import eu.kanade.tachiyomi.R -import kotlinx.android.synthetic.main.common_action_toolbar.view.common_action_menu -import kotlinx.android.synthetic.main.common_action_toolbar.view.common_action_toolbar +import eu.kanade.tachiyomi.databinding.CommonActionToolbarBinding /** * A toolbar holding only menu items. @@ -20,23 +20,25 @@ import kotlinx.android.synthetic.main.common_action_toolbar.view.common_action_t class ActionToolbar @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) : FrameLayout(context, attrs) { + private val binding: CommonActionToolbarBinding + init { - inflate(context, R.layout.common_action_toolbar, this) + binding = CommonActionToolbarBinding.inflate(LayoutInflater.from(context), this, true) } /** * Remove menu items and remove listener. */ fun destroy() { - common_action_menu.menu.clear() - common_action_menu.setOnMenuItemClickListener(null) + binding.commonActionMenu.menu.clear() + binding.commonActionMenu.setOnMenuItemClickListener(null) } /** * Gets a menu item if found. */ fun findItem(@IdRes itemId: Int): MenuItem? { - return common_action_menu.menu.findItem(itemId) + return binding.commonActionMenu.menu.findItem(itemId) } /** @@ -44,14 +46,14 @@ class ActionToolbar @JvmOverloads constructor(context: Context, attrs: Attribute */ fun show(mode: ActionMode, @MenuRes menuRes: Int, listener: (item: MenuItem?) -> Boolean) { // Avoid re-inflating the menu - if (common_action_menu.menu.size() == 0) { - mode.menuInflater.inflate(menuRes, common_action_menu.menu) - common_action_menu.setOnMenuItemClickListener { listener(it) } + if (binding.commonActionMenu.menu.size() == 0) { + mode.menuInflater.inflate(menuRes, binding.commonActionMenu.menu) + binding.commonActionMenu.setOnMenuItemClickListener { listener(it) } } - common_action_toolbar.isVisible = true + binding.commonActionToolbar.isVisible = true val bottomAnimation = AnimationUtils.loadAnimation(context, R.anim.enter_from_bottom) - common_action_toolbar.startAnimation(bottomAnimation) + binding.commonActionToolbar.startAnimation(bottomAnimation) } /** @@ -62,10 +64,10 @@ class ActionToolbar @JvmOverloads constructor(context: Context, attrs: Attribute bottomAnimation.setAnimationListener( object : SimpleAnimationListener() { override fun onAnimationEnd(animation: Animation) { - common_action_toolbar.isVisible = false + binding.commonActionToolbar.isVisible = false } } ) - common_action_toolbar.startAnimation(bottomAnimation) + binding.commonActionToolbar.startAnimation(bottomAnimation) } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/widget/DialogCheckboxView.kt b/app/src/main/java/eu/kanade/tachiyomi/widget/DialogCheckboxView.kt index 4d5fd2569..ae8d2b203 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/widget/DialogCheckboxView.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/widget/DialogCheckboxView.kt @@ -2,29 +2,30 @@ package eu.kanade.tachiyomi.widget import android.content.Context import android.util.AttributeSet +import android.view.LayoutInflater import android.widget.LinearLayout import androidx.annotation.StringRes -import eu.kanade.tachiyomi.R -import eu.kanade.tachiyomi.util.view.inflate -import kotlinx.android.synthetic.main.common_dialog_with_checkbox.view.checkbox_option -import kotlinx.android.synthetic.main.common_dialog_with_checkbox.view.description +import eu.kanade.tachiyomi.databinding.CommonDialogWithCheckboxBinding class DialogCheckboxView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) : LinearLayout(context, attrs) { + private val binding: CommonDialogWithCheckboxBinding + init { - addView(inflate(R.layout.common_dialog_with_checkbox)) + binding = CommonDialogWithCheckboxBinding.inflate(LayoutInflater.from(context), this, false) + addView(binding.root) } fun setDescription(@StringRes id: Int) { - description.text = context.getString(id) + binding.description.text = context.getString(id) } fun setOptionDescription(@StringRes id: Int) { - checkbox_option.text = context.getString(id) + binding.checkboxOption.text = context.getString(id) } fun isChecked(): Boolean { - return checkbox_option.isChecked + return binding.checkboxOption.isChecked } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/widget/DialogCustomDownloadView.kt b/app/src/main/java/eu/kanade/tachiyomi/widget/DialogCustomDownloadView.kt index 60af36113..f0bd354c9 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/widget/DialogCustomDownloadView.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/widget/DialogCustomDownloadView.kt @@ -3,15 +3,10 @@ package eu.kanade.tachiyomi.widget import android.content.Context import android.text.SpannableStringBuilder import android.util.AttributeSet +import android.view.LayoutInflater import android.view.View import android.widget.LinearLayout -import eu.kanade.tachiyomi.R -import eu.kanade.tachiyomi.util.view.inflate -import kotlinx.android.synthetic.main.download_custom_amount.view.btn_decrease -import kotlinx.android.synthetic.main.download_custom_amount.view.btn_decrease_10 -import kotlinx.android.synthetic.main.download_custom_amount.view.btn_increase -import kotlinx.android.synthetic.main.download_custom_amount.view.btn_increase_10 -import kotlinx.android.synthetic.main.download_custom_amount.view.myNumber +import eu.kanade.tachiyomi.databinding.DownloadCustomAmountBinding import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Job @@ -26,8 +21,6 @@ import timber.log.Timber class DialogCustomDownloadView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) : LinearLayout(context, attrs) { - private val scope = CoroutineScope(Job() + Dispatchers.Main) - /** * Current amount of custom download chooser. */ @@ -44,44 +37,43 @@ class DialogCustomDownloadView @JvmOverloads constructor(context: Context, attrs */ private var max = 0 + private val scope = CoroutineScope(Job() + Dispatchers.Main) + + private val binding: DownloadCustomAmountBinding + init { - // Add view to stack - addView(inflate(R.layout.download_custom_amount)) + binding = DownloadCustomAmountBinding.inflate(LayoutInflater.from(context), this, false) + addView(binding.root) } - /** - * Called when view is added - * - * @param child - */ override fun onViewAdded(child: View) { super.onViewAdded(child) // Set download count to 0. - myNumber.text = SpannableStringBuilder(getAmount(0).toString()) + binding.myNumber.text = SpannableStringBuilder(getAmount(0).toString()) // When user presses button decrease amount by 10. - btn_decrease_10.setOnClickListener { - myNumber.text = SpannableStringBuilder(getAmount(amount - 10).toString()) + binding.btnDecrease10.setOnClickListener { + binding.myNumber.text = SpannableStringBuilder(getAmount(amount - 10).toString()) } // When user presses button increase amount by 10. - btn_increase_10.setOnClickListener { - myNumber.text = SpannableStringBuilder(getAmount(amount + 10).toString()) + binding.btnIncrease10.setOnClickListener { + binding.myNumber.text = SpannableStringBuilder(getAmount(amount + 10).toString()) } // When user presses button decrease amount by 1. - btn_decrease.setOnClickListener { - myNumber.text = SpannableStringBuilder(getAmount(amount - 1).toString()) + binding.btnDecrease.setOnClickListener { + binding.myNumber.text = SpannableStringBuilder(getAmount(amount - 1).toString()) } // When user presses button increase amount by 1. - btn_increase.setOnClickListener { - myNumber.text = SpannableStringBuilder(getAmount(amount + 1).toString()) + binding.btnIncrease.setOnClickListener { + binding.myNumber.text = SpannableStringBuilder(getAmount(amount + 1).toString()) } // When user inputs custom number set amount equal to input. - myNumber.textChanges() + binding.myNumber.textChanges() .onEach { try { amount = getAmount(Integer.parseInt(it.toString())) diff --git a/app/src/main/java/eu/kanade/tachiyomi/widget/EmptyView.kt b/app/src/main/java/eu/kanade/tachiyomi/widget/EmptyView.kt index 05bb89d6c..b211f4303 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/widget/EmptyView.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/widget/EmptyView.kt @@ -2,22 +2,22 @@ package eu.kanade.tachiyomi.widget import android.content.Context import android.util.AttributeSet +import android.view.LayoutInflater import android.widget.LinearLayout import android.widget.RelativeLayout import androidx.annotation.StringRes import androidx.appcompat.widget.AppCompatButton import androidx.core.view.isVisible -import eu.kanade.tachiyomi.R -import kotlinx.android.synthetic.main.common_view_empty.view.actions_container -import kotlinx.android.synthetic.main.common_view_empty.view.text_face -import kotlinx.android.synthetic.main.common_view_empty.view.text_label +import eu.kanade.tachiyomi.databinding.CommonViewEmptyBinding import kotlin.random.Random class EmptyView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) : RelativeLayout(context, attrs) { + private val binding: CommonViewEmptyBinding + init { - inflate(context, R.layout.common_view_empty, this) + binding = CommonViewEmptyBinding.inflate(LayoutInflater.from(context), this, true) } /** @@ -36,10 +36,10 @@ class EmptyView @JvmOverloads constructor(context: Context, attrs: AttributeSet? } fun show(message: String, actions: List? = null) { - text_face.text = getRandomErrorFace() - text_label.text = message + binding.textFace.text = getRandomErrorFace() + binding.textLabel.text = message - actions_container.removeAllViews() + binding.actionsContainer.removeAllViews() if (!actions.isNullOrEmpty()) { actions.forEach { val button = AppCompatButton(context).apply { @@ -52,7 +52,7 @@ class EmptyView @JvmOverloads constructor(context: Context, attrs: AttributeSet? setOnClickListener(it.listener) } - actions_container.addView(button) + binding.actionsContainer.addView(button) } }