UI improvements

This commit is contained in:
Koitharu
2023-12-13 11:32:52 +02:00
parent afd56c02e6
commit bb2294f248
11 changed files with 329 additions and 202 deletions

View File

@@ -65,10 +65,7 @@ fun categoryAD(
binding.imageViewEdit.setOnClickListener(eventListener) binding.imageViewEdit.setOnClickListener(eventListener)
binding.imageViewHandle.setOnTouchListener(eventListener) binding.imageViewHandle.setOnTouchListener(eventListener)
bind { payloads -> bind {
if (payloads.isNotEmpty()) {
return@bind
}
binding.textViewTitle.text = item.category.title binding.textViewTitle.text = item.category.title
binding.textViewSubtitle.text = if (item.mangaCount == 0) { binding.textViewSubtitle.text = if (item.mangaCount == 0) {
getString(R.string.empty) getString(R.string.empty)

View File

@@ -15,13 +15,13 @@ fun categoriesHeaderAD() = adapterDelegateViewBinding<CategoriesHeaderItem, List
val onClickListener = View.OnClickListener { v -> val onClickListener = View.OnClickListener { v ->
val intent = when (v.id) { val intent = when (v.id) {
R.id.button_create -> FavouritesCategoryEditActivity.newIntent(v.context) R.id.chip_create -> FavouritesCategoryEditActivity.newIntent(v.context)
R.id.button_manage -> FavouriteCategoriesActivity.newIntent(v.context) R.id.chip_manage -> FavouriteCategoriesActivity.newIntent(v.context)
else -> return@OnClickListener else -> return@OnClickListener
} }
v.context.startActivity(intent) v.context.startActivity(intent)
} }
binding.buttonCreate.setOnClickListener(onClickListener) binding.chipCreate.setOnClickListener(onClickListener)
binding.buttonManage.setOnClickListener(onClickListener) binding.chipManage.setOnClickListener(onClickListener)
} }

View File

@@ -8,6 +8,7 @@ import android.view.ViewGroup
import android.widget.AdapterView import android.widget.AdapterView
import android.widget.ArrayAdapter import android.widget.ArrayAdapter
import androidx.core.view.isGone import androidx.core.view.isGone
import androidx.core.view.updatePadding
import androidx.fragment.app.FragmentManager import androidx.fragment.app.FragmentManager
import com.google.android.material.chip.Chip import com.google.android.material.chip.Chip
import org.koitharu.kotatsu.R import org.koitharu.kotatsu.R
@@ -39,8 +40,11 @@ class FilterSheetFragment :
override fun onViewBindingCreated(binding: SheetFilterBinding, savedInstanceState: Bundle?) { override fun onViewBindingCreated(binding: SheetFilterBinding, savedInstanceState: Bundle?) {
super.onViewBindingCreated(binding, savedInstanceState) super.onViewBindingCreated(binding, savedInstanceState)
if (dialog == null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { if (dialog == null) {
binding.scrollView.scrollIndicators = 0 binding.layoutBody.updatePadding(top = binding.layoutBody.paddingBottom)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
binding.scrollView.scrollIndicators = 0
}
} }
val filter = requireFilter() val filter = requireFilter()
filter.filterSortOrder.observe(viewLifecycleOwner, this::onSortOrderChanged) filter.filterSortOrder.observe(viewLifecycleOwner, this::onSortOrderChanged)

View File

@@ -31,6 +31,7 @@ import org.koitharu.kotatsu.filter.ui.FilterOwner
import org.koitharu.kotatsu.image.ui.ImageActivity import org.koitharu.kotatsu.image.ui.ImageActivity
import org.koitharu.kotatsu.parsers.model.Manga import org.koitharu.kotatsu.parsers.model.Manga
import org.koitharu.kotatsu.parsers.model.MangaTag import org.koitharu.kotatsu.parsers.model.MangaTag
import org.koitharu.kotatsu.reader.ui.ReaderActivity
import org.koitharu.kotatsu.search.ui.MangaListActivity import org.koitharu.kotatsu.search.ui.MangaListActivity
import org.koitharu.kotatsu.search.ui.SearchActivity import org.koitharu.kotatsu.search.ui.SearchActivity
import javax.inject.Inject import javax.inject.Inject
@@ -56,8 +57,10 @@ class PreviewFragment : BaseFragment<FragmentPreviewBinding>(), View.OnClickList
binding.textViewAuthor.setOnClickListener(this) binding.textViewAuthor.setOnClickListener(this)
binding.imageViewCover.setOnClickListener(this) binding.imageViewCover.setOnClickListener(this)
binding.buttonOpen.setOnClickListener(this) binding.buttonOpen.setOnClickListener(this)
binding.buttonRead.setOnClickListener(this)
viewModel.manga.observe(viewLifecycleOwner, ::onMangaUpdated) viewModel.manga.observe(viewLifecycleOwner, ::onMangaUpdated)
viewModel.footer.observe(viewLifecycleOwner, ::onFooterUpdated)
viewModel.tagsChips.observe(viewLifecycleOwner, ::onTagsChipsChanged) viewModel.tagsChips.observe(viewLifecycleOwner, ::onTagsChipsChanged)
viewModel.description.observe(viewLifecycleOwner, ::onDescriptionChanged) viewModel.description.observe(viewLifecycleOwner, ::onDescriptionChanged)
} }
@@ -70,6 +73,14 @@ class PreviewFragment : BaseFragment<FragmentPreviewBinding>(), View.OnClickList
DetailsActivity.newIntent(v.context, manga), DetailsActivity.newIntent(v.context, manga),
) )
R.id.button_read -> {
startActivity(
ReaderActivity.IntentBuilder(v.context)
.manga(manga)
.build(),
)
}
R.id.textView_author -> startActivity( R.id.textView_author -> startActivity(
SearchActivity.newIntent( SearchActivity.newIntent(
context = v.context, context = v.context,
@@ -118,6 +129,43 @@ class PreviewFragment : BaseFragment<FragmentPreviewBinding>(), View.OnClickList
} }
} }
private fun onFooterUpdated(footer: PreviewViewModel.FooterInfo?) {
with(requireViewBinding()) {
toolbarBottom.isVisible = footer != null
if (footer == null) {
return
}
toolbarBottom.title = when {
footer.isInProgress() -> {
getString(R.string.chapter_d_of_d, footer.currentChapter, footer.totalChapters)
}
footer.totalChapters > 0 -> {
resources.getQuantityString(R.plurals.chapters, footer.totalChapters, footer.totalChapters)
}
else -> {
getString(R.string.no_chapters)
}
}
buttonRead.isEnabled = footer.totalChapters > 0
buttonRead.setIconResource(
when {
footer.isIncognito -> R.drawable.ic_incognito
footer.isInProgress() -> R.drawable.ic_play
else -> R.drawable.ic_read
},
)
buttonRead.setText(
if (footer.isInProgress()) {
R.string._continue
} else {
R.string.read
},
)
}
}
private fun onDescriptionChanged(description: CharSequence?) { private fun onDescriptionChanged(description: CharSequence?) {
val tv = viewBinding?.textViewDescription ?: return val tv = viewBinding?.textViewDescription ?: return
when { when {

View File

@@ -13,11 +13,14 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.distinctUntilChangedBy import kotlinx.coroutines.flow.distinctUntilChangedBy
import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.stateIn import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.flow.transformLatest import kotlinx.coroutines.flow.transformLatest
import kotlinx.coroutines.plus import kotlinx.coroutines.plus
import org.koitharu.kotatsu.core.model.getPreferredBranch
import org.koitharu.kotatsu.core.model.parcelable.ParcelableManga import org.koitharu.kotatsu.core.model.parcelable.ParcelableManga
import org.koitharu.kotatsu.core.parser.MangaIntent import org.koitharu.kotatsu.core.parser.MangaIntent
import org.koitharu.kotatsu.core.parser.MangaRepository import org.koitharu.kotatsu.core.parser.MangaRepository
@@ -25,6 +28,7 @@ import org.koitharu.kotatsu.core.ui.BaseViewModel
import org.koitharu.kotatsu.core.ui.widgets.ChipsView import org.koitharu.kotatsu.core.ui.widgets.ChipsView
import org.koitharu.kotatsu.core.util.ext.require import org.koitharu.kotatsu.core.util.ext.require
import org.koitharu.kotatsu.core.util.ext.sanitize import org.koitharu.kotatsu.core.util.ext.sanitize
import org.koitharu.kotatsu.history.data.HistoryRepository
import org.koitharu.kotatsu.list.domain.ListExtraProvider import org.koitharu.kotatsu.list.domain.ListExtraProvider
import javax.inject.Inject import javax.inject.Inject
@@ -33,6 +37,7 @@ class PreviewViewModel @Inject constructor(
savedStateHandle: SavedStateHandle, savedStateHandle: SavedStateHandle,
private val extraProvider: ListExtraProvider, private val extraProvider: ListExtraProvider,
private val repositoryFactory: MangaRepository.Factory, private val repositoryFactory: MangaRepository.Factory,
private val historyRepository: HistoryRepository,
private val imageGetter: Html.ImageGetter, private val imageGetter: Html.ImageGetter,
) : BaseViewModel() { ) : BaseViewModel() {
@@ -40,6 +45,26 @@ class PreviewViewModel @Inject constructor(
savedStateHandle.require<ParcelableManga>(MangaIntent.KEY_MANGA).manga, savedStateHandle.require<ParcelableManga>(MangaIntent.KEY_MANGA).manga,
) )
val footer = combine(
manga,
historyRepository.observeOne(manga.value.id),
manga.flatMapLatest { historyRepository.observeShouldSkip(it) }.distinctUntilChanged(),
) { m, history, incognito ->
if (m.chapters == null) {
return@combine null
}
val b = m.getPreferredBranch(history)
val chapters = m.getChapters(b).orEmpty()
FooterInfo(
branch = b,
currentChapter = history?.chapterId?.let {
chapters.indexOfFirst { x -> x.id == it }
} ?: -1,
totalChapters = chapters.size,
isIncognito = incognito,
)
}.stateIn(viewModelScope + Dispatchers.Default, SharingStarted.Lazily, null)
val description = manga val description = manga
.distinctUntilChangedBy { it.description.orEmpty() } .distinctUntilChangedBy { it.description.orEmpty() }
.transformLatest { .transformLatest {
@@ -82,4 +107,14 @@ class PreviewViewModel @Inject constructor(
} }
return spannable.trim() return spannable.trim()
} }
data class FooterInfo(
val branch: String?,
val currentChapter: Int,
val totalChapters: Int,
val isIncognito: Boolean,
) {
fun isInProgress() = currentChapter >= 0
}
} }

View File

@@ -1,23 +1,23 @@
package org.koitharu.kotatsu.search.ui.suggestion.adapter package org.koitharu.kotatsu.search.ui.suggestion.adapter
import com.hannesdorfmann.adapterdelegates4.dsl.adapterDelegate import com.hannesdorfmann.adapterdelegates4.dsl.adapterDelegateViewBinding
import org.koitharu.kotatsu.R
import org.koitharu.kotatsu.core.ui.widgets.ChipsView import org.koitharu.kotatsu.core.ui.widgets.ChipsView
import org.koitharu.kotatsu.databinding.ItemSearchSuggestionTagsBinding
import org.koitharu.kotatsu.parsers.model.MangaTag import org.koitharu.kotatsu.parsers.model.MangaTag
import org.koitharu.kotatsu.search.ui.suggestion.SearchSuggestionListener import org.koitharu.kotatsu.search.ui.suggestion.SearchSuggestionListener
import org.koitharu.kotatsu.search.ui.suggestion.model.SearchSuggestionItem import org.koitharu.kotatsu.search.ui.suggestion.model.SearchSuggestionItem
fun searchSuggestionTagsAD( fun searchSuggestionTagsAD(
listener: SearchSuggestionListener, listener: SearchSuggestionListener,
) = adapterDelegate<SearchSuggestionItem.Tags, SearchSuggestionItem>(R.layout.item_search_suggestion_tags) { ) = adapterDelegateViewBinding<SearchSuggestionItem.Tags, SearchSuggestionItem, ItemSearchSuggestionTagsBinding>(
{ layoutInflater, parent -> ItemSearchSuggestionTagsBinding.inflate(layoutInflater, parent, false) },
) {
val chipGroup = itemView as ChipsView binding.chipsGenres.onChipClickListener = ChipsView.OnChipClickListener { _, data ->
chipGroup.onChipClickListener = ChipsView.OnChipClickListener { _, data ->
listener.onTagClick(data as? MangaTag ?: return@OnChipClickListener) listener.onTagClick(data as? MangaTag ?: return@OnChipClickListener)
} }
bind { bind {
chipGroup.setChips(item.tags) binding.chipsGenres.setChips(item.tags)
} }
} }

View File

@@ -1,165 +1,197 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<ScrollView <FrameLayout
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"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent">
<androidx.constraintlayout.widget.ConstraintLayout <ScrollView
android:id="@+id/scrollView"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content"> android:layout_height="wrap_content"
android:scrollIndicators="bottom">
<com.google.android.material.imageview.ShapeableImageView <androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/imageView_cover" android:layout_width="match_parent"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:background="?colorSecondaryContainer"
android:foreground="?selectableItemBackground"
android:scaleType="centerCrop"
app:layout_constraintDimensionRatio="H,13:18"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintWidth_percent="0.3"
app:shapeAppearanceOverlay="@style/ShapeAppearanceOverlay.Kotatsu.Cover"
tools:background="@tools:sample/backgrounds/scenic[5]"
tools:ignore="ContentDescription,UnusedAttribute" />
<TextView
android:id="@+id/textView_title"
android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="16dp" android:paddingBottom="?actionBarSize">
android:layout_marginTop="16dp"
android:ellipsize="end"
android:maxLines="5"
android:textAppearance="?attr/textAppearanceHeadlineSmall"
app:layout_constraintEnd_toStartOf="@id/button_open"
app:layout_constraintStart_toEndOf="@id/imageView_cover"
app:layout_constraintTop_toTopOf="parent"
app:layout_goneMarginEnd="16dp"
tools:text="@tools:sample/lorem" />
<ImageButton <com.google.android.material.imageview.ShapeableImageView
android:id="@+id/button_open" android:id="@+id/imageView_cover"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:background="?colorSecondaryContainer"
android:foreground="?selectableItemBackground"
android:scaleType="centerCrop"
app:layout_constraintDimensionRatio="H,13:18"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintWidth_percent="0.3"
app:shapeAppearanceOverlay="@style/ShapeAppearanceOverlay.Kotatsu.Cover"
tools:background="@tools:sample/backgrounds/scenic[5]"
tools:ignore="ContentDescription,UnusedAttribute" />
<TextView
android:id="@+id/textView_title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:ellipsize="end"
android:maxLines="5"
android:textAppearance="?attr/textAppearanceHeadlineSmall"
app:layout_constraintEnd_toStartOf="@id/button_open"
app:layout_constraintStart_toEndOf="@id/imageView_cover"
app:layout_constraintTop_toTopOf="parent"
app:layout_goneMarginEnd="16dp"
tools:text="@tools:sample/lorem" />
<ImageButton
android:id="@+id/button_open"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="4dp"
android:background="?selectableItemBackgroundBorderless"
android:contentDescription="@string/details"
android:padding="12dp"
app:layout_constraintEnd_toStartOf="@id/button_close"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/ic_expand" />
<ImageButton
android:id="@+id/button_close"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="4dp"
android:layout_marginEnd="4dp"
android:background="?selectableItemBackgroundBorderless"
android:contentDescription="@string/close"
android:padding="12dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="?actionModeCloseDrawable"
app:tint="?colorControlNormal" />
<TextView
android:id="@+id/textView_subtitle"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="4dp"
android:layout_marginEnd="16dp"
android:ellipsize="end"
android:maxLines="3"
android:textAppearance="?attr/textAppearanceBodyMedium"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/imageView_cover"
app:layout_constraintTop_toBottomOf="@id/textView_title"
tools:text="@tools:sample/lorem[12]" />
<TextView
android:id="@+id/textView_author"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="4dp"
android:layout_marginEnd="16dp"
android:background="@drawable/list_selector"
android:padding="2dp"
android:singleLine="true"
android:textColor="?attr/colorTertiary"
android:textStyle="bold"
app:layout_constrainedWidth="true"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0"
app:layout_constraintStart_toEndOf="@id/imageView_cover"
app:layout_constraintTop_toBottomOf="@id/textView_subtitle"
tools:text="@tools:sample/full_names" />
<RatingBar
android:id="@+id/rating_bar"
style="?ratingBarStyleSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="4dp"
android:layout_marginEnd="16dp"
android:isIndicator="true"
android:max="1"
android:numStars="5"
android:stepSize="0.5"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toEndOf="@id/imageView_cover"
app:layout_constraintTop_toBottomOf="@id/textView_author"
tools:rating="4" />
<androidx.constraintlayout.widget.Barrier
android:id="@+id/barrier_header"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:barrierDirection="bottom"
app:barrierMargin="8dp"
app:constraint_referenced_ids="imageView_cover,rating_bar" />
<org.koitharu.kotatsu.core.ui.widgets.ChipsView
android:id="@+id/chips_tags"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:paddingStart="16dp"
android:paddingEnd="16dp"
app:chipSpacingHorizontal="6dp"
app:chipSpacingVertical="6dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/barrier_header" />
<org.koitharu.kotatsu.core.ui.widgets.SelectableTextView
android:id="@+id/textView_description"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/margin_normal"
android:layout_marginTop="@dimen/margin_small"
android:layout_marginEnd="@dimen/margin_normal"
android:lineSpacingMultiplier="1.2"
android:paddingBottom="@dimen/margin_normal"
android:textAppearance="?attr/textAppearanceBodyMedium"
android:textIsSelectable="true"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/chips_tags"
tools:ignore="UnusedAttribute"
tools:text="@tools:sample/lorem/random" />
</androidx.constraintlayout.widget.ConstraintLayout>
</ScrollView>
<com.google.android.material.appbar.MaterialToolbar
android:id="@+id/toolbar_bottom"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:background="?colorBackgroundFloating">
<com.google.android.material.button.MaterialButton
android:id="@+id/button_read"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="4dp" android:layout_gravity="end|center_vertical"
android:background="?selectableItemBackgroundBorderless" android:layout_marginHorizontal="@dimen/toolbar_button_margin"
android:contentDescription="@string/details" android:enabled="false"
android:padding="12dp" android:text="@string/read"
app:layout_constraintEnd_toStartOf="@id/button_close" android:textAllCaps="false"
app:layout_constraintTop_toTopOf="parent" app:iconGravity="textStart"
app:srcCompat="@drawable/ic_expand" /> app:iconPadding="8dp"
tools:enabled="true"
tools:icon="@drawable/ic_read" />
<ImageButton </com.google.android.material.appbar.MaterialToolbar>
android:id="@+id/button_close"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="4dp"
android:layout_marginEnd="4dp"
android:background="?selectableItemBackgroundBorderless"
android:contentDescription="@string/close"
android:padding="12dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="?actionModeCloseDrawable"
app:tint="?colorControlNormal" />
<TextView </FrameLayout>
android:id="@+id/textView_subtitle"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="4dp"
android:layout_marginEnd="16dp"
android:ellipsize="end"
android:maxLines="3"
android:textAppearance="?attr/textAppearanceBodyMedium"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/imageView_cover"
app:layout_constraintTop_toBottomOf="@id/textView_title"
tools:text="@tools:sample/lorem[12]" />
<TextView
android:id="@+id/textView_author"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="4dp"
android:layout_marginEnd="16dp"
android:background="@drawable/list_selector"
android:padding="2dp"
android:singleLine="true"
android:textColor="?attr/colorTertiary"
android:textStyle="bold"
app:layout_constrainedWidth="true"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0"
app:layout_constraintStart_toEndOf="@id/imageView_cover"
app:layout_constraintTop_toBottomOf="@id/textView_subtitle"
tools:text="@tools:sample/full_names" />
<RatingBar
android:id="@+id/rating_bar"
style="?ratingBarStyleSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="4dp"
android:layout_marginEnd="16dp"
android:isIndicator="true"
android:max="1"
android:numStars="5"
android:stepSize="0.5"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toEndOf="@id/imageView_cover"
app:layout_constraintTop_toBottomOf="@id/textView_author"
tools:rating="4" />
<androidx.constraintlayout.widget.Barrier
android:id="@+id/barrier_header"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:barrierDirection="bottom"
app:barrierMargin="8dp"
app:constraint_referenced_ids="imageView_cover,rating_bar" />
<org.koitharu.kotatsu.core.ui.widgets.ChipsView
android:id="@+id/chips_tags"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:paddingStart="16dp"
android:paddingEnd="16dp"
app:chipSpacingHorizontal="6dp"
app:chipSpacingVertical="6dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/barrier_header" />
<org.koitharu.kotatsu.core.ui.widgets.SelectableTextView
android:id="@+id/textView_description"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/margin_normal"
android:layout_marginTop="@dimen/margin_small"
android:layout_marginEnd="@dimen/margin_normal"
android:lineSpacingMultiplier="1.2"
android:paddingBottom="@dimen/margin_normal"
android:textAppearance="?attr/textAppearanceBodyMedium"
android:textIsSelectable="true"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/chips_tags"
tools:ignore="UnusedAttribute"
tools:text="@tools:sample/lorem/random" />
</androidx.constraintlayout.widget.ConstraintLayout>
</ScrollView>

View File

@@ -1,34 +1,34 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<LinearLayout <HorizontalScrollView
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:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:gravity="center" android:scrollbars="none">
android:orientation="horizontal"
android:paddingHorizontal="12dp"
android:paddingVertical="8dp"
app:layout_scrollFlags="scroll|exitUntilCollapsed">
<Button <com.google.android.material.chip.ChipGroup
android:id="@+id/button_create"
style="@style/Widget.Material3.Button.OutlinedButton"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:ellipsize="end" android:paddingStart="?listPreferredItemPaddingStart"
android:singleLine="true" android:paddingEnd="?listPreferredItemPaddingEnd"
android:text="@string/create_category" app:singleLine="true">
app:icon="@drawable/ic_add" />
<Button <com.google.android.material.chip.Chip
android:id="@+id/button_manage" android:id="@+id/chip_create"
style="@style/Widget.Material3.Button.OutlinedButton" style="@style/Widget.Kotatsu.Chip.Assist"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="8dp" android:text="@string/create_category"
android:ellipsize="end" app:chipIcon="@drawable/ic_add" />
android:singleLine="true"
android:text="@string/manage"
app:icon="@drawable/ic_edit" />
</LinearLayout> <com.google.android.material.chip.Chip
android:id="@+id/chip_manage"
style="@style/Widget.Kotatsu.Chip.Assist"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/manage_categories"
app:chipIcon="@drawable/ic_edit" />
</com.google.android.material.chip.ChipGroup>
</HorizontalScrollView>

View File

@@ -1,9 +1,18 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<org.koitharu.kotatsu.core.ui.widgets.ChipsView <HorizontalScrollView
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"
android:id="@+id/scrollView"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:paddingStart="?listPreferredItemPaddingStart" android:scrollbars="none">
android:paddingTop="4dp"
android:paddingEnd="?listPreferredItemPaddingEnd" <org.koitharu.kotatsu.core.ui.widgets.ChipsView
android:paddingBottom="6dp" /> android:id="@+id/chips_genres"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingStart="?listPreferredItemPaddingStart"
android:paddingEnd="?listPreferredItemPaddingEnd"
app:singleLine="true" />
</HorizontalScrollView>

View File

@@ -20,6 +20,7 @@
android:scrollIndicators="top"> android:scrollIndicators="top">
<LinearLayout <LinearLayout
android:id="@+id/layout_body"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="vertical" android:orientation="vertical"

View File

@@ -17,18 +17,19 @@
<com.google.android.material.textfield.TextInputLayout <com.google.android.material.textfield.TextInputLayout
android:id="@+id/text_input_layout" android:id="@+id/text_input_layout"
style="?textInputFilledDenseStyle"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
app:startIconDrawable="?android:actionModeWebSearchDrawable"
app:endIconMode="clear_text"
app:endIconDrawable="@drawable/abc_ic_clear_material"
android:hint="@string/genres_search_hint"
android:layout_marginHorizontal="16dp" android:layout_marginHorizontal="16dp"
android:layout_marginBottom="4dp" android:layout_marginBottom="4dp"
android:hint="@string/genres_search_hint"
app:endIconDrawable="@drawable/abc_ic_clear_material"
app:endIconMode="clear_text"
app:layout_constraintBottom_toTopOf="@id/recyclerView"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/headerBar" app:layout_constraintTop_toBottomOf="@id/headerBar"
app:layout_constraintBottom_toTopOf="@id/recyclerView"> app:startIconDrawable="?android:actionModeWebSearchDrawable">
<com.google.android.material.textfield.TextInputEditText <com.google.android.material.textfield.TextInputEditText
android:id="@+id/edit_search" android:id="@+id/edit_search"
@@ -36,7 +37,7 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:imeOptions="actionSearch|flagNoFullscreen" android:imeOptions="actionSearch|flagNoFullscreen"
android:importantForAutofill="no" android:importantForAutofill="no"
android:inputType="text"/> android:inputType="text" />
</com.google.android.material.textfield.TextInputLayout> </com.google.android.material.textfield.TextInputLayout>