问题与ConstraintLayout - ImageView的16:9不合适的上边距

问题与ConstraintLayout - ImageView的16:9不合适的上边距

问题描述:

我想用ConstraintLayout构建布局如下:问题与ConstraintLayout - ImageView的16:9不合适的上边距

Mockup

我用这个源布局:

<?xml version="1.0" encoding="utf-8"?> 
<FrameLayout 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.constraint.ConstraintLayout 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:layout_gravity="center" 
     android:background="@color/colorAccent"> 

     <ImageView 
      android:id="@+id/imageView" 
      android:layout_width="0dp" 
      android:layout_height="0dp" 
      android:scaleType="centerCrop" 
      app:srcCompat="@android:color/darker_gray" 
      app:layout_constraintDimensionRatio="h,16:9" 
      app:layout_constraintTop_toTopOf="parent" 
      app:layout_constraintLeft_toLeftOf="parent" 
      app:layout_constraintRight_toRightOf="parent" 
      app:layout_constraintBottom_toTopOf="@+id/textView1" /> 

     <TextView 
      android:id="@+id/textView1" 
      android:layout_width="0dp" 
      android:layout_height="wrap_content" 
      android:layout_marginTop="24dp" 
      android:layout_marginLeft="16dp" 
      android:layout_marginRight="16dp" 
      android:text="Title" 
      android:textAppearance="@style/TextAppearance.AppCompat.Headline" 
      app:layout_constraintTop_toBottomOf="@+id/imageView" 
      app:layout_constraintLeft_toLeftOf="parent" 
      app:layout_constraintRight_toRightOf="parent" 
      app:layout_constraintBottom_toTopOf="@+id/textView2" /> 

     <TextView 
      android:id="@+id/textView2" 
      android:layout_width="0dp" 
      android:layout_height="wrap_content" 
      android:layout_marginTop="16dp" 
      android:layout_marginLeft="16dp" 
      android:layout_marginRight="16dp" 
      android:layout_marginBottom="24dp" 
      android:text="Subtle" 
      app:layout_constraintTop_toBottomOf="@+id/textView1" 
      app:layout_constraintLeft_toLeftOf="parent" 
      app:layout_constraintRight_toRightOf="parent" 
      app:layout_constraintBottom_toBottomOf="parent" /> 

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

不幸的是获得此结果:

Result view

正如你可以看到ImageView的顶部有一个不必要的边距,尽管布局显示marginTop = 0。

+0

你layout_gravity为中心。删除,你应该很好去 – NSimon

+0

@NSimon不,它没有帮助...看到这个截图https://www.dropbox.com/s/rftoxtk76jg3r6i/Screenshot_1507214820.png?dl=0 –

+0

删除这个:app:layout_constraintBottom_toTopOf =“@ + id/textView1” –

根据张贴在回答这个问题,并考虑到约束的布局V1.1.0答案和注释仍处于测试阶段,在这个时候最好的解决办法是使用app:layout_constraintVertical_chainStyle="packed"

<?xml version="1.0" encoding="utf-8"?> 
<FrameLayout 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.constraint.ConstraintLayout 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content"> 

     <ImageView 
      android:id="@+id/imageView" 
      android:layout_width="0dp" 
      android:layout_height="0dp" 
      android:scaleType="centerCrop" 
      app:srcCompat="@android:color/darker_gray" 
      app:layout_constraintDimensionRatio="h,16:9" 
      app:layout_constraintTop_toTopOf="parent" 
      app:layout_constraintLeft_toLeftOf="parent" 
      app:layout_constraintRight_toRightOf="parent" 
      app:layout_constraintBottom_toTopOf="@+id/textView1" 
      app:layout_constraintVertical_chainStyle="packed"/> 

     <TextView 
      android:id="@+id/textView1" 
      android:layout_width="0dp" 
      android:layout_height="wrap_content" 
      android:layout_marginTop="24dp" 
      android:layout_marginLeft="16dp" 
      android:layout_marginRight="16dp" 
      android:text="Title" 
      android:textAppearance="@style/TextAppearance.AppCompat.Headline" 
      app:layout_constraintTop_toBottomOf="@+id/imageView" 
      app:layout_constraintLeft_toLeftOf="parent" 
      app:layout_constraintRight_toRightOf="parent" 
      app:layout_constraintBottom_toTopOf="@+id/textView2" /> 

     <TextView 
      android:id="@+id/textView2" 
      android:layout_width="0dp" 
      android:layout_height="wrap_content" 
      android:layout_marginTop="16dp" 
      android:layout_marginLeft="16dp" 
      android:layout_marginRight="16dp" 
      android:layout_marginBottom="24dp" 
      android:text="Subtle" 
      app:layout_constraintTop_toBottomOf="@+id/textView1" 
      app:layout_constraintLeft_toLeftOf="parent" 
      app:layout_constraintRight_toRightOf="parent" 
      app:layout_constraintBottom_toBottomOf="parent" /> 

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

