Improve tablet navigation

master
Koitharu 11 months ago
parent 12f1ffd019
commit d3d7912bb8
Signed by: Koitharu
GPG Key ID: 676DEE768C17A9D7

@ -0,0 +1,97 @@
package org.koitharu.kotatsu.core.ui.widgets
import android.content.Context
import android.os.Parcel
import android.os.Parcelable
import android.os.Parcelable.Creator
import android.util.AttributeSet
import android.widget.Checkable
import androidx.annotation.AttrRes
import androidx.appcompat.widget.AppCompatImageButton
import androidx.core.os.ParcelCompat
import androidx.customview.view.AbsSavedState
class CheckableImageButton @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
@AttrRes defStyleAttr: Int = 0,
) : AppCompatImageButton(context, attrs, defStyleAttr), Checkable {
private var isCheckedInternal = false
private var isBroadcasting = false
var onCheckedChangeListener: OnCheckedChangeListener? = null
override fun isChecked() = isCheckedInternal
override fun toggle() {
isChecked = !isCheckedInternal
}
override fun setChecked(checked: Boolean) {
if (checked != isCheckedInternal) {
isCheckedInternal = checked
refreshDrawableState()
if (!isBroadcasting) {
isBroadcasting = true
onCheckedChangeListener?.onCheckedChanged(this, checked)
isBroadcasting = false
}
}
}
override fun onCreateDrawableState(extraSpace: Int): IntArray {
val state = super.onCreateDrawableState(extraSpace + 1)
if (isCheckedInternal) {
mergeDrawableStates(state, intArrayOf(android.R.attr.state_checked))
}
return state
}
override fun onSaveInstanceState(): Parcelable? {
val superState = super.onSaveInstanceState() ?: return null
return SavedState(superState, isChecked)
}
override fun onRestoreInstanceState(state: Parcelable?) {
if (state is SavedState) {
super.onRestoreInstanceState(state.superState)
isChecked = state.isChecked
} else {
super.onRestoreInstanceState(state)
}
}
fun interface OnCheckedChangeListener {
fun onCheckedChanged(view: CheckableImageButton, isChecked: Boolean)
}
private class SavedState : AbsSavedState {
val isChecked: Boolean
constructor(superState: Parcelable, checked: Boolean) : super(superState) {
isChecked = checked
}
constructor(source: Parcel, classLoader: ClassLoader?) : super(source, classLoader) {
isChecked = ParcelCompat.readBoolean(source)
}
override fun writeToParcel(out: Parcel, flags: Int) {
super.writeToParcel(out, flags)
ParcelCompat.writeBoolean(out, isChecked)
}
companion object {
@Suppress("unused")
@JvmField
val CREATOR: Creator<SavedState> = object : Creator<SavedState> {
override fun createFromParcel(`in`: Parcel) = SavedState(`in`, SavedState::class.java.classLoader)
override fun newArray(size: Int): Array<SavedState?> = arrayOfNulls(size)
}
}
}
}

@ -6,8 +6,10 @@ import android.view.View
import android.view.View.MeasureSpec import android.view.View.MeasureSpec
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.Checkable import android.widget.Checkable
import androidx.annotation.StringRes
import androidx.appcompat.widget.ActionMenuView import androidx.appcompat.widget.ActionMenuView
import androidx.appcompat.widget.Toolbar import androidx.appcompat.widget.Toolbar
import androidx.appcompat.widget.TooltipCompat
import androidx.core.view.children import androidx.core.view.children
import androidx.core.view.descendants import androidx.core.view.descendants
import androidx.core.view.isVisible import androidx.core.view.isVisible
@ -192,3 +194,9 @@ fun Chip.setProgressIcon() {
chipIcon = progressDrawable chipIcon = progressDrawable
progressDrawable.start() progressDrawable.start()
} }
fun View.setContentDescriptionAndTooltip(@StringRes resId: Int) {
val text = resources.getString(resId)
contentDescription = text
TooltipCompat.setTooltipText(this, text)
}

