Improve CoverImageView
This commit is contained in:
@@ -6,10 +6,11 @@ import android.widget.LinearLayout
|
||||
import androidx.appcompat.widget.AppCompatImageView
|
||||
import androidx.core.content.withStyledAttributes
|
||||
import org.koitharu.kotatsu.R
|
||||
import org.koitharu.kotatsu.utils.ext.resolveAdjustedSize
|
||||
|
||||
|
||||
class CoverImageView @JvmOverloads constructor(
|
||||
context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
|
||||
context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0,
|
||||
) : AppCompatImageView(context, attrs, defStyleAttr) {
|
||||
|
||||
private var orientation: Int = HORIZONTAL
|
||||
@@ -21,25 +22,42 @@ class CoverImageView @JvmOverloads constructor(
|
||||
}
|
||||
|
||||
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
|
||||
val w: Int
|
||||
val h: Int
|
||||
if (orientation == VERTICAL) {
|
||||
val originalHeight = MeasureSpec.getSize(heightMeasureSpec)
|
||||
super.onMeasure(
|
||||
MeasureSpec.makeMeasureSpec(
|
||||
(originalHeight * ASPECT_RATIO_WIDTH / ASPECT_RATIO_HEIGHT).toInt(),
|
||||
MeasureSpec.EXACTLY
|
||||
),
|
||||
MeasureSpec.makeMeasureSpec(originalHeight, MeasureSpec.EXACTLY)
|
||||
val desiredHeight = (drawable?.intrinsicHeight?.coerceAtLeast(0) ?: 0) +
|
||||
paddingTop + paddingBottom
|
||||
h = resolveAdjustedSize(
|
||||
desiredHeight.coerceAtLeast(suggestedMinimumHeight),
|
||||
maxHeight,
|
||||
heightMeasureSpec
|
||||
)
|
||||
val desiredWidth =
|
||||
(h * ASPECT_RATIO_WIDTH / ASPECT_RATIO_HEIGHT).toInt() + paddingLeft + paddingRight
|
||||
w = resolveAdjustedSize(
|
||||
desiredWidth.coerceAtLeast(suggestedMinimumWidth),
|
||||
maxWidth,
|
||||
widthMeasureSpec
|
||||
)
|
||||
} else {
|
||||
val originalWidth = MeasureSpec.getSize(widthMeasureSpec)
|
||||
super.onMeasure(
|
||||
MeasureSpec.makeMeasureSpec(originalWidth, MeasureSpec.EXACTLY),
|
||||
MeasureSpec.makeMeasureSpec(
|
||||
(originalWidth * ASPECT_RATIO_HEIGHT / ASPECT_RATIO_WIDTH).toInt(),
|
||||
MeasureSpec.EXACTLY
|
||||
)
|
||||
val desiredWidth = (drawable?.intrinsicWidth?.coerceAtLeast(0) ?: 0) +
|
||||
paddingLeft + paddingRight
|
||||
w = resolveAdjustedSize(
|
||||
desiredWidth.coerceAtLeast(suggestedMinimumWidth),
|
||||
maxWidth,
|
||||
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 {
|
||||
|
||||
@@ -5,6 +5,7 @@ import android.graphics.Rect
|
||||
import android.view.LayoutInflater
|
||||
import android.view.Menu
|
||||
import android.view.View
|
||||
import android.view.View.MeasureSpec
|
||||
import android.view.ViewGroup
|
||||
import android.view.inputmethod.InputMethodManager
|
||||
import androidx.annotation.LayoutRes
|
||||
@@ -53,7 +54,7 @@ var RecyclerView.firstItem: Int
|
||||
inline fun View.showPopupMenu(
|
||||
@MenuRes menuRes: Int,
|
||||
onPrepare: (Menu) -> Unit = {},
|
||||
onItemClick: PopupMenu.OnMenuItemClickListener
|
||||
onItemClick: PopupMenu.OnMenuItemClickListener,
|
||||
) {
|
||||
val menu = PopupMenu(context, this)
|
||||
menu.inflate(menuRes)
|
||||
@@ -171,4 +172,30 @@ fun BaseProgressIndicator<*>.setIndeterminateCompat(indeterminate: Boolean) {
|
||||
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:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginHorizontal="8dp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:layout_marginBottom="4dp"
|
||||
android:layout_marginHorizontal="8dp"
|
||||
app:cardCornerRadius="4dp"
|
||||
app:cardElevation="4dp">
|
||||
|
||||
@@ -22,9 +22,10 @@
|
||||
android:id="@+id/imageView_cover"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:scaleType="centerCrop"
|
||||
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>
|
||||
|
||||
@@ -33,12 +34,12 @@
|
||||
style="@style/TextAppearance.AppCompat.Body2"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:elegantTextHeight="false"
|
||||
android:ellipsize="end"
|
||||
android:lineSpacingExtra="-2dp"
|
||||
android:maxLines="2"
|
||||
android:paddingHorizontal="8dp"
|
||||
android:paddingBottom="4dp"
|
||||
android:elegantTextHeight="false"
|
||||
tools:text="Sample name" />
|
||||
|
||||
</LinearLayout>
|
||||
Reference in New Issue
Block a user