Android ConstraintLayout:在工具栏上重叠ImageView,并根据指南根据宽度设置图像高度 我想实现以下几点(第一幅图):

Android ConstraintLayout:在工具栏上重叠ImageView,并根据指南根据宽度设置图像高度 我想实现以下几点(第一幅图):,android,android-layout,android-xml,android-constraintlayout,Android,Android Layout,Android Xml,Android Constraintlayout,工具栏高度必须为屏幕高度的35% ImageView的中心必须位于工具栏的底部(如图所示) ImageView的宽度必须为屏幕宽度的33% ImageView的比率必须为1:1(根据屏幕大小调整大小) 我的代码是: 请帮我找出问题所在 谢谢。如果您想支持多种屏幕尺寸,那么我认为您必须通过编程实现。我稍后再讨论原因 我的设备是小米A1,分辨率是1080:1920。所以长宽比是16:9。我将首先讨论此设备的解决方案 我们的目标是将ImageView的中心与guidelineToolbarHe

工具栏
高度必须为屏幕高度的35%

  • ImageView
    的中心必须位于
    工具栏的底部(如图所示)

  • ImageView
    的宽度必须为屏幕宽度的33%
  • ImageView
    的比率必须为1:1(根据屏幕大小调整大小)
  • 我的代码是:
    
    

    请帮我找出问题所在


    谢谢。

    如果您想支持多种屏幕尺寸,那么我认为您必须通过编程实现。我稍后再讨论原因

    我的设备是小米A1,分辨率是1080:1920。所以长宽比是16:9。我将首先讨论此设备的解决方案

    我们的目标是将
    ImageView
    的中心与
    guidelineToolbarHeight
    对齐,即屏幕高度的35%。现在,如果我们可以绘制另一条准则(
    guidelineImageTop
    )来设置与之对齐的
    ImageView
    的顶部,那么我们的问题就解决了。问题是,我们应该在屏幕高度的哪个百分比上绘制
    guidelineImageTop

    由于我们的
    ImageView
    s高度等于宽度,让我们从计算宽度开始

    width = 33% of 1080 = 356.4
    height = width = 356.4
    halfHeight = height/2 = 178.2
    
    我们的
    guidelineImageTop
    应该位于
    guidelineToolbarHeight
    上方的
    halfHeight

    guidelineToolbarHeights position in pixel = 35% of 1920 = 672
    guidelineImageTops position in pixel = 672 - 178.2 = 493.8
    Imagine, x% of 1920 = 493.8
    x = 25.7
    
    因此,我们的
    指南ImageTop
    应位于屏幕高度的25%。我对您的代码进行了如下编辑:

    <?xml version="1.0" encoding="utf-8"?>
    <android.support.constraint.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_width="match_parent"
    android:layout_height="match_parent"
    tools:context="me.mazid.test.MainActivity">
    
    <android.support.constraint.Guideline
        android:id="@+id/guidelineToolbarHeight"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        app:layout_constraintGuide_percent=".35" />
    
    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:background="@color/colorPrimary"
        android:theme="@style/ThemeOverlay.MyApp.ActionBar"
        app:layout_constraintBottom_toBottomOf="@id/guidelineToolbarHeight"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent">
    
    </android.support.v7.widget.Toolbar>
    
    <android.support.constraint.Guideline
        android:id="@+id/guidelineImageStart"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        app:layout_constraintGuide_percent=".33" />
    
    <android.support.constraint.Guideline
        android:id="@+id/guidelineImageEnd"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        app:layout_constraintGuide_percent=".66" />
    
    <android.support.constraint.Guideline
        android:id="@+id/guidelineImageTop"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        app:layout_constraintGuide_percent=".25" />
    
    <ImageView
        android:id="@+id/imageView"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:src="@drawable/avatar_diver"
        app:layout_constraintDimensionRatio="h,1:1"
        app:layout_constraintBottom_toBottomOf="@id/toolbar"
        app:layout_constraintLeft_toLeftOf="@id/guidelineImageStart"
        app:layout_constraintRight_toRightOf="@id/guidelineImageEnd"
        app:layout_constraintTop_toTopOf="@id/guidelineImageTop" />
    
    
    

    确认:

    • 如果以横向模式旋转设备,此解决方案将不起作用。因为纵横比会改变
    • 为了支持具有不同纵横比的多个设备,您可能需要计算设备高度的百分比,并以编程方式定位
      guidelineImageTop

    看起来您遇到的问题是尺寸比没有生效,因为图像视图的高度是
    0dp
    ,您将图像视图的顶部和底部约束到工具栏的底部,并强制高度为零。我想这应该行得通,但不行,所以这里有个解决办法

    在70%的高度处定义第二条水平基准线(请参见下面XML中的
    guidelineToolbarHeight2
    ),并将图像视图约束在父顶部(实际上是工具栏顶部)和此新基准线之间。这将正确地将图像放置在工具栏底部。我想其他一切都好

    [我不太喜欢的第二种选择是将图像视图的高度设置为较大的值,如
    10000dp
    。它只需要大于您期望的宽度。]

    
    
    下面是一个较短的版本,但结果相同:

    <android.support.constraint.ConstraintLayout 
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    
        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="0dp"
            android:layout_height="0dp"
            android:background="@color/colorPrimary"
            app:layout_constraintHeight_percent="0.35"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toTopOf="parent" />
    
        <ImageView
            android:id="@+id/imageView"
            android:layout_width="0dp"
            android:layout_height="0dp"
            android:src="@drawable/avatar_diver"
            app:layout_constraintBottom_toTopOf="@+id/guideline"
            app:layout_constraintDimensionRatio="H,1:1"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="@id/toolbar"
            app:layout_constraintWidth_percent="0.33" />
    
        <android.support.constraint.Guideline
            android:id="@+id/guideline"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            app:layout_constraintGuide_percent="0.70" />
    
    </android.support.constraint.ConstraintLayout>
    

    直接使用ConstraintLayout目前无法实现您想要实现的目标。您必须在Java代码中计算图像的最终目的地。请遵循以下代码:

    XML:

     <?xml version="1.0" encoding="utf-8"?>
    <android.support.constraint.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_width="match_parent"
        android:layout_height="match_parent">
    
        <android.support.constraint.Guideline
            android:id="@+id/guidelineToolbarHeight"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            app:layout_constraintGuide_percent=".35" />
    
        <android.support.constraint.Guideline
            android:id="@+id/guidelineToolbarHeight2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            app:layout_constraintGuide_percent=".35" />
    
        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="0dp"
            android:layout_height="0dp"
            android:background="@color/colorPrimary"
            app:layout_constraintBottom_toBottomOf="@id/guidelineToolbarHeight"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toTopOf="parent">
    
        </android.support.v7.widget.Toolbar>
    
        <android.support.constraint.Guideline
            android:id="@+id/guidelineImageStart"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            app:layout_constraintGuide_percent=".33" />
    
        <android.support.constraint.Guideline
            android:id="@+id/guidelineImageEnd"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            app:layout_constraintGuide_percent=".66" />
    
        <ImageView
            android:id="@+id/imageView"
            android:layout_width="0dp"
            android:layout_height="0dp"
            android:adjustViewBounds="false"
            android:cropToPadding="false"
            android:src="@mipmap/ic_launcher_round"
            app:layout_constraintBottom_toBottomOf="@id/toolbar"
            app:layout_constraintTop_toBottomOf="@id/guidelineToolbarHeight2"
            app:layout_constraintDimensionRatio="h,1:1"
            app:layout_constraintLeft_toLeftOf="@id/guidelineImageStart"
            app:layout_constraintRight_toRightOf="@id/guidelineImageEnd" />
    
    </android.support.constraint.ConstraintLayout>
    
    ConstraintLayout的“1.1.0-beta3”版本允许使用百分比尺寸和许多更酷的功能

    只需将“layout_ConstraintheRight_default”属性设置为“percent”(使用百分比单位),并使用“layout_ConstraintheRight_percent”设置百分比。(与宽度相关的属性也可用)

    这是解决办法

    <?xml version="1.0" encoding="utf-8"?>
    <android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    
        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="0dp"
            android:layout_height="0dp"
            android:background="@android:color/holo_blue_bright"
            app:layout_constraintHeight_default="percent"
            app:layout_constraintHeight_percent=".35"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />
    
        <Space
            android:id="@+id/space"
            android:layout_width="wrap_content"
            android:layout_height="200dp"
            app:layout_constraintTop_toBottomOf="@+id/toolbar"
            app:layout_constraintBottom_toBottomOf="@+id/toolbar" />
    
        <ImageView
            android:id="@+id/imageView"
            android:layout_width="0dp"
            android:layout_height="0dp"
            android:src="@mipmap/ic_launcher"
            app:layout_constraintBottom_toBottomOf="@+id/space"
            app:layout_constraintTop_toTopOf="@+id/space"
            app:layout_constraintDimensionRatio="1"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintWidth_default="percent"
            app:layout_constraintWidth_percent=".33" />
    
    </android.support.constraint.ConstraintLayout>
    
    
    
    正如您所看到的,我必须添加一个
    空格
    小部件,并将其高度设置为
    200dp
    ,因为现在百分比维度在居中到另一个小部件的边缘时会崩溃。

    以下是解决方案:

    <?xml version="1.0" encoding="utf-8"?>
    <android.support.constraint.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_width="match_parent"
        android:layout_height="match_parent">
    
        <View
            android:id="@+id/view"
            android:layout_width="0dp"
            android:layout_height="0dp"
            android:background="#019AE8"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintHeight_percent=".35"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintVertical_bias="0" />
    
        <android.support.constraint.Guideline
            android:id="@+id/guideline"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            app:layout_constraintGuide_percent=".70" />
    
        <ImageView
            android:layout_width="0dp"
            android:layout_height="0dp"
            app:layout_constraintBottom_toTopOf="@+id/guideline"
            app:layout_constraintDimensionRatio="w,1:1"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintWidth_percent=".33"
            tools:src="@drawable/ic_user" />
    
    </android.support.constraint.ConstraintLayout>
    
    
    

    我认为目前约束布局是不可能的(但我不确定)。当图像大小为“包裹内容”时,它是免费的,您可以将其移动到任何位置。但当图像为“匹配父对象”时,您无法将其自由移动到任何位置,它将与其父视图绑定。在您的情况下,图像是动态的,因此需要父对象来创建其大小。它将在工具栏下方或工具栏上方创建纵横比1:1。ImageView不知道它的高度。但是当它是wrap内容约束布局时,我知道关于imageview大小的所有信息,所以我认为只有WrapContent图像可以在您的情况下工作。但它让我@HasanAbdullah发布了您的新XML,从而得出了这个结果。您使用的是哪种版本的constraint layout?先生,我使用并获得了输出。仅供参考:在横向模式下,此代码可以正常工作。@HasanAbdullah您提供的PasteBin代码在我的设计器中的纵向和横向工作正常。您正在使用哪个版本的约束布局?另外,您的图像大小和类型(PNG等)@HasanAbdullah我敢打赌您使用的是
    ConstraintLayout
    的1.1.0-beta1。更新到1.1.0-beta3版本,布局将开始适合您。
    import android.os.Bundle;
    import android.support.constraint.ConstraintLayout;
    import android.support.constraint.Guideline;
    import android.support.v7.app.AppCompatActivity;
    import android.util.DisplayMetrics;
    import android.view.ViewTreeObserver;
    import android.widget.ImageView;
    
    public class MainActivity extends AppCompatActivity {
        private ImageView iv;
        private int imageHeight, screenHeight;
        private Guideline guideLine;
        private ConstraintLayout.LayoutParams params;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            iv = findViewById(R.id.imageView);
    
            guideLine = findViewById(R.id.guidelineToolbarHeight2);
            params = (ConstraintLayout.LayoutParams) guideLine.getLayoutParams();
    
            //Get Display Height
            DisplayMetrics displayMetrics = new DisplayMetrics();
            getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
            screenHeight = displayMetrics.heightPixels;
    
            //Get ImageView Current Height
            ViewTreeObserver vto = iv.getViewTreeObserver();
            vto.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
                public boolean onPreDraw() {
                    iv.getViewTreeObserver().removeOnPreDrawListener(this);
                    imageHeight = iv.getMeasuredHeight();
    
                    //getting screen height where guideline will be placed
                    float predictedGuidelinePlacementHeight = ((screenHeight * 35) / 100) - (imageHeight/2); // 35 is your guideline percentage for toolbar
    
                    //change guideline constraint percentage
                    params.guidePercent = ((predictedGuidelinePlacementHeight * 100) / screenHeight) / 100;
                    guideLine.setLayoutParams(params);
    
                    return true;
                }
            });
    
    
    
    
        }
    }
    
    <?xml version="1.0" encoding="utf-8"?>
    <android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    
        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="0dp"
            android:layout_height="0dp"
            android:background="@android:color/holo_blue_bright"
            app:layout_constraintHeight_default="percent"
            app:layout_constraintHeight_percent=".35"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />
    
        <Space
            android:id="@+id/space"
            android:layout_width="wrap_content"
            android:layout_height="200dp"
            app:layout_constraintTop_toBottomOf="@+id/toolbar"
            app:layout_constraintBottom_toBottomOf="@+id/toolbar" />
    
        <ImageView
            android:id="@+id/imageView"
            android:layout_width="0dp"
            android:layout_height="0dp"
            android:src="@mipmap/ic_launcher"
            app:layout_constraintBottom_toBottomOf="@+id/space"
            app:layout_constraintTop_toTopOf="@+id/space"
            app:layout_constraintDimensionRatio="1"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintWidth_default="percent"
            app:layout_constraintWidth_percent=".33" />
    
    </android.support.constraint.ConstraintLayout>
    
    <?xml version="1.0" encoding="utf-8"?>
    <android.support.constraint.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_width="match_parent"
        android:layout_height="match_parent">
    
        <View
            android:id="@+id/view"
            android:layout_width="0dp"
            android:layout_height="0dp"
            android:background="#019AE8"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintHeight_percent=".35"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintVertical_bias="0" />
    
        <android.support.constraint.Guideline
            android:id="@+id/guideline"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            app:layout_constraintGuide_percent=".70" />
    
        <ImageView
            android:layout_width="0dp"
            android:layout_height="0dp"
            app:layout_constraintBottom_toTopOf="@+id/guideline"
            app:layout_constraintDimensionRatio="w,1:1"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintWidth_percent=".33"
            tools:src="@drawable/ic_user" />
    
    </android.support.constraint.ConstraintLayout>