@ -14,6 +14,7 @@ import kotlinx.coroutines.launch
import org.koitharu.kotatsu.R import org.koitharu.kotatsu.R
import org.koitharu.kotatsu.core.ui.BaseListAdapter import org.koitharu.kotatsu.core.ui.BaseListAdapter
import org.koitharu.kotatsu.core.util.ext.getQuantityStringSafe import org.koitharu.kotatsu.core.util.ext.getQuantityStringSafe
import org.koitharu.kotatsu.core.util.ext.setContentDescriptionAndTooltip
import org.koitharu.kotatsu.core.util.ext.textAndVisible import org.koitharu.kotatsu.core.util.ext.textAndVisible
import org.koitharu.kotatsu.databinding.ItemDownloadBinding import org.koitharu.kotatsu.databinding.ItemDownloadBinding
import org.koitharu.kotatsu.download.ui.list.chapters.DownloadChapter import org.koitharu.kotatsu.download.ui.list.chapters.DownloadChapter
@ -41,7 +42,7 @@ fun downloadItemAD(
R.id.button_skip -> listener.onSkipClick(item) R.id.button_skip -> listener.onSkipClick(item)
R.id.button_skip_all -> listener.onSkipAllClick(item) R.id.button_skip_all -> listener.onSkipAllClick(item)
R.id.button_pause -> listener.onPauseClick(item) R.id.button_pause -> listener.onPauseClick(item)
R.id.imageView_expand -> listener.onExpandClick(item) R.id.button_expand -> listener.onExpandClick(item)
else -> listener.onItemClick(item, v) else -> listener.onItemClick(item, v)
} }
} }
@ -59,7 +60,7 @@ fun downloadItemAD(
binding.buttonResume.setOnClickListener(clickListener) binding.buttonResume.setOnClickListener(clickListener)
binding.buttonSkip.setOnClickListener(clickListener) binding.buttonSkip.setOnClickListener(clickListener)
binding.buttonSkipAll.setOnClickListener(clickListener) binding.buttonSkipAll.setOnClickListener(clickListener)
binding.imageViewExpand.setOnClickListener(clickListener) binding.buttonExpand.setOnClickListener(clickListener)
itemView.setOnClickListener(clickListener) itemView.setOnClickListener(clickListener)
itemView.setOnLongClickListener(clickListener) itemView.setOnLongClickListener(clickListener)
@ -83,7 +84,7 @@ fun downloadItemAD(
chaptersJob?.cancel() chaptersJob?.cancel()
chaptersJob = lifecycleOwner.lifecycleScope.launch(start = CoroutineStart.UNDISPATCHED) { chaptersJob = lifecycleOwner.lifecycleScope.launch(start = CoroutineStart.UNDISPATCHED) {
item.chapters.collect { chapters -> item.chapters.collect { chapters ->
binding.imageViewExpand.isGone = chapters.isNullOrEmpty() binding.buttonExpand.isGone = chapters.isNullOrEmpty()
chaptersAdapter.emit(chapters) chaptersAdapter.emit(chapters)
scrollToCurrentChapter() scrollToCurrentChapter()
} }
@ -93,7 +94,8 @@ fun downloadItemAD(
scrollToCurrentChapter() scrollToCurrentChapter()
} }
} }
binding.imageViewExpand.isChecked = item.isExpanded binding.buttonExpand.isChecked = item.isExpanded
binding.buttonExpand.setContentDescriptionAndTooltip(if (item.isExpanded) R.string.collapse else R.string.expand)
binding.recyclerViewChapters.isVisible = item.isExpanded binding.recyclerViewChapters.isVisible = item.isExpanded
when (item.workState) { when (item.workState) {
WorkInfo.State.ENQUEUED, WorkInfo.State.ENQUEUED,

@ -120,6 +120,9 @@ class MainActivity : BaseActivity<ActivityMainBinding>(), AppBarOwner, BottomNav
) )
navigationDelegate.addOnFragmentChangedListener(this) navigationDelegate.addOnFragmentChangedListener(this)
navigationDelegate.onCreate(this, savedInstanceState) navigationDelegate.onCreate(this, savedInstanceState)
viewBinding.textViewTitle?.let { tv ->
navigationDelegate.observeTitle().observe(this) { tv.text = it }
}
addMenuProvider(MainMenuProvider(router, viewModel)) addMenuProvider(MainMenuProvider(router, viewModel))
@ -409,7 +412,7 @@ class MainActivity : BaseActivity<ActivityMainBinding>(), AppBarOwner, BottomNav
} }
} }
private fun SearchView.observeState() = callbackFlow<SearchView.TransitionState> { private fun SearchView.observeState() = callbackFlow {
val listener = SearchView.TransitionListener { _, _, state -> val listener = SearchView.TransitionListener { _, _, state ->
trySendBlocking(state) trySendBlocking(state)
} }

@ -3,6 +3,7 @@ package org.koitharu.kotatsu.main.ui
import android.os.Bundle import android.os.Bundle
import android.view.Menu import android.view.Menu
import android.view.MenuItem import android.view.MenuItem
import android.view.View
import androidx.activity.OnBackPressedCallback import androidx.activity.OnBackPressedCallback
import androidx.annotation.IdRes import androidx.annotation.IdRes
import androidx.core.view.isEmpty import androidx.core.view.isEmpty
@ -13,11 +14,16 @@ import androidx.fragment.app.FragmentManager
import androidx.lifecycle.LifecycleOwner import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
import com.google.android.material.navigation.NavigationBarView import com.google.android.material.navigation.NavigationBarView
import com.google.android.material.navigationrail.NavigationRailView
import com.google.android.material.transition.MaterialFadeThrough import com.google.android.material.transition.MaterialFadeThrough
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.channels.awaitClose
import kotlinx.coroutines.channels.trySendBlocking
import kotlinx.coroutines.flow.callbackFlow
import kotlinx.coroutines.flow.filter import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.flowOn import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.flow.onStart import kotlinx.coroutines.flow.onStart
import org.koitharu.kotatsu.R import org.koitharu.kotatsu.R
@ -26,7 +32,9 @@ import org.koitharu.kotatsu.core.prefs.AppSettings
import org.koitharu.kotatsu.core.prefs.NavItem import org.koitharu.kotatsu.core.prefs.NavItem
import org.koitharu.kotatsu.core.ui.util.RecyclerViewOwner import org.koitharu.kotatsu.core.ui.util.RecyclerViewOwner
import org.koitharu.kotatsu.core.ui.widgets.SlidingBottomNavigationView import org.koitharu.kotatsu.core.ui.widgets.SlidingBottomNavigationView
import org.koitharu.kotatsu.core.util.ext.setContentDescriptionAndTooltip
import org.koitharu.kotatsu.core.util.ext.smoothScrollToTop import org.koitharu.kotatsu.core.util.ext.smoothScrollToTop
import org.koitharu.kotatsu.databinding.NavigationRailFabBinding
import org.koitharu.kotatsu.explore.ui.ExploreFragment import org.koitharu.kotatsu.explore.ui.ExploreFragment
import org.koitharu.kotatsu.favourites.ui.container.FavouritesContainerFragment import org.koitharu.kotatsu.favourites.ui.container.FavouritesContainerFragment
import org.koitharu.kotatsu.history.ui.HistoryListFragment import org.koitharu.kotatsu.history.ui.HistoryListFragment
@ -45,9 +53,12 @@ class MainNavigationDelegate(
private val settings: AppSettings, private val settings: AppSettings,
) : OnBackPressedCallback(false), ) : OnBackPressedCallback(false),
NavigationBarView.OnItemSelectedListener, NavigationBarView.OnItemSelectedListener,
NavigationBarView.OnItemReselectedListener { NavigationBarView.OnItemReselectedListener, View.OnClickListener {
private val listeners = LinkedList<OnFragmentChangedListener>() private val listeners = LinkedList<OnFragmentChangedListener>()
private val navRailHeader = (navBar as? NavigationRailView)?.headerView?.let {
NavigationRailFabBinding.bind(it)
}
val primaryFragment: Fragment? val primaryFragment: Fragment?
get() = fragmentManager.findFragmentByTag(TAG_PRIMARY) get() = fragmentManager.findFragmentByTag(TAG_PRIMARY)
@ -55,6 +66,14 @@ class MainNavigationDelegate(
init { init {
navBar.setOnItemSelectedListener(this) navBar.setOnItemSelectedListener(this)
navBar.setOnItemReselectedListener(this) navBar.setOnItemReselectedListener(this)
navRailHeader?.run {
val horizontalPadding = (navBar as NavigationRailView).itemActiveIndicatorExpandedMarginHorizontal
root.setPadding(horizontalPadding, 0, horizontalPadding, 0)
buttonExpand.setOnClickListener(this@MainNavigationDelegate)
buttonExpand.setContentDescriptionAndTooltip(R.string.expand)
railFab.isExtended = false
railFab.isAnimationEnabled = false
}
} }
override fun onNavigationItemSelected(item: MenuItem): Boolean { override fun onNavigationItemSelected(item: MenuItem): Boolean {
@ -70,6 +89,30 @@ class MainNavigationDelegate(
onNavigationItemReselected() onNavigationItemReselected()
} }
override fun onClick(v: View) {
when (v.id) {
R.id.button_expand -> {
if (navBar is NavigationRailView) {
if (navBar.isExpanded) {
navBar.collapse()
navRailHeader?.run {
railFab.shrink()
buttonExpand.setImageResource(R.drawable.ic_drawer_menu)
buttonExpand.setContentDescriptionAndTooltip(R.string.expand)
}
} else {
navBar.expand()
navRailHeader?.run {
railFab.extend()
buttonExpand.setImageResource(R.drawable.ic_drawer_menu_open)
buttonExpand.setContentDescriptionAndTooltip(R.string.collapse)
}
}
}
}
}
}
override fun handleOnBackPressed() { override fun handleOnBackPressed() {
navBar.selectedItemId = firstItem()?.itemId ?: return navBar.selectedItemId = firstItem()?.itemId ?: return
} }
@ -96,6 +139,16 @@ class MainNavigationDelegate(
} }
} }
fun observeTitle() = callbackFlow {
val listener = OnFragmentChangedListener { f, _ ->
trySendBlocking(getItemId(f))
}
addOnFragmentChangedListener(listener)
awaitClose { removeOnFragmentChangedListener(listener) }
}.map {
navBar.menu.findItem(it)?.title
}
fun setCounter(item: NavItem, counter: Int) { fun setCounter(item: NavItem, counter: Int) {
setCounter(item.id, counter) setCounter(item.id, counter)
} }
@ -248,7 +301,7 @@ class MainNavigationDelegate(
} }
} }
interface OnFragmentChangedListener { fun interface OnFragmentChangedListener {
fun onFragmentChanged(fragment: Fragment, fromUser: Boolean) fun onFragmentChanged(fragment: Fragment, fromUser: Boolean)
} }

