Improve CoverImageView
This commit is contained in:
@@ -6,10 +6,11 @@ import android.widget.LinearLayout
|
|||||||
import androidx.appcompat.widget.AppCompatImageView
|
import androidx.appcompat.widget.AppCompatImageView
|
||||||
import androidx.core.content.withStyledAttributes
|
import androidx.core.content.withStyledAttributes
|
||||||
import org.koitharu.kotatsu.R
|
import org.koitharu.kotatsu.R
|
||||||
|
import org.koitharu.kotatsu.utils.ext.resolveAdjustedSize
|
||||||
|
|
||||||
|
|
||||||
class CoverImageView @JvmOverloads constructor(
|
class CoverImageView @JvmOverloads constructor(
|
||||||
context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
|
context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0,
|
||||||
) : AppCompatImageView(context, attrs, defStyleAttr) {
|
) : AppCompatImageView(context, attrs, defStyleAttr) {
|
||||||
|
|
||||||
private var orientation: Int = HORIZONTAL
|
private var orientation: Int = HORIZONTAL
|
||||||
@@ -21,25 +22,42 @@ class CoverImageView @JvmOverloads constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
|
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
|
||||||
|
val w: Int
|
||||||
|
val h: Int
|
||||||
if (orientation == VERTICAL) {
|
if (orientation == VERTICAL) {
|
||||||
val originalHeight = MeasureSpec.getSize(heightMeasureSpec)
|
val desiredHeight = (drawable?.intrinsicHeight?.coerceAtLeast(0) ?: 0) +
|
||||||
super.onMeasure(
|
paddingTop + paddingBottom
|
||||||
MeasureSpec.makeMeasureSpec(
|
h = resolveAdjustedSize(
|
||||||
(originalHeight * ASPECT_RATIO_WIDTH / ASPECT_RATIO_HEIGHT).toInt(),
|
desiredHeight.coerceAtLeast(suggestedMinimumHeight),
|
||||||
MeasureSpec.EXACTLY
|
maxHeight,
|
||||||
),
|
heightMeasureSpec
|
||||||
MeasureSpec.makeMeasureSpec(originalHeight, MeasureSpec.EXACTLY)
|
)
|
||||||
|
val desiredWidth =
|
||||||
|
(h * ASPECT_RATIO_WIDTH / ASPECT_RATIO_HEIGHT).toInt() + paddingLeft + paddingRight
|
||||||
|
w = resolveAdjustedSize(
|
||||||
|
desiredWidth.coerceAtLeast(suggestedMinimumWidth),
|
||||||
|
maxWidth,
|
||||||
|
widthMeasureSpec
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
val originalWidth = MeasureSpec.getSize(widthMeasureSpec)
|
val desiredWidth = (drawable?.intrinsicWidth?.coerceAtLeast(0) ?: 0) +
|
||||||
super.onMeasure(
|
paddingLeft + paddingRight
|
||||||
MeasureSpec.makeMeasureSpec(originalWidth, MeasureSpec.EXACTLY),
|
w = resolveAdjustedSize(
|
||||||
MeasureSpec.makeMeasureSpec(
|
desiredWidth.coerceAtLeast(suggestedMinimumWidth),
|
||||||
(originalWidth * ASPECT_RATIO_HEIGHT / ASPECT_RATIO_WIDTH).toInt(),
|
maxWidth,
|
||||||
MeasureSpec.EXACTLY
|
widthMeasureSpec
|
||||||
)
|
)
|
||||||
|
val desiredHeight =
|
||||||
|
(w * ASPECT_RATIO_HEIGHT / ASPECT_RATIO_WIDTH).toInt() + paddingTop + paddingBottom
|
||||||
|
h = resolveAdjustedSize(
|
||||||
|
desiredHeight.coerceAtLeast(suggestedMinimumHeight),
|
||||||
|
maxHeight,
|
||||||
|
heightMeasureSpec
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
val widthSize = resolveSizeAndState(w, widthMeasureSpec, 0)
|
||||||
|
val heightSize = resolveSizeAndState(h, heightMeasureSpec, 0)
|
||||||
|
setMeasuredDimension(widthSize, heightSize)
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import android.graphics.Rect
|
|||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.Menu
|
import android.view.Menu
|
||||||
import android.view.View
|
import android.view.View
|
||||||
|
import android.view.View.MeasureSpec
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import android.view.inputmethod.InputMethodManager
|
import android.view.inputmethod.InputMethodManager
|
||||||
import androidx.annotation.LayoutRes
|
import androidx.annotation.LayoutRes
|
||||||
@@ -53,7 +54,7 @@ var RecyclerView.firstItem: Int
|
|||||||
inline fun View.showPopupMenu(
|
inline fun View.showPopupMenu(
|
||||||
@MenuRes menuRes: Int,
|
@MenuRes menuRes: Int,
|
||||||
onPrepare: (Menu) -> Unit = {},
|
onPrepare: (Menu) -> Unit = {},
|
||||||
onItemClick: PopupMenu.OnMenuItemClickListener
|
onItemClick: PopupMenu.OnMenuItemClickListener,
|
||||||
) {
|
) {
|
||||||
val menu = PopupMenu(context, this)
|
val menu = PopupMenu(context, this)
|
||||||
menu.inflate(menuRes)
|
menu.inflate(menuRes)
|
||||||
@@ -171,4 +172,30 @@ fun BaseProgressIndicator<*>.setIndeterminateCompat(indeterminate: Boolean) {
|
|||||||
isIndeterminate = indeterminate
|
isIndeterminate = indeterminate
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun resolveAdjustedSize(
|
||||||
|
desiredSize: Int,
|
||||||
|
maxSize: Int,
|
||||||
|
measureSpec: Int,
|
||||||
|
): Int {
|
||||||
|
val specMode = MeasureSpec.getMode(measureSpec)
|
||||||
|
val specSize = MeasureSpec.getSize(measureSpec)
|
||||||
|
return when (specMode) {
|
||||||
|
MeasureSpec.UNSPECIFIED ->
|
||||||
|
// Parent says we can be as big as we want. Just don't be larger
|
||||||
|
// than max size imposed on ourselves.
|
||||||
|
desiredSize.coerceAtMost(maxSize)
|
||||||
|
MeasureSpec.AT_MOST ->
|
||||||
|
// Parent says we can be as big as we want, up to specSize.
|
||||||
|
// Don't be larger than specSize, and don't be larger than
|
||||||
|
// the max size imposed on ourselves.
|
||||||
|
desiredSize.coerceAtMost(specSize).coerceAtMost(maxSize)
|
||||||
|
MeasureSpec.EXACTLY ->
|
||||||
|
// No choice. Do what we are told.
|
||||||
|
specSize
|
||||||
|
else ->
|
||||||
|
// This should not happen
|
||||||
|
desiredSize
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -12,9 +12,9 @@
|
|||||||
android:id="@+id/card"
|
android:id="@+id/card"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginHorizontal="8dp"
|
||||||
android:layout_marginTop="8dp"
|
android:layout_marginTop="8dp"
|
||||||
android:layout_marginBottom="4dp"
|
android:layout_marginBottom="4dp"
|
||||||
android:layout_marginHorizontal="8dp"
|
|
||||||
app:cardCornerRadius="4dp"
|
app:cardCornerRadius="4dp"
|
||||||
app:cardElevation="4dp">
|
app:cardElevation="4dp">
|
||||||
|
|
||||||
@@ -22,9 +22,10 @@
|
|||||||
android:id="@+id/imageView_cover"
|
android:id="@+id/imageView_cover"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:scaleType="centerCrop"
|
|
||||||
android:orientation="horizontal"
|
android:orientation="horizontal"
|
||||||
tools:ignore="ContentDescription" />
|
android:scaleType="centerCrop"
|
||||||
|
tools:ignore="ContentDescription"
|
||||||
|
tools:src="@tools:sample/backgrounds/scenic[3]" />
|
||||||
|
|
||||||
</com.google.android.material.card.MaterialCardView>
|
</com.google.android.material.card.MaterialCardView>
|
||||||
|
|
||||||
@@ -33,12 +34,12 @@
|
|||||||
style="@style/TextAppearance.AppCompat.Body2"
|
style="@style/TextAppearance.AppCompat.Body2"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
android:elegantTextHeight="false"
|
||||||
android:ellipsize="end"
|
android:ellipsize="end"
|
||||||
android:lineSpacingExtra="-2dp"
|
android:lineSpacingExtra="-2dp"
|
||||||
android:maxLines="2"
|
android:maxLines="2"
|
||||||
android:paddingHorizontal="8dp"
|
android:paddingHorizontal="8dp"
|
||||||
android:paddingBottom="4dp"
|
android:paddingBottom="4dp"
|
||||||
android:elegantTextHeight="false"
|
|
||||||
tools:text="Sample name" />
|
tools:text="Sample name" />
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
Reference in New Issue
Block a user