相对于ImageView尺寸的ConstraintLayout [英] ConstraintLayout relative to ImageView dimensions

查看:80
本文介绍了相对于ImageView尺寸的ConstraintLayout的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在开发一个小型Android应用程序,并使用新的ConstraintLayout.

I'm currently developing a small Android application and use the new ConstraintLayout.

我有一个ImageView,其中包含一个矢量图形图像,相对于其长宽比,该图形应该占据最大的可用空间.我将其与以下代码一起使用:

I have an ImageView which contains a vector graphic image which is supposed to take the maximum space available with respect to its aspect ratio. I got this to work with the following code:

<ImageView
    android:id="@+id/imageView"
    android:layout_width="0dp"
    android:layout_height="0dp"
    android:layout_margin="@dimen/margin"
    android:src="@drawable/image"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintRight_toRightOf="parent"
    app:layout_constraintTop_toTopOf="parent"
    />

现在,我想在精确位置放置多个自定义视图(按钮).使用约束准则,我想到了以下内容:

Now, I want to place multiple custom views (buttons) at exact positions. Using Constraint Guidelines, I came up with the following:

<android.support.constraint.Guideline
    android:id="@+id/guideline_x"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    app:layout_constraintGuide_percent="0.20"
    tools:layout_editor_absoluteX="..."
    tools:layout_editor_absoluteY="..."
    />

<android.support.constraint.Guideline
    android:id="@+id/guideline_y"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
    app:layout_constraintGuide_percent="0.20"
    tools:layout_editor_absoluteX="..."
    tools:layout_editor_absoluteY="..."
    />

<com.example.android.myCustomView
    android:id="@+id/myCustomView"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:onClick="doSomething"
    app:layout_constraintLeft_toLeftOf="@+id/guideline_x"
    app:layout_constraintTop_toTopOf="@+id/guideline_y"
    />

这非常适合我最初使用的特定设备.但是:一旦设备尺寸改变,自定义视图就会放在错误的位置.

This works great for the specific device that I've been testing with initially. But: As soon as the device dimensions vary, the custom views are placed at wrong positions.

我正在寻找一种相对于图像视图的x坐标放置自定义视图n%的方法.我尝试将app:layout_constraintLeft_toLeftOf="@+id/imageView"添加到准则中,但这没有任何改变.您对我如何解决此问题有任何想法吗?非常感谢!

I am looking for a way to place a custom view n% relative to the x coordinate of the image view. I've tried adding app:layout_constraintLeft_toLeftOf="@+id/imageView" to the guidelines but this changes nothing. Do you have any ideas how I can resolve this issue? Thanks a lot!

这是两张说明问题的图像.

Here are 2 images which illustrate the issue.

三星Galaxy S8:

Samsung Galaxy S8:

Google Pixel XL:

Google Pixel XL:

红色小方块应始终相对于Android图标处于完全相同的位置.

The little red square should always be at the exact same position relative to the Android icon.

推荐答案

这是一种将窗口小部件精确放置在ImageView或任何其他视图上的简便方法,无论ImageView只要纵横比保持恒定即可.在我的其他答案的第一个建议的解决方案中,我建议使用偏差将小部件放置在ImageView中.不幸的是,将窗口小部件的相对大小更改为ImageView的大小会导致窗口小部件在图像上移动,这是不希望的.

Here is a easier way to place a widget precisely on an ImageView or any other view that will retain it placement regardless of any change in size of the ImageView as long as the aspect ratio remains constant. In the first proposed solution of my other answer, I suggested using bias to place the widget within the ImageView. Unfortunately, a change in the relative size of the widget to to the size of the ImageView causes the widget to shift on the image which is not desireable.

要解决此问题,我建议使用偏压在ImageView上放置一个1x1像素Space视图.由于空间"视图的大小仅为1x1像素,因此可以通过使用偏差将其放置在ImageView中的任何位置.由于ImageView大小的改变(由于在单个设备上旋转)或因为应用托管在具有不同屏幕尺寸的设备上,因此它的相对位置将保持不变.无论屏幕大小如何,图像的纵横比都必须保持恒定.

To get around this, I suggest placing a 1x1 pixel Space view on the ImageView using bias. Because the Space view is just 1x1 pixel in size, it can be placed anywhere within the ImageView by using bias. It's relative position will remain constant as the ImageView changes size due to rotation on a single device or because the app is being hosted on devices with different screen sizes. It is just important that the aspect ratio of the image remain constant regardless of the size of the screen.

一旦放置了1x1像素视图,就可以通过约束来附加窗口小部件.在下面的示例中,我通过将每只眼睛小部件的所有侧面限制在其放置像素的相应侧面,来选择将眼睛的小部件置于放置像素的中心.

Once the 1x1 pixel view is placed, the widget can be attached through constraints. In the example below, I have chosen to center the widgets for the eyes on the placement pixels by constraining all sides of each eye widget to the corresponding sides of its placement pixel.