@ -12,9 +12,7 @@ import android.widget.Button
import android.widget.FrameLayout import android.widget.FrameLayout
import android.widget.LinearLayout import android.widget.LinearLayout
import androidx.annotation.AttrRes import androidx.annotation.AttrRes
import androidx.annotation.StringRes
import androidx.appcompat.widget.TooltipCompat import androidx.appcompat.widget.TooltipCompat
import androidx.core.view.ViewCompat
import androidx.core.view.isVisible import androidx.core.view.isVisible
import androidx.core.view.updateLayoutParams import androidx.core.view.updateLayoutParams
import com.google.android.material.slider.Slider import com.google.android.material.slider.Slider
@ -25,6 +23,7 @@ import org.koitharu.kotatsu.core.prefs.AppSettings
import org.koitharu.kotatsu.core.prefs.ReaderControl import org.koitharu.kotatsu.core.prefs.ReaderControl
import org.koitharu.kotatsu.core.util.ext.hasVisibleChildren import org.koitharu.kotatsu.core.util.ext.hasVisibleChildren
import org.koitharu.kotatsu.core.util.ext.isRtl import org.koitharu.kotatsu.core.util.ext.isRtl
import org.koitharu.kotatsu.core.util.ext.setContentDescriptionAndTooltip
import org.koitharu.kotatsu.core.util.ext.setValueRounded import org.koitharu.kotatsu.core.util.ext.setValueRounded
import org.koitharu.kotatsu.databinding.LayoutReaderActionsBinding import org.koitharu.kotatsu.databinding.LayoutReaderActionsBinding
import org.koitharu.kotatsu.details.ui.pager.ChaptersPagesSheet import org.koitharu.kotatsu.details.ui.pager.ChaptersPagesSheet
@ -134,6 +133,7 @@ class ReaderActionsView @JvmOverloads constructor(
override fun onLongClick(v: View): Boolean = when (v.id) { override fun onLongClick(v: View): Boolean = when (v.id) {
R.id.button_bookmark -> AppRouter.from(this) R.id.button_bookmark -> AppRouter.from(this)
?.showChapterPagesSheet(ChaptersPagesSheet.TAB_BOOKMARKS) ?.showChapterPagesSheet(ChaptersPagesSheet.TAB_BOOKMARKS)
R.id.button_timer -> listener?.onScrollTimerClick(isLongClick = true) R.id.button_timer -> listener?.onScrollTimerClick(isLongClick = true)
R.id.button_options -> AppRouter.from(this)?.openReaderSettings() R.id.button_options -> AppRouter.from(this)?.openReaderSettings()
else -> null else -> null
@ -206,7 +206,7 @@ class ReaderActionsView @JvmOverloads constructor(
button.setIconResource( button.setIconResource(
if (isPagesMode) R.drawable.ic_grid else R.drawable.ic_list, if (isPagesMode) R.drawable.ic_grid else R.drawable.ic_list,
) )
button.setTitle( button.setContentDescriptionAndTooltip(
if (isPagesMode) R.string.pages else R.string.chapters, if (isPagesMode) R.string.pages else R.string.chapters,
) )
} }
@ -216,7 +216,7 @@ class ReaderActionsView @JvmOverloads constructor(
button.setIconResource( button.setIconResource(
if (isBookmarkAdded) R.drawable.ic_bookmark_added else R.drawable.ic_bookmark, if (isBookmarkAdded) R.drawable.ic_bookmark_added else R.drawable.ic_bookmark,
) )
button.setTitle( button.setContentDescriptionAndTooltip(
if (isBookmarkAdded) R.string.bookmark_remove else R.string.bookmark_add, if (isBookmarkAdded) R.string.bookmark_remove else R.string.bookmark_add,
) )
} }
@ -240,12 +240,12 @@ class ReaderActionsView @JvmOverloads constructor(
when { when {
!button.isVisible -> return !button.isVisible -> return
isAutoRotationEnabled() -> { isAutoRotationEnabled() -> {
button.setTitle(R.string.lock_screen_rotation) button.setContentDescriptionAndTooltip(R.string.lock_screen_rotation)
button.setIconResource(R.drawable.ic_screen_rotation_lock) button.setIconResource(R.drawable.ic_screen_rotation_lock)
} }
else -> { else -> {
button.setTitle(R.string.rotate_screen) button.setContentDescriptionAndTooltip(R.string.rotate_screen)
button.setIconResource(R.drawable.ic_screen_rotation) button.setIconResource(R.drawable.ic_screen_rotation)
} }
} }
@ -257,12 +257,6 @@ class ReaderActionsView @JvmOverloads constructor(
TooltipCompat.setTooltipText(this, contentDescription) TooltipCompat.setTooltipText(this, contentDescription)
} }
private fun Button.setTitle(@StringRes titleResId: Int) {
val text = resources.getString(titleResId)
contentDescription = text
TooltipCompat.setTooltipText(this, text)
}
private fun isAutoRotationEnabled(): Boolean = Settings.System.getInt( private fun isAutoRotationEnabled(): Boolean = Settings.System.getInt(
context.contentResolver, context.contentResolver,
Settings.System.ACCELEROMETER_ROTATION, Settings.System.ACCELEROMETER_ROTATION,

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<vector
xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:tint="?attr/colorControlNormal"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="@android:color/white"
android:pathData="M3,18h18v-2L3,16v2zM3,13h18v-2L3,11v2zM3,6v2h18L21,6L3,6z" />
</vector>

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<vector
xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:autoMirrored="true"
android:tint="?attr/colorControlNormal"
android:viewportWidth="960"
android:viewportHeight="960">
<path
android:fillColor="@android:color/white"
android:pathData="M120,720v-80L640,640v80L120,720ZM784,680L584,480L784,280l56,56L696,480L840,624l-56,56ZM120,520v-80L520,440v80L120,520ZM120,320v-80L640,240v80L120,320Z" />
</vector>

@ -12,6 +12,7 @@
android:id="@+id/navRail" android:id="@+id/navRail"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="match_parent" android:layout_height="match_parent"
android:clipToPadding="false"
android:fitsSystemWindows="false" android:fitsSystemWindows="false"
app:elevation="1dp" app:elevation="1dp"
app:headerLayout="@layout/navigation_rail_fab" app:headerLayout="@layout/navigation_rail_fab"
@ -60,6 +61,16 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
app:layout_scrollFlags="scroll|enterAlways|snap"> app:layout_scrollFlags="scroll|enterAlways|snap">
<TextView
android:id="@+id/textView_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical|start"
android:paddingStart="@dimen/screen_padding"
android:textAppearance="?textAppearanceTitleLarge"
tools:ignore="RtlSymmetry"
tools:text="@string/history" />
<com.google.android.material.search.SearchBar <com.google.android.material.search.SearchBar
android:id="@+id/search_bar" android:id="@+id/search_bar"
android:layout_width="match_parent" android:layout_width="match_parent"

@ -34,23 +34,21 @@
android:gravity="center_vertical" android:gravity="center_vertical"
android:singleLine="true" android:singleLine="true"
android:textAppearance="?attr/textAppearanceTitleSmall" android:textAppearance="?attr/textAppearanceTitleSmall"
app:layout_constraintEnd_toStartOf="@id/imageView_expand" app:layout_constraintEnd_toStartOf="@id/button_expand"
app:layout_constraintStart_toEndOf="@id/imageView_cover" app:layout_constraintStart_toEndOf="@id/imageView_cover"
app:layout_constraintTop_toTopOf="parent" app:layout_constraintTop_toTopOf="parent"
app:layout_goneMarginEnd="12dp" app:layout_goneMarginEnd="12dp"
tools:text="@tools:sample/lorem" /> tools:text="@tools:sample/lorem" />
<org.koitharu.kotatsu.core.ui.widgets.CheckableImageView <org.koitharu.kotatsu.core.ui.widgets.CheckableImageButton
android:id="@+id/imageView_expand" android:id="@+id/button_expand"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:background="?selectableItemBackgroundBorderless" android:background="?selectableItemBackgroundBorderless"
android:contentDescription="@string/details" android:contentDescription="@string/expand"
android:minWidth="?minTouchTargetSize" android:minWidth="?minTouchTargetSize"
android:minHeight="?minTouchTargetSize" android:minHeight="?minTouchTargetSize"
android:pointerIcon="hand"
android:scaleType="center" android:scaleType="center"
android:tooltipText="@string/details"
android:visibility="gone" android:visibility="gone"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" app:layout_constraintTop_toTopOf="parent"
@ -63,7 +61,7 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
app:barrierDirection="bottom" app:barrierDirection="bottom"
app:constraint_referenced_ids="imageView_cover,textView_status,imageView_expand,textView_details" /> app:constraint_referenced_ids="imageView_cover,textView_status,button_expand,textView_details" />
<com.google.android.material.progressindicator.LinearProgressIndicator <com.google.android.material.progressindicator.LinearProgressIndicator
android:id="@+id/progressBar" android:id="@+id/progressBar"

@ -14,6 +14,7 @@
android:id="@+id/chips_genres" android:id="@+id/chips_genres"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:clipChildren="false"
android:paddingTop="6dp" android:paddingTop="6dp"
android:paddingBottom="12dp" android:paddingBottom="12dp"
app:singleLine="true" /> app:singleLine="true" />

@ -1,9 +1,29 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<com.google.android.material.floatingactionbutton.FloatingActionButton <LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/railFab" android:id="@+id/cat_navigation_rail_efab_container"
android:layout_width="wrap_content" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:contentDescription="@string/_continue" android:layout_gravity="top|start"
app:srcCompat="@drawable/ic_read" /> android:clipChildren="false"
android:clipToPadding="false"
android:orientation="vertical">
<ImageButton
android:id="@+id/button_expand"
android:layout_width="56dp"
android:layout_height="56dp"
android:background="?selectableItemBackgroundBorderless"
android:contentDescription="@string/expand"
android:scaleType="center"
android:src="@drawable/ic_drawer_menu" />
<com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
android:id="@+id/railFab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/_continue"
app:icon="@drawable/ic_read" />
</LinearLayout>

@ -840,4 +840,6 @@
<string name="hide_from_main_screen">Hide from main screen</string> <string name="hide_from_main_screen">Hide from main screen</string>
<string name="changelog">Changelog</string> <string name="changelog">Changelog</string>
<string name="changelog_summary">Changes history for recently released versions</string> <string name="changelog_summary">Changes history for recently released versions</string>
<string name="collapse">Collapse</string>
<string name="expand">Expand</string>
</resources> </resources>

Loading…
Cancel
Save