Java/Android:如何在不切断边缘视图的情况下显示一系列图像视图?

Posted

技术标签:

【中文标题】Java/Android:如何在不切断边缘视图的情况下显示一系列图像视图?【英文标题】:Java/Android: How to display series of imageViews without cutting off edge views? 【发布时间】:2021-03-28 17:57:33 【问题描述】:

我正在尝试以可重复使用的布局显示一系列 4 个头像。我的布局test_layout.xml 如下所示:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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_
    android:layout_>

    <ImageView
        android:id="@+id/img1"
        android:layout_
        android:layout_
        android:scaleType="fitStart"
        android:layout_marginEnd="1dp"
        android:adjustViewBounds="true"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toStartOf="@+id/img2"
        app:layout_constraintHorizontal_chainStyle="packed"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        tools:srcCompat="@tools:sample/avatars" />

    <ImageView
        android:id="@+id/img2"
        android:layout_
        android:layout_
        android:scaleType="fitStart"
        android:layout_marginHorizontal="1dp"
        android:adjustViewBounds="true"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toStartOf="@id/img3"
        app:layout_constraintStart_toEndOf="@+id/img1"
        app:layout_constraintTop_toTopOf="parent"
        tools:srcCompat="@tools:sample/avatars" />

    <ImageView
        android:id="@+id/img3"
        android:layout_
        android:layout_
        android:scaleType="fitStart"
        android:layout_marginHorizontal="1dp"
        android:adjustViewBounds="true"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toStartOf="@id/img4"
        app:layout_constraintStart_toEndOf="@+id/img2"
        app:layout_constraintTop_toTopOf="parent"
        tools:srcCompat="@tools:sample/avatars" />

    <ImageView
        android:id="@+id/img4"
        android:layout_
        android:layout_
        android:scaleType="fitStart"
        android:layout_marginStart="1dp"
        android:adjustViewBounds="true"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toEndOf="@+id/img3"
        app:layout_constraintTop_toTopOf="parent"
        tools:srcCompat="@tools:sample/avatars" />

</androidx.constraintlayout.widget.ConstraintLayout>

我将在多个地方重用这个布局(有时在同一个屏幕上多次),所以它需要是通过include 标签(或者可能是merge)合并的自己的布局。

当框架太宽/太短时,这种布局看起来很棒,完全符合我的预期,头像处于“打包”形式:

但是当框架太窄/太高时,布局开始切断外部的图像:

我怎样才能做到这一点,而不是切断图像的侧面,而是调整它们的大小,使它们都水平适合,并在顶部和底部添加空白?我对任何类型的布局持开放态度,而不仅仅是constraintlayout。谢谢!

【问题讨论】:

您是否尝试过使用ScrollView @Mustansir,我不希望它可滚动,我希望始终显示所有四个图像 【参考方案1】:

我要做的可能是以编程方式为这四个 ImageView 设置 LayoutParams:

int totalWidth = yourConstraintLayout.getWidth();
yourImageView1.setLayoutParams(new  ConstraintLayout.LayoutParams(totalWidth / 4, totalWidth / 4));

// And the same thing for the rest of your imageViews, or just use a for loop

这只会将图片的宽度设置为其父级(ConstraintLayout)的四分之一。我想这就是您要问的吗?让我知道它是否适合您!

【讨论】:

我在屏幕截图中使用占位符图像,但实际上图像的宽度不同,并且会在整个应用程序生命周期内发生变化,因此很遗憾这种方法行不通。我需要它来动态调整图像的大小【参考方案2】:

设置所有宽度以匹配约束和所有高度以包裹内容

<ImageView
    android:id="@+id/img1"
    android:layout_
    android:layout_
    android:layout_marginEnd="1dp"
    android:adjustViewBounds="true"
    android:scaleType="fitStart"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintEnd_toStartOf="@+id/img2"
    app:layout_constraintHorizontal_chainStyle="packed"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent"
    tools:srcCompat="@tools:sample/avatars" />

<ImageView
    android:id="@+id/img2"
    android:layout_
    android:layout_
    android:layout_marginHorizontal="1dp"
    android:adjustViewBounds="true"
    android:scaleType="fitStart"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintEnd_toStartOf="@id/img3"
    app:layout_constraintStart_toEndOf="@+id/img1"
    app:layout_constraintTop_toTopOf="parent"
    tools:srcCompat="@tools:sample/avatars" />

<ImageView
    android:id="@+id/img3"
    android:layout_
    android:layout_
    android:layout_marginHorizontal="1dp"
    android:adjustViewBounds="true"
    android:scaleType="fitStart"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintEnd_toStartOf="@id/img4"
    app:layout_constraintStart_toEndOf="@+id/img2"
    app:layout_constraintTop_toTopOf="parent"
    tools:srcCompat="@tools:sample/avatars" />

<ImageView
    android:id="@+id/img4"
    android:layout_
    android:layout_
    android:layout_marginStart="1dp"
    android:adjustViewBounds="true"
    android:scaleType="fitStart"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toEndOf="@+id/img3"
    app:layout_constraintTop_toTopOf="parent"
    tools:srcCompat="@tools:sample/avatars" />

【讨论】:

