如何在图像布局上实现可缩放图像?

时间:2017-10-24 15:46:40

标签: android android-constraintlayout

我想在图片的右上角显示一个图标。此外,它应略微抵消。最后,两者的组合应该是可扩展的,因此使总宽度加倍会导致图像以及图标具有与原始宽度相比的两倍。当然,应保持纵横比,使高度也加倍。

由于对这个实际上简单的问题的描述非常复杂,这里有一个巧妙的图画来说明这个主题:)

enter image description here

所以,假设我有RecyclerView GridLayout,其中每个图片图块的宽度为200dp。然后,灰色区域的宽度和高度应为200dp,橙色图标的宽度和高度为50dp,图标与蓝色图像边框的偏移量为25dp,依此类推。

如果我决定将GridLayout中的列数加倍,则灰色区域的宽度和高度为100dp等。

这是我到目前为止所尝试的内容:

我从一个FrameLayout开始,对于最简单的情况可以正常工作,但是只要你想用百分比指定尺寸,就会出现问题。

<FrameLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <ImageView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="50dp"
        android:adjustViewBounds="true"
        app:srcCompat="@drawable/blueShip200x200" />

    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="top|end"
        android:layout_marginRight="25dp"
        android:layout_marginTop="25dp"
        app:srcCompat="@drawable/new50x50" />
</FrameLayout>

然后,我了解了最近在支持库中引入的PercentFrameLayout - 并且已被弃用:https://developer.android.com/reference/android/support/percent/PercentFrameLayout.html

所以现在的建议是使用ConstraintLayout代替(参见上面的链接),你可以使用帮助指南来定义他们的百分比位置。

幸运的是,如果灰色框具有固定的宽度和高度,文档会举例说明如何替换效果很好的PercentFrameLayout

<android.support.constraint.ConstraintLayout
    android:layout_width="200dp"
    android:layout_height="200dp">

    <android.support.constraint.Guideline
        android:id="@+id/left_image_guideline"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        app:layout_constraintGuide_percent=".25" />

    <android.support.constraint.Guideline
        android:id="@+id/right_image_guideline"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        app:layout_constraintGuide_percent=".75" />

    <android.support.constraint.Guideline
        android:id="@+id/top_image_guideline"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        app:layout_constraintGuide_percent=".25" />

    <android.support.constraint.Guideline
        android:id="@+id/bottom_image_guideline"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        app:layout_constraintGuide_percent=".75" />

    <ImageView
        android:layout_width="0dp"
        android:layout_height="0dp"
        app:layout_constraintBottom_toBottomOf="@+id/bottom_image_guideline"
        app:layout_constraintLeft_toLeftOf="@+id/left_image_guideline"
        app:layout_constraintRight_toRightOf="@+id/right_image_guideline"
        app:layout_constraintTop_toTopOf="@+id/top_image_guideline"
        app:srcCompat="@drawable/blueShip200x200" />

    <android.support.constraint.Guideline
        android:id="@+id/left_icon_guideline"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        app:layout_constraintGuide_percent=".625" />

    <android.support.constraint.Guideline
        android:id="@+id/right_icon_guideline"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        app:layout_constraintGuide_percent=".875" />

    <android.support.constraint.Guideline
        android:id="@+id/top_icon_guideline"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        app:layout_constraintGuide_percent=".125" />

    <android.support.constraint.Guideline
        android:id="@+id/bottom_icon_guideline"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        app:layout_constraintGuide_percent=".375" />

    <ImageView
        android:layout_width="0dp"
        android:layout_height="0dp"
        app:layout_constraintBottom_toBottomOf="@+id/bottom_icon_guideline"
        app:layout_constraintLeft_toLeftOf="@+id/left_icon_guideline"
        app:layout_constraintRight_toRightOf="@+id/right_icon_guideline"
        app:layout_constraintTop_toTopOf="@+id/top_icon_guideline"
        app:srcCompat="@drawable/new50x50" />
</android.support.constraint.ConstraintLayout>

但是如果你没有指定固定的尺寸......那就没有了。

调整FrameLayout示例(layout_widthlayout_heightadjustViewBounds)中的以下行会导致ConstraintLayout获得高度为0。

<android.support.constraint.ConstraintLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

<ImageView
    android:layout_width="0dp"
    android:layout_height="0dp"
    android:adjustViewBounds="true"
    app:layout_constraintBottom_toBottomOf="@+id/bottom_image_guideline"
    app:layout_constraintLeft_toLeftOf="@+id/left_image_guideline"
    app:layout_constraintRight_toRightOf="@+id/right_image_guideline"
    app:layout_constraintTop_toTopOf="@+id/top_image_guideline"
    app:srcCompat="@drawable/blueShip200x200" />

我希望通过对布局文件进行一些更改来非编程地解决此问题。基本上,只有adjustViewBounds不能将ImageView的宽度和高度设置为match_constraint(0dp)。

另外,如果可能的话,我想坚持ConstraintLayout。也许可以使用LinearLayoutSpace以及layout_weight来解决问题 - 我还没有尝试过。

谢谢!

3 个答案:

答案 0 :(得分:2)

您可以使用约束布局创建布局。

首先使用一些视图作为指导将布局拆分为5x5。 关键是使用水平和垂直权重。

enter image description here

<!--GUIDE LINE-->
<TextView
    android:id="@+id/guide_1"
    android:layout_width="0dp"
    android:layout_height="0dp"
    android:background="@color/primary_light"
    android:text="25%"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintHorizontal_weight="25"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintRight_toLeftOf="@+id/guide_2"
    app:layout_constraintTop_toBottomOf="@+id/guide_2"
    app:layout_constraintVertical_weight="25" />

