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>