试试这个 - >我删除了app:layout_constraintBottom_toTopOf="@+id/textView1"ImageView它工作正常。

<?xml version="1.0" encoding="utf-8"?> 
<FrameLayout 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.constraint.ConstraintLayout 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:layout_gravity="center" 
     android:background="@color/colorAccent"> 

     <ImageView 
      android:id="@+id/imageView" 
      android:layout_width="0dp" 
      android:layout_height="0dp" 
      android:scaleType="centerCrop" 
      app:srcCompat="@android:color/darker_gray" 
      app:layout_constraintDimensionRatio="h,16:9" 
      app:layout_constraintTop_toTopOf="parent" 
      app:layout_constraintLeft_toLeftOf="parent" 
      app:layout_constraintRight_toRightOf="parent" /> 

     <TextView 
      android:id="@+id/textView1" 
      android:layout_width="0dp" 
      android:layout_height="wrap_content" 
      android:layout_marginTop="24dp" 
      android:layout_marginLeft="16dp" 
      android:layout_marginRight="16dp" 
      android:text="Title" 
      android:textAppearance="@style/TextAppearance.AppCompat.Headline" 
      app:layout_constraintTop_toBottomOf="@+id/imageView" 
      app:layout_constraintLeft_toLeftOf="parent" 
      app:layout_constraintRight_toRightOf="parent" 
      app:layout_constraintBottom_toTopOf="@+id/textView2" /> 

     <TextView 
      android:id="@+id/textView2" 
      android:layout_width="0dp" 
      android:layout_height="wrap_content" 
      android:layout_marginTop="16dp" 
      android:layout_marginLeft="16dp" 
      android:layout_marginRight="16dp" 
      android:layout_marginBottom="24dp" 
      android:text="Subtle" 
      app:layout_constraintTop_toBottomOf="@+id/textView1" 
      app:layout_constraintLeft_toLeftOf="parent" 
      app:layout_constraintRight_toRightOf="parent" 
      app:layout_constraintBottom_toBottomOf="parent" /> 

    </android.support.constraint.ConstraintLayout> 
</FrameLayout> 
+0

查看结果dropbox.com/s/tjw1raf224aaq6l/...。现在textView1和imageView之间的垂直距离约为40dp。 –

我需要摆脱这顶边距

对于这一点,只是从你的ImageView

+0

查看结果https://www.dropbox.com/s/tjw1raf224aaq6l/device-2017-10-05-185647%20copy.png?dl=0。现在textView1和imageView之间的垂直距离约为40dp。 –

前两个答案删除此行

app:layout_constraintBottom_toTopOf="@+id/textView1" 

会工作。如果您想维护垂直链,您还可以将app:layout_constraintVertical_chainStyle="spread_inside"添加到顶部ImageView

这里添加此声明后的图像

enter image description here

这里是XML(而不是其他任何变动。):

<FrameLayout 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.constraint.ConstraintLayout 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:layout_gravity="center" 
     android:background="@color/colorAccent"> 

     <ImageView 
      android:id="@+id/imageView" 
      android:layout_width="0dp" 
      android:layout_height="0dp" 
      android:scaleType="centerCrop" 
      app:srcCompat="@android:color/darker_gray" 
      app:layout_constraintDimensionRatio="h,16:9" 
      app:layout_constraintTop_toTopOf="parent" 
      app:layout_constraintLeft_toLeftOf="parent" 
      app:layout_constraintRight_toRightOf="parent" 
      app:layout_constraintVertical_chainStyle="spread_inside" 
      app:layout_constraintBottom_toTopOf="@+id/textView1" /> 

     <TextView 
      android:id="@+id/textView1" 
      android:layout_width="0dp" 
      android:layout_height="wrap_content" 
      android:layout_marginTop="24dp" 
      android:layout_marginLeft="16dp" 
      android:layout_marginRight="16dp" 
      android:text="Title" 
      android:textAppearance="@style/TextAppearance.AppCompat.Headline" 
      app:layout_constraintTop_toBottomOf="@+id/imageView" 
      app:layout_constraintLeft_toLeftOf="parent" 
      app:layout_constraintRight_toRightOf="parent" 
      app:layout_constraintBottom_toTopOf="@+id/textView2" /> 

     <TextView 
      android:id="@+id/textView2" 
      android:layout_width="0dp" 
      android:layout_height="wrap_content" 
      android:layout_marginTop="16dp" 
      android:layout_marginLeft="16dp" 
      android:layout_marginRight="16dp" 
      android:layout_marginBottom="24dp" 
      android:text="Subtle" 
      app:layout_constraintTop_toBottomOf="@+id/textView1" 
      app:layout_constraintLeft_toLeftOf="parent" 
      app:layout_constraintRight_toRightOf="parent" 
      app:layout_constraintBottom_toBottomOf="parent" /> 

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