以下是一些显示效果的图像.我测试过的各种尺寸的屏幕显示出相同的结果.

Here are some images showing the effect. Screen with varying sizes that I have tested show the same result.

Nexus 6纵向

Nexus 6景观

由于眼睛的ImageView没有缩放,因此它们在Nexus 10屏幕上显得较小.眼睛与Nexus 6放在同一位置.缩放眼睛是另一回事.

Because the ImageViews for the eyes are not scaled, they appear smaller on the Nexus 10 screen. The eyes are placed in the same location as on the Nexus 6. Scaling the eyes is a different matter.

Nexus 10景观

以下是显示约束的布局:

Here is the layout showing the constraints:

position_view.xml

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

    <ImageView
        android:id="@+id/androidGreen"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:src="@drawable/android_image"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintDimensionRatio="H,1:1"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        tools:ignore="ContentDescription" />

    <Space
        android:id="@+id/pinpoint1"
        android:layout_width="1px"
        android:layout_height="1px"
        app:layout_constraintBottom_toBottomOf="@id/androidGreen"
        app:layout_constraintEnd_toEndOf="@id/androidGreen"
        app:layout_constraintHorizontal_bias="0.373"
        app:layout_constraintStart_toStartOf="@id/androidGreen"
        app:layout_constraintTop_toTopOf="@id/androidGreen"
        app:layout_constraintVertical_bias="0.19" />

    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/circle"
        app:layout_constraintBottom_toBottomOf="@id/pinpoint1"
        app:layout_constraintEnd_toEndOf="@id/pinpoint1"
        app:layout_constraintStart_toStartOf="@id/pinpoint1"
        app:layout_constraintTop_toTopOf="@id/pinpoint1"
        app:srcCompat="@drawable/circle"
        tools:ignore="ContentDescription" />

    <Space
        android:id="@+id/pinpoint2"
        android:layout_width="1px"
        android:layout_height="1px"
        android:background="@android:color/holo_red_light"
        app:layout_constraintBottom_toBottomOf="@id/androidGreen"
        app:layout_constraintEnd_toEndOf="@id/androidGreen"
        app:layout_constraintHorizontal_bias="0.625"
        app:layout_constraintStart_toStartOf="@id/androidGreen"
        app:layout_constraintTop_toTopOf="@id/androidGreen"
        app:layout_constraintVertical_bias="0.19" />

    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/circle"
        app:layout_constraintBottom_toBottomOf="@id/pinpoint2"
        app:layout_constraintEnd_toEndOf="@id/pinpoint2"
        app:layout_constraintStart_toStartOf="@id/pinpoint2"
        app:layout_constraintTop_toTopOf="@id/pinpoint2"
        tools:ignore="ContentDescription" />

</android.support.constraint.ConstraintLayout>

您还可以通过将ImageView包裹在ConstraintLayout中并将ImageView的宽度和高度设置为match_parent来实现相同的目标.然后,您可以使用百分比准则将小部件放置在ImageView上.此方法在布局层次结构中引入了另一个级别,但可能更易于理解.

You can also achieve the same goal by wrapping the ImageView in a ConstraintLayout and setting the width and height of the ImageView to match_parent. You can then use percent guidelines to position a widget on the ImageView. This method introduces another level in the layout hierarchy but may be easier to understand.

这里是XML,它将演示此方法.

Here is XML that will demonstrate this method.

使用嵌套ConstraintLayout

XML using guidelines within nested ConstraintLayout

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

    <android.support.constraint.ConstraintLayout
        android:layout_width="0dp"
        android:layout_height="0dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintDimensionRatio="H,1:1"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent">

        <ImageView
            android:id="@+id/androidGreen"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:src="@drawable/android_image"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            tools:ignore="ContentDescription" />

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

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

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

        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@drawable/circle"
            app:layout_constraintBottom_toBottomOf="@id/guidelineHorizontal"
            app:layout_constraintEnd_toEndOf="@id/guidelineVerticalLeft"
            app:layout_constraintStart_toStartOf="@id/guidelineVerticalLeft"
            app:layout_constraintTop_toTopOf="@id/guidelineHorizontal"
            app:srcCompat="@drawable/circle"
            tools:ignore="ContentDescription" />

        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@drawable/circle"
            app:layout_constraintBottom_toBottomOf="@id/guidelineHorizontal"
            app:layout_constraintEnd_toEndOf="@id/guidelineVerticalRight"
            app:layout_constraintStart_toStartOf="@id/guidelineVerticalRight"
            app:layout_constraintTop_toTopOf="@id/guidelineHorizontal"
            tools:ignore="ContentDescription" />

    </android.support.constraint.ConstraintLayout>
</android.support.constraint.ConstraintLayout>

这篇关于相对于ImageView尺寸的ConstraintLayout的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