ImageView по ширине, начиная сверху

У меня есть изображение, которое должно соответствовать ширине, но поскольку оно длинное, мне нужно, чтобы верхняя часть оставалась видимой, я попытался использовать ImageView:

<ImageView
    android:layout_width = "match_parent"
    android:layout_height = "match_parent"
    android:src = "@mipmap/day_length_background"
    android:scaleType = "centerCrop"
    android:adjustViewBounds = "true"
    />

Но результат такой:

ImageView по ширине, начиная сверху

Я не могу использовать fitXY, потому что он меняет соотношение сторон.

Мне нужно, чтобы это было так ImageView по ширине, начиная сверху

Попробуйте установить его в качестве фона для imageView. Это не сработает, вы можете предоставить ссылку на фактическое изображение, которое вы используете.

ADM 10.05.2018 16:19
2
1
842
5

Ответы 5

Centercrop - ваша проблема. Попробуйте fitXY, он должен работать, если соотношение сторон примерно такое же.

Нет, fitXY искажает соотношение сторон.

AVEbrahimi 10.05.2018 16:01

могу пройти через то, что я бы попробовал. если вам просто нужна ширина, соответствующая телефону, возможно, измените высоту на wrap_content. Возможно, придется поместить его в режим прокрутки, если вы хотите сохранить соотношение сторон и согласовать ширину с экраном, если поэтому изображение должно быть длиннее экрана.

Ryan McCaffrey 10.05.2018 16:04

Попробуйте scaleType = "fitStart"

Scale the image using Matrix.ScaleToFit.START

Matrix.ScaleToFit.START: Compute a scale that will maintain the original src aspect ratio, but will also ensure that src fits entirely inside dst. At least one axis (X or Y) will fit exactly. START aligns the result to the left and top edges of dst.

Ссылка здесь: https://robots.oughttbot.com/android-imageview-scaletype-a-visual-guide#fit_start

fitStart не будет работать, потому что высота изображения больше, чем высота экрана, поэтому оно соответствует высоте, а не ширине: |

AVEbrahimi 10.05.2018 16:32

Поместите изображение в папку выдвижной и поместите изображение в фон вашего макета, т.е.

<RelativeLayout xmlns:android = "http://schemas.android.com/apk/res/android"
    xmlns:tools = "http://schemas.android.com/tools"
    android:layout_width = "match_parent"
    android:layout_height = "match_parent"
    android:orientation = "vertical"
    android:background = "@drawable/image">

Вы также можете разрезать изображение пополам

или, возможно, использовать настраиваемую матрицу в java

if (imageView.getScaleType() != ImageView.ScaleType.MATRIX) {
                    imageView.setScaleType(ImageView.ScaleType.MATRIX);
                }
                Matrix m = imageView.getImageMatrix();
                int dw = imageView.getDrawable().getIntrinsicWidth();
                int dh = imageView.getDrawable().getIntrinsicHeight();
                int msWidth, msHeight;
                float scalew, scaleh;

                Display display = activity.getWindowManager().getDefaultDisplay();
                Point size = new Point();
                display.getSize(size);
                msWidth = size.x;
                if (imageView.getLayoutParams().width == ViewGroup.LayoutParams.WRAP_CONTENT) {
                    msWidth = dw < msWidth ? dw : msWidth;
                }
                scalew = (float) msWidth / dw;
                msHeight = size.y;
                if (imageView.getLayoutParams().height == ViewGroup.LayoutParams.WRAP_CONTENT) {
                    msHeight = dh < msHeight ? dh : msHeight;
                }
                scaleh = (float) msHeight / dh;
                float scale = Math.max(scalew, scaleh);

                m.setScale(scale, scale);
                m.postTranslate(0, 0);
                imageView.setImageMatrix(m);
            }

Вы можете использовать эту реализацию TopCropImageView:

class TopCropImageView : AppCompatImageView {
    constructor(context: Context) : super(context) {
        init()
    }

    constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) {
        init()
    }

    constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr) {
        init()
    }

    override fun onLayout(changed: Boolean, left: Int, top: Int, right: Int, bottom: Int) {
        super.onLayout(changed, left, top, right, bottom)
        recomputeImgMatrix()
    }

    override fun setFrame(l: Int, t: Int, r: Int, b: Int): Boolean {
        recomputeImgMatrix()
        return super.setFrame(l, t, r, b)
    }

    private fun init() {
        scaleType = ScaleType.MATRIX
    }

    private fun recomputeImgMatrix() {
        val drawable = drawable ?: return
        val matrix = imageMatrix
        val scale: Float
        val viewWidth = width - paddingLeft - paddingRight
        val viewHeight = height - paddingTop - paddingBottom
        val drawableWidth = drawable.intrinsicWidth
        val drawableHeight = drawable.intrinsicHeight
        scale = if (drawableWidth * viewHeight > drawableHeight * viewWidth) {
            viewHeight.toFloat() / drawableHeight.toFloat()
        } else {
            viewWidth.toFloat() / drawableWidth.toFloat()
        }
        matrix.setScale(scale, scale)
        imageMatrix = matrix
    }
}

Верх будет выровнен, а вид снизу будет обрезан.

Другие вопросы по теме