Expandable manga description
This commit is contained in:
@@ -11,6 +11,7 @@ import androidx.core.content.res.use
|
||||
import androidx.core.view.isGone
|
||||
import androidx.core.widget.TextViewCompat
|
||||
|
||||
|
||||
var TextView.textAndVisible: CharSequence?
|
||||
get() = text?.takeIf { visibility == View.VISIBLE }
|
||||
set(value) {
|
||||
@@ -70,3 +71,13 @@ fun TextView.setThemeTextAppearance(@AttrRes resId: Int, @StyleRes fallback: Int
|
||||
TextViewCompat.setTextAppearance(this, it.getResourceId(0, fallback))
|
||||
}
|
||||
}
|
||||
|
||||
val TextView.isTextTruncated: Boolean
|
||||
get() {
|
||||
val l = layout ?: return false
|
||||
if (maxLines in 0 until l.lineCount) {
|
||||
return true
|
||||
}
|
||||
val layoutLines = l.lineCount
|
||||
return layoutLines > 0 && l.getEllipsisCount(layoutLines - 1) > 0
|
||||
}
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
package org.koitharu.kotatsu.details.ui
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.ViewGroup
|
||||
import androidx.fragment.app.FragmentManager
|
||||
import org.koitharu.kotatsu.core.ui.sheet.BaseAdaptiveSheet
|
||||
import org.koitharu.kotatsu.core.util.ext.showDistinct
|
||||
import org.koitharu.kotatsu.core.util.ext.withArgs
|
||||
import org.koitharu.kotatsu.databinding.SheetDescriptionBinding
|
||||
|
||||
class DescriptionSheet : BaseAdaptiveSheet<SheetDescriptionBinding>() {
|
||||
|
||||
override fun onCreateViewBinding(inflater: LayoutInflater, container: ViewGroup?): SheetDescriptionBinding {
|
||||
return SheetDescriptionBinding.inflate(inflater, container, false)
|
||||
}
|
||||
|
||||
override fun onViewBindingCreated(binding: SheetDescriptionBinding, savedInstanceState: Bundle?) {
|
||||
super.onViewBindingCreated(binding, savedInstanceState)
|
||||
binding.textViewDescription.text = arguments?.getCharSequence(ARG_CONTENT)
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
private const val ARG_CONTENT = "content"
|
||||
private const val TAG = "DescriptionSheet"
|
||||
|
||||
fun show(fm: FragmentManager, content: CharSequence) = DescriptionSheet().withArgs(1) {
|
||||
putCharSequence(ARG_CONTENT, content)
|
||||
}.showDistinct(fm, TAG)
|
||||
}
|
||||
}
|
||||
@@ -2,9 +2,11 @@ package org.koitharu.kotatsu.details.ui
|
||||
|
||||
import android.os.Bundle
|
||||
import android.text.method.LinkMovementMethod
|
||||
import android.transition.TransitionManager
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.view.ViewTreeObserver
|
||||
import android.widget.Toast
|
||||
import androidx.appcompat.widget.PopupMenu
|
||||
import androidx.core.content.ContextCompat
|
||||
@@ -36,7 +38,9 @@ import org.koitharu.kotatsu.core.util.ext.crossfade
|
||||
import org.koitharu.kotatsu.core.util.ext.drawableTop
|
||||
import org.koitharu.kotatsu.core.util.ext.enqueueWith
|
||||
import org.koitharu.kotatsu.core.util.ext.ifNullOrEmpty
|
||||
import org.koitharu.kotatsu.core.util.ext.isTextTruncated
|
||||
import org.koitharu.kotatsu.core.util.ext.observe
|
||||
import org.koitharu.kotatsu.core.util.ext.parentView
|
||||
import org.koitharu.kotatsu.core.util.ext.resolveDp
|
||||
import org.koitharu.kotatsu.core.util.ext.scaleUpActivityOptionsOf
|
||||
import org.koitharu.kotatsu.core.util.ext.textAndVisible
|
||||
@@ -70,7 +74,7 @@ class DetailsFragment :
|
||||
BaseFragment<FragmentDetailsBinding>(),
|
||||
View.OnClickListener,
|
||||
ChipsView.OnChipClickListener,
|
||||
OnListItemClickListener<Bookmark> {
|
||||
OnListItemClickListener<Bookmark>, ViewTreeObserver.OnDrawListener {
|
||||
|
||||
@Inject
|
||||
lateinit var coil: ImageLoader
|
||||
@@ -94,6 +98,7 @@ class DetailsFragment :
|
||||
binding.buttonScrobblingMore.setOnClickListener(this)
|
||||
binding.buttonRelatedMore.setOnClickListener(this)
|
||||
binding.infoLayout.textViewSource.setOnClickListener(this)
|
||||
binding.textViewDescription.viewTreeObserver.addOnDrawListener(this)
|
||||
binding.textViewDescription.movementMethod = LinkMovementMethod.getInstance()
|
||||
binding.chipsTags.onChipClickListener = this
|
||||
binding.recyclerViewRelated.addItemDecoration(
|
||||
@@ -132,6 +137,13 @@ class DetailsFragment :
|
||||
return true
|
||||
}
|
||||
|
||||
override fun onDraw() {
|
||||
viewBinding?.run {
|
||||
buttonDescriptionMore.isVisible = textViewDescription.maxLines == Int.MAX_VALUE ||
|
||||
textViewDescription.isTextTruncated
|
||||
}
|
||||
}
|
||||
|
||||
private fun onMangaUpdated(manga: Manga) {
|
||||
with(requireViewBinding()) {
|
||||
// Main
|
||||
@@ -189,12 +201,13 @@ class DetailsFragment :
|
||||
}
|
||||
|
||||
private fun onDescriptionChanged(description: CharSequence?) {
|
||||
val tv = requireViewBinding().textViewDescription
|
||||
if (description.isNullOrBlank()) {
|
||||
requireViewBinding().textViewDescription.setText(R.string.no_description)
|
||||
tv.setText(R.string.no_description)
|
||||
} else {
|
||||
requireViewBinding().textViewDescription.text = description
|
||||
tv.text = description
|
||||
}
|
||||
requireViewBinding().buttonDescriptionMore.isGone = description.isNullOrBlank()
|
||||
requireViewBinding().buttonDescriptionMore.isVisible = tv.isTextTruncated
|
||||
}
|
||||
|
||||
private fun onLocalSizeChanged(size: Long) {
|
||||
@@ -300,7 +313,13 @@ class DetailsFragment :
|
||||
}
|
||||
|
||||
R.id.button_description_more -> {
|
||||
DescriptionSheet.show(parentFragmentManager, viewModel.description.value ?: return)
|
||||
val tv = requireViewBinding().textViewDescription
|
||||
TransitionManager.beginDelayedTransition(tv.parentView)
|
||||
if (tv.maxLines in 1 until Integer.MAX_VALUE) {
|
||||
tv.maxLines = Integer.MAX_VALUE
|
||||
} else {
|
||||
tv.maxLines = resources.getInteger(R.integer.details_description_lines)
|
||||
}
|
||||
}
|
||||
|
||||
R.id.button_scrobbling_more -> {
|
||||
|
||||
@@ -164,7 +164,7 @@
|
||||
app:layout_constraintBaseline_toBaselineOf="@id/textView_description_title"
|
||||
app:layout_constraintEnd_toEndOf="parent" />
|
||||
|
||||
<TextView
|
||||
<org.koitharu.kotatsu.core.ui.widgets.SelectableTextView
|
||||
android:id="@+id/textView_description"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
@@ -173,9 +173,10 @@
|
||||
android:layout_marginEnd="@dimen/margin_normal"
|
||||
android:ellipsize="end"
|
||||
android:lineSpacingMultiplier="1.2"
|
||||
android:maxLines="5"
|
||||
android:maxLines="@integer/details_description_lines"
|
||||
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/textView_description_title"
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:animateLayoutChanges="true"
|
||||
android:orientation="vertical">
|
||||
|
||||
<org.koitharu.kotatsu.core.ui.sheet.AdaptiveSheetHeaderBar
|
||||
android:id="@+id/headerBar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:title="@string/description" />
|
||||
|
||||
<androidx.core.widget.NestedScrollView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<org.koitharu.kotatsu.core.ui.widgets.SelectableTextView
|
||||
android:id="@+id/textView_description"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="@dimen/margin_normal"
|
||||
android:layout_marginEnd="@dimen/margin_normal"
|
||||
android:lineSpacingMultiplier="1.2"
|
||||
android:paddingBottom="@dimen/margin_normal"
|
||||
android:textAppearance="?attr/textAppearanceBodyMedium"
|
||||
android:textIsSelectable="true"
|
||||
tools:text="@tools:sample/lorem/random" />
|
||||
|
||||
</androidx.core.widget.NestedScrollView>
|
||||
</LinearLayout>
|
||||
@@ -6,4 +6,5 @@
|
||||
|
||||
<integer name="manga_badge_max_character_count">3</integer>
|
||||
<integer name="explore_buttons_columns">2</integer>
|
||||
<integer name="details_description_lines">5</integer>
|
||||
</resources>
|
||||
|
||||
Reference in New Issue
Block a user