ConstraintSet
看起来很难应对Start/End
约束。
此示例摘自 Google示例。 Github:android-ConstraintLayoutExamples
当您替换Left&正确约束Start
& End
,ConstraintSet - 无法正常工作,仅适用于Left/Right
约束。
例如替换
layout_constraintStart_toStartOf with layout_constraintLeft_toLeftOf&更换
layout_constraintEnd_toEndOf with layout_constraintRight_toRightOf
以下文件:
constraintset_example_main.xml
constraintset_example_big.xml
onClick of image:
private ConstraintSet mConstraintSetNormal = new ConstraintSet();
private ConstraintSet mConstraintSetBig = new ConstraintSet();
public void toggleMode(View v) {
TransitionManager.beginDelayedTransition(mRootLayout);
mShowBigImage = !mShowBigImage;
applyConfig();
}
private void applyConfig() {
if (mShowBigImage) {
mConstraintSetBig.applyTo(mRootLayout);
} else {
mConstraintSetNormal.applyTo(mRootLayout);
}
}
默认情况下,Android工作室使用start
/ end
约束,因此我想了解根本原因和可能的修复方法。
或者这是ConstrainSet
本身的错误吗?
答案 0 :(得分:4)
这看起来像ConstraintSet
的问题,但让我们看看。以下分析基于sample project
以及您提供的链接。
在示例项目中,我已将ConstraintLayout
更新为最新版本:
compile 'com.android.support.constraint:constraint-layout:1.1.0-beta5'
我是这样做的,以防我们试图追查已经解决过的问题。我还更新了布局constraintset_example_big
并用开始/结束约束替换了所有左/右约束,如下所示:
<强> constraintset_example_big.xml 强>
<android.support.constraint.ConstraintLayout
android:id="@+id/activity_constraintset_example"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<ImageView
android:id="@+id/imageView"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginEnd="24dp"
android:layout_marginStart="24dp"
android:layout_marginTop="24dp"
android:onClick="toggleMode"
android:scaleType="centerCrop"
android:src="@drawable/lake"
app:layout_constraintDimensionRatio="h,16:9"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:contentDescription="@string/lake_tahoe_image" />
<TextView
android:id="@+id/textView9"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/lake_tahoe_title"
android:textSize="30sp"
app:layout_constraintStart_toStartOf="@+id/imageView"
android:layout_marginTop="8dp"
app:layout_constraintTop_toBottomOf="@+id/imageView" />
<TextView
android:id="@+id/textView11"
android:layout_width="0dp"
android:layout_height="0dp"
android:text="@string/lake_discription"
app:layout_constraintStart_toStartOf="@+id/textView9"
android:layout_marginTop="8dp"
app:layout_constraintTop_toBottomOf="@+id/textView9"
app:layout_constraintEnd_toEndOf="@+id/imageView"
app:layout_constraintBottom_toBottomOf="parent"
android:layout_marginBottom="16dp"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintVertical_bias="0.0" />
</android.support.constraint.ConstraintLayout>
有了这些变化,这就是我们所看到的。
这显然不对。转换后它应该看起来像this
。
经过一些调试后,我在ConstraintSetExampleActivity.java
:
mConstraintSetBig.load(this, R.layout.constraintset_example_big);
ConstraintSet#load()
似乎很简单,但是如果我们用布局的显式膨胀替换上面的代码,然后在膨胀的布局上克隆ConstraintSet
,如下所示:
// mConstraintSetBig.load(this, R.layout.constraintset_example_big);
ConstraintLayout cl = (ConstraintLayout) getLayoutInflater().inflate(R.layout.constraintset_example_big,null);
mConstraintSetBig.clone(cl);
我们在应用中看到这种行为要好得多。
所以我的看法是ConstraintSet#load()
在开始/结束约束方面存在问题。解决方法是膨胀ConstraintLayout
然后进行克隆。
<强> ConstraintSetExampleActivity#的onCreate()强>
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.constraintset_example_main);
mRootLayout = (ConstraintLayout) findViewById(R.id.activity_constraintset_example);
// Note that this can also be achieved by calling
// `mConstraintSetNormal.load(this, R.layout.constraintset_example_main);`
// Since we already have an inflated ConstraintLayout in `mRootLayout`, clone() is
// faster and considered the best practice.
mConstraintSetNormal.clone(mRootLayout);
// Load the constraints from the layout where ImageView is enlarged.
// Toggle the comment status on the following three lines to fix/break.
// mConstraintSetBig.load(this, R.layout.constraintset_example_big);
ConstraintLayout cl = (ConstraintLayout) getLayoutInflater().inflate(R.layout.constraintset_example_big,null);
mConstraintSetBig.clone(cl);
if (savedInstanceState != null) {
boolean previous = savedInstanceState.getBoolean(SHOW_BIG_IMAGE);
if (previous != mShowBigImage) {
mShowBigImage = previous;
applyConfig();
}
}
}
答案 1 :(得分:1)
此问题已知,将在1.1 beta 6版本中修复
答案 2 :(得分:0)
对于那些面临约束集克隆等问题无法正常工作的人,我在api调用后调用clone和applyTo方法时,布局没有更新为新约束,这是由于更改之前显示的加载对话框导致了错误。