这解决了容器太窄/太高的问题,但现在当容器太宽时头像不尊重packed链样式,而是分散开来。我也尝试将两个维度都设置为wrap_content,但是当容器太窄时,这仍然会切断外部的图像【参考方案3】:

我认为像@Zuo Wang 所说的那样以编程方式进行,这是最好的选择。但是,如果您不想那样做,仍然通过 XML 来做。在这里,您可能有一种方法。设置一个 maxHeight,但它并不适合所有设备屏幕。

这里有一个 250dp 高度的预览

这里有 50dp 的高度

   <androidx.constraintlayout.widget.ConstraintLayout
    android:id="@+id/imageWrapper"
    android:layout_
    android:layout_
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintTop_toTopOf="parent">

    <ImageView
        android:id="@+id/img1"
        android:layout_
        android:layout_
        android:adjustViewBounds="true"
        android:maxHeight="100dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toStartOf="@id/img2"
        app:layout_constraintHorizontal_chainStyle="packed"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_chainStyle="packed"
        tools:srcCompat="@tools:sample/avatars" />

    <ImageView
        android:id="@+id/img2"
        android:layout_
        android:layout_
        android:adjustViewBounds="true"
        android:maxHeight="100dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toStartOf="@id/img3"
        app:layout_constraintStart_toEndOf="@id/img1"
        app:layout_constraintTop_toTopOf="parent"
        tools:srcCompat="@tools:sample/avatars" />

    <ImageView
        android:id="@+id/img3"
        android:layout_
        android:layout_
        android:adjustViewBounds="true"
        android:maxHeight="100dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toStartOf="@id/img4"
        app:layout_constraintStart_toEndOf="@id/img2"
        app:layout_constraintTop_toTopOf="parent"
        tools:srcCompat="@tools:sample/avatars" />

    <ImageView
        android:id="@+id/img4"
        android:layout_
        android:layout_
        android:adjustViewBounds="true"
        android:maxHeight="100dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toEndOf="@id/img3"
        app:layout_constraintTop_toTopOf="parent"
        tools:srcCompat="@tools:sample/avatars" />

</androidx.constraintlayout.widget.ConstraintLayout>

【讨论】:

这很奇怪,当容器太窄时,这会在顶部和底部引入空白(这很好),但它仍然会同时切断侧面的部分图像。我不确定为什么这两种情况都允许同时发生【参考方案4】:

设置您的 test_layout.xml 高度 wrap_content 和宽度 match_constraints

然后如果您使用 include 添加到另一个布局,您需要设置高度 wrap_content 以保持原始大小

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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_
    android:layout_>

    <ImageView
        android:id="@+id/img1"
        android:layout_
        android:layout_
        android:adjustViewBounds="true"
        android:scaleType="fitStart"
        app:layout_constraintEnd_toStartOf="@id/img2"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        tools:srcCompat="@tools:sample/avatars" />

    <ImageView
        android:id="@+id/img2"
        android:layout_
        android:layout_
        android:adjustViewBounds="true"
        android:scaleType="fitStart"
        app:layout_constraintEnd_toStartOf="@id/img3"
        app:layout_constraintStart_toEndOf="@id/img1"
        app:layout_constraintTop_toTopOf="parent"
        tools:srcCompat="@tools:sample/avatars" />

    <ImageView
        android:id="@+id/img3"
        android:layout_
        android:layout_
        android:adjustViewBounds="true"
        android:scaleType="fitStart"
        app:layout_constraintEnd_toStartOf="@id/img4"
        app:layout_constraintStart_toEndOf="@id/img2"
        app:layout_constraintTop_toTopOf="parent"
        tools:srcCompat="@tools:sample/avatars" />

    <ImageView
        android:id="@+id/img4"
        android:layout_
        android:layout_
        android:adjustViewBounds="true"
        android:scaleType="fitStart"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toEndOf="@id/img3"
        app:layout_constraintTop_toTopOf="parent"
        tools:srcCompat="@tools:sample/avatars" />

</androidx.constraintlayout.widget.ConstraintLayout>

【讨论】:

这会使整个容器消失,因为所有单个图像的高度都是 0(使用 ConstraintLayout 的 match_constraints 行为所必需的),我误解了吗? @NicoleGerber 对不起我的小姐,检查编辑的答案,我尝试将宽度更改为match_constraints,将高度更改为wrap_content,以将固定宽度更改为任何屏幕尺寸 啊好的,另一位发帖人建议这样做,但问题是这解决了容器太窄/太高时的问题,但现在化身不尊重容器时的打包链样式太宽了,反而它们散开了。我也尝试将两个维度都作为 wrap_content ,但是当容器太窄时,这仍然会切断外部的图像

以上是关于Java/Android:如何在不切断边缘视图的情况下显示一系列图像视图?的主要内容,如果未能解决你的问题,请参考以下文章

MFMailComposeViewController 在 iOS 7 中切断消息正文的右边缘

将图像调整为更小只是切断边缘

从 Adob​​e Illustrator 导出到 PNG 会切断边缘 [关闭]

如何在 20 个字符后切断文本视图?

如何在 iPhone 中混合来自不同视图的颜色

表格视图单元格中的 ImageView 切断标签(自动布局)[关闭]