<TextView
    android:id="@+id/guide_2"
    android:layout_width="0dp"
    android:layout_height="0dp"
    android:background="@color/primary_light"
    android:text="37.5%"
    app:layout_constraintBottom_toTopOf="@id/guide_1"
    app:layout_constraintHorizontal_weight="37.5"
    app:layout_constraintLeft_toRightOf="@id/guide_1"
    app:layout_constraintRight_toLeftOf="@id/guide_3"
    app:layout_constraintTop_toBottomOf="@id/guide_3"
    app:layout_constraintVertical_weight="37.5" />

<TextView
    android:id="@+id/guide_3"
    android:layout_width="0dp"
    android:layout_height="0dp"
    android:background="@color/primary_light"
    android:text="12.5%"
    app:layout_constraintBottom_toTopOf="@id/guide_2"
    app:layout_constraintHorizontal_weight="12.5"
    app:layout_constraintLeft_toRightOf="@id/guide_2"
    app:layout_constraintRight_toLeftOf="@id/guide_4"
    app:layout_constraintTop_toBottomOf="@id/guide_4"
    app:layout_constraintVertical_weight="12.5" />
<TextView
    android:id="@+id/guide_4"
    android:layout_width="0dp"
    android:layout_height="0dp"
    android:background="@color/primary_light"
    android:text="12.5%"
    app:layout_constraintBottom_toTopOf="@id/guide_3"
    app:layout_constraintHorizontal_weight="12.5"
    app:layout_constraintLeft_toRightOf="@id/guide_3"
    app:layout_constraintRight_toLeftOf="@id/guide_5"
    app:layout_constraintTop_toBottomOf="@id/guide_5"
    app:layout_constraintVertical_weight="12.5" />

<TextView
    android:id="@+id/guide_5"
    android:layout_width="0dp"
    android:layout_height="0dp"
    android:background="@color/primary_light"
    android:text="12.5%"
    app:layout_constraintBottom_toTopOf="@id/guide_4"
    app:layout_constraintHorizontal_weight="12.5"
    app:layout_constraintLeft_toRightOf="@id/guide_4"
    app:layout_constraintRight_toRightOf="parent"
    app:layout_constraintTop_toTopOf="parent"
    app:layout_constraintVertical_weight="12.5" />

创建指南后,您可以使用指南行放置所需的图像...

enter image description here

这两个视图将如下所示。

<TextView
    android:text="MAIN ICON"
    android:textColor="@color/icons"
    android:gravity="center"
    android:textSize="60sp"
    android:layout_width="0dp"
    android:layout_height="0dp"
    app:layout_constraintLeft_toLeftOf="@id/guide_2"
    app:layout_constraintBottom_toBottomOf="@id/guide_2"
    app:layout_constraintTop_toTopOf="@id/guide_3"
    app:layout_constraintRight_toRightOf="@id/guide_3"
    android:background="@color/primary"/>
<TextView
    android:layout_width="0dp"
    android:layout_height="0dp"
    app:layout_constraintTop_toTopOf="@id/guide_4"
    app:layout_constraintRight_toRightOf="@id/guide_4"
    app:layout_constraintBottom_toBottomOf="@id/guide_3"
    app:layout_constraintLeft_toLeftOf="@id/guide_3"
    android:background="@color/accent"
    android:text="NEW"
    android:gravity="center"
    android:textSize="40sp"
    android:textColor="@color/icons"/>

答案 1 :(得分:0)

小图像的FIxing维度将帮助您获得这种UI。请查看下面的代码

<?xml version="1.0" encoding="utf-8"?>
    <android.support.constraint.ConstraintLayout 
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">
    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:paddingTop="25dp"
        android:paddingRight="25dp"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        android:id="@+id/image"
        app:layout_constraintBottom_toBottomOf="parent"
        app:srcCompat="@drawable/blue200" />

    <ImageView
        android:layout_width="50dp"
        android:layout_height="50dp"
        app:layout_constraintTop_toTopOf="@+id/image"
        app:layout_constraintRight_toRightOf="@+id/image"
        app:srcCompat="@drawable/new50x50" />
</android.support.constraint.ConstraintLayout>

答案 2 :(得分:0)

您想要完成的事情可以通过ConstraintLayout的一些新增功能来完成。我使用版本1.1.0-beta3执行了以下操作。请参阅文档here

对于ConstrainLayout的后续版本,我们现在可以将视图的宽度和高度指定为包含视图的宽度/高度的百分比。蓝色框的大小为灰色区域宽度/高度的50%并居中。

橙色盒子的大小为容器宽度和高度的25%。它的中心位于蓝色框的右上角,将其开始和结束侧设置为蓝色框的末端,顶部和底部设置在顶部。

布局将适应所有尺寸,但正如您所提到的,必须遵守宽高比。

enter image description here

<android.support.constraint.ConstraintLayout 
    android:layout_width="200dp"
    android:layout_height="200dp">

    <ImageView
        android:id="@+id/boat"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:adjustViewBounds="true"
        android:src="@drawable/boat"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHeight_default="percent"
        app:layout_constraintHeight_percent="0.5"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintWidth_default="percent"
        app:layout_constraintWidth_percent="0.5" />

    <ImageView
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:src="@drawable/new_square"
        app:layout_constraintBottom_toTopOf="@id/boat"
        app:layout_constraintEnd_toEndOf="@id/boat"
        app:layout_constraintHeight_default="percent"
        app:layout_constraintHeight_percent="0.25"
        app:layout_constraintStart_toEndOf="@id/boat"
        app:layout_constraintTop_toTopOf="@id/boat"
        app:layout_constraintWidth_default="percent"
        app:layout_constraintWidth_percent="0..25" />
</android.support.constraint.ConstraintLayout>

以下是我使用的图片:

enter image description here enter image description here