更新:所以上面没有按” t使用ConstraintLayout版本1.0.2在API 23上工作。请尝试改为:

textView2中删除android:layout_marginTop="16dp"并将android:layout_marginBottom="16dp"添加到textView1。这有所作为。

+0

前两个答案不起作用,我得到textView1和imageView之间的距离为40dp https://www.dropbox.com/s/tjw1raf224aaq6l/device-2017-10-05-185647%20copy.png?dl=0 。使用“spread_inside”,textView1和textView2之间没有垂直边距。看到这个截图https://www.dropbox.com/s/59nixtlhnah44j7/device-2017-10-05-190906.png?dl=0。 –

+0

@EugeneBrusov查看更新的答案。 – Cheticamp

+0

只需复制/粘贴源代码,并在API 23上运行的Nexus 5模拟器上获得这些结果,并在API 23上运行的真实Nexus 5上获得相同的结果https://www.dropbox.com/s/x48wk7sgk4ma6d5/Screenshot_1507223903.png? DL = 0。正如你现在所看到的,textView1和textView2之间没有空间。 –

的它的要点是使用一个垂直偏差为0的包装链,这样链条的内容将位于最上面。另外,我不确定你为什么使用FrameLayout - 你可能不需要。

enter image description here

随着1.1.0-β2:

<?xml version="1.0" encoding="utf-8"?> 
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:background="@color/colorAccent" 
    xmlns:app="http://schemas.android.com/apk/res-auto"> 

    <ImageView 
     android:id="@+id/imageView" 
     android:layout_width="0dp" 
     android:layout_height="0dp" 
     android:scaleType="centerCrop" 
     app:layout_constraintBottom_toTopOf="@+id/textView1" 
     app:layout_constraintDimensionRatio="h,16:9" 
     app:layout_constraintVertical_bias="0.0" 
     app:layout_constraintLeft_toLeftOf="parent" 
     app:layout_constraintRight_toRightOf="parent" 
     app:layout_constraintTop_toTopOf="parent" 
     app:layout_constraintVertical_chainStyle="packed" 
     app:srcCompat="@android:color/darker_gray" /> 

    <TextView 
     android:id="@+id/textView1" 
     android:layout_width="0dp" 
     android:layout_height="wrap_content" 
     android:layout_marginTop="24dp" 
     android:layout_marginLeft="16dp" 
     android:layout_marginRight="16dp" 
     android:text="Title" 
     android:textAppearance="@style/TextAppearance.AppCompat.Headline" 
     app:layout_constraintTop_toBottomOf="@+id/imageView" 
     app:layout_constraintLeft_toLeftOf="parent" 
     app:layout_constraintRight_toRightOf="parent" 
     app:layout_constraintBottom_toTopOf="@+id/textView2" /> 

    <TextView 
     android:id="@+id/textView2" 
     android:layout_width="0dp" 
     android:layout_height="wrap_content" 
     android:layout_marginTop="16dp" 
     android:layout_marginLeft="16dp" 
     android:layout_marginRight="16dp" 
     android:layout_marginBottom="24dp" 
     android:text="Subtle" 
     app:layout_constraintTop_toBottomOf="@+id/textView1" 
     app:layout_constraintLeft_toLeftOf="parent" 
     app:layout_constraintRight_toRightOf="parent" 
     app:layout_constraintBottom_toBottomOf="parent" /> 

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

感谢您的回答!是的,即使使用constraint-layout v1.0.2,打包链也会修复所请求布局中的所有垂直边距。我使用FrameLayout仅用于测试目的,因为我想查看ConstraintLayout封装内容的方式。例如,我可以使用带'layout_height =“wrap_content”'的ConstraintLayout作为RecyclerView项目。 –