英文:
Android studio, Java: Cannot change horizontal margin at run time (ConstraintSet.LEFT)
问题
如标题所示,我通常在运行时使用ConstraintSet来更改按钮或布局的位置,我有一个长的代码,在那个代码中它起作用,但是我在同一项目上再次尝试,以及在一个测试项目中(如下),我能够改变的只有垂直边距。因为某种奇怪的原因,水平边距被忽略了。特别是这一行:
set.connect(testLayout.getId(), ConstraintSet.LEFT, rootLayout.getId(),ConstraintSet.LEFT, 100);
如果两者都不起作用,我可能会考虑可能是我把它放错了地方之类的,但不,一个有效,另一个无效,唯一的区别是一个使用了TOP,另一个使用了LEFT,实际上没有出错的余地。那是什么原因?这里是测试运行的代码,我尝试了一个在XML中设计的,一个以编程方式设计的,对于LEFT的情况都不起作用:
主要部分
```java
package com.example.cusom_buttom_test1;
import androidx.appcompat.app.AppCompatActivity;
import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.constraintlayout.widget.ConstraintSet;
import android.graphics.Color;
import android.os.Bundle;
import android.view.View;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//XML中的对象
ConstraintLayout rootLayout = findViewById(R.id.rootLayout);
ConstraintLayout testLayout = findViewById(R.id.relativeLayout_test);
//设置testLayout的位置
ConstraintSet set = new ConstraintSet();
set.clone(rootLayout);
set.connect(testLayout.getId(), ConstraintSet.TOP, rootLayout.getId(), ConstraintSet.TOP, 500);
set.connect(testLayout.getId(), ConstraintSet.LEFT, rootLayout.getId(), ConstraintSet.LEFT, 100);
set.applyTo(rootLayout);
//创建新的ConstraintLayout
ConstraintLayout testLayout2 = new ConstraintLayout(this);
testLayout2.setId(View.generateViewId());
testLayout2.setBackgroundColor(Color.GREEN);
rootLayout.addView(testLayout2);
//设置大小
testLayout2.getLayoutParams().height = 200;
testLayout2.getLayoutParams().width = 200;
//设置位置
ConstraintSet set2 = new ConstraintSet();
set2.clone(rootLayout);
set2.connect(testLayout2.getId(), ConstraintSet.TOP, rootLayout.getId(), ConstraintSet.TOP, 100);
set2.connect(testLayout.getId(), ConstraintSet.LEFT, rootLayout.getId(), ConstraintSet.LEFT, 300);
set2.applyTo(rootLayout);
}
}
XML部分
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.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:id="@+id/rootLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/relativeLayout_test"
android:layout_width="222dp"
android:layout_height="230dp"
android:background="#DD1515"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
<details>
<summary>英文:</summary>
As the title says, I normally use ConstraintSet to change location of a button or layout at run time, and I have a long code where it works, but I tried again on the same project, and again in a test project (below) and all I could ever change was the vertical margin. For some bizarre reason the horizontal margin is ignored. This line specifically:
set.connect(testLayout.getId(), ConstraintSet.LEFT, rootLayout.getId(),ConstraintSet.LEFT, 100);
If it was both of them that didn't work I would consider that maybe I put it in the wrong place or something, but no, one works the other doesn't, and the only difference is one has TOP and one has LEFT, there is literally no room for error. So what gives? Here is the code of the test run, I tried one designed in xml and one designed programmatically, neither work for the LEFT case:
Main
package com.example.cusom_buttom_test1;
import androidx.appcompat.app.AppCompatActivity;
import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.constraintlayout.widget.ConstraintSet;
import android.graphics.Color;
import android.os.Bundle;
import android.view.View;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//XML OBJECTS
ConstraintLayout rootLayout = findViewById(R.id.rootLayout);
ConstraintLayout testLayout = findViewById(R.id.relativeLayout_test);
//SET LOCATION OF testLayout
ConstraintSet set = new ConstraintSet();
set.clone(rootLayout);
set.connect(testLayout.getId(), ConstraintSet.TOP, rootLayout.getId(),ConstraintSet.TOP, 500);
set.connect(testLayout.getId(), ConstraintSet.LEFT, rootLayout.getId(),ConstraintSet.LEFT, 100);
set.applyTo(rootLayout);
//CREATE NEW CONSTRAINT LAYOUT
ConstraintLayout testLayout2 = new ConstraintLayout(this);
testLayout2.setId(View.generateViewId());
testLayout2.setBackgroundColor(Color.GREEN);
rootLayout.addView(testLayout2);
//SET SIZE
testLayout2.getLayoutParams().height = 200;
testLayout2.getLayoutParams().width = 200;
//SET LOCATION
ConstraintSet set2 = new ConstraintSet();
set2.clone(rootLayout);
set2.connect(testLayout2.getId(), ConstraintSet.TOP, rootLayout.getId(), ConstraintSet.TOP, 100);
set2.connect(testLayout.getId(), ConstraintSet.LEFT, rootLayout.getId(), ConstraintSet.LEFT, 300);
set2.applyTo(rootLayout);
}
}
XML
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.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:id="@+id/rootLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/relativeLayout_test"
android:layout_width="222dp"
android:layout_height="230dp"
android:background="#DD1515"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
</details>
# 答案1
**得分**: 0
找到两个可行的解决方案,而不是使用ConstraintSet,可以使用animate或MarginLayoutParams。
```java
testLayout.animate().x(300).y(700).setDuration(0).start();
testLayout.animate().x(300).y(700).setDuration(0).start();
ViewGroup.MarginLayoutParams margins = (ViewGroup.MarginLayoutParams) testLayout.getLayoutParams();
margins.topMargin = 100;
margins.leftMargin = 200;
英文:
Found two answers that work, instead of using ConstraintSet, use either animate or MarginLayoutParams.
testLayout.animate().x(300).y(700).setDuration(0).start();
testLayout.animate().x(300).y(700).setDuration(0).start();
ViewGroup.MarginLayoutParams margins = (ViewGroup.MarginLayoutParams) testLayout.getLayoutParams();
margins.topMargin = 100;
margins.leftMargin = 200;
专注分享java语言的经验与见解,让所有开发者获益!
评论