当我更改元素的 id 时,通过 ConstraintSet 以编程方式添加障碍不起作用?
Adding barriers programmatically via ConstraintSet doesn't work when I change id's of elements?
我一直在尝试使用 ConstraintSet 以编程方式向 Android Studio 中的约束布局添加障碍,但我无法让我的代码正常工作,最终结果应该只是一个 textView,然后它右侧的屏障,以及从屏障右侧开始的另一个文本视图。我正在使用 ConstraintSet.createBarrier 方法添加障碍,这就是应用程序中的结果:
“TextView1”“TextView2”
也就是说,textView2 从textView1 的末尾开始,不管textView1 有多长。这是 activity_main.xml:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/content"
xmlns:app="http://schemas.android.com/apk/res-auto">
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView 1"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
这是我在 MainActivity.java 中的代码:
package com.example.test_application;
import android.annotation.SuppressLint;
import android.os.Build;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.TextView;
import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AppCompatActivity;
import androidx.constraintlayout.widget.Barrier;
import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.constraintlayout.widget.ConstraintSet;
public class MainActivity extends AppCompatActivity {
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR1)
@SuppressLint("ResourceType")
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
LayoutInflater inflater = getLayoutInflater();
ConstraintLayout myConstraintLayout = (ConstraintLayout) findViewById(R.id.content);
View textView1 = findViewById(R.id.textView1);
textView1.setId(1);
TextView textView2 = new TextView(this);
textView2.setId(2);
textView2.setText("HELLO");
myConstraintLayout.addView(textView2);
ConstraintSet constraintSet = new ConstraintSet();
constraintSet.clone(myConstraintLayout);
int[] createBarrier_ids = {textView1.getId()};
constraintSet.createBarrier(3, Barrier.END,0, createBarrier_ids);
constraintSet.connect(textView2.getId(), ConstraintSet.START, 3, ConstraintSet.END,0);
constraintSet.connect(textView2.getId(), ConstraintSet.TOP, textView1.getId(), ConstraintSet.TOP,0);
constraintSet.applyTo(myConstraintLayout);
}
}
这是我运行时的结果:
请注意,在 textView1.setId(1)
行中,我如何将 textView1 的 ID 更改为 1(我也尝试使用 textView1.setId(View.generateViewId())
更改 ID 并得到相同的结果),当我禁用它时行,不要再次更改 textView1 的 ID 和 运行 代码,我得到了我想要的结果:
我做错了什么?为什么当我不更改 id 时它会起作用?我希望能够在我的代码中更改 ID。
我相信 ConstraintLayout 除了视图层次结构本身之外,还维护内部视图相关结构。当您更改 textView1
的 ID 时,该 ID 不会传播到这些其他内部结构。 (一个猜测,但我相信这是一个很好的。)
如果您必须更改视图的 id,我建议您将其从层次结构中删除并重新添加。这将强制 ConstraintLayout 接受您对其结构的更改。像这样:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
LayoutInflater inflater = getLayoutInflater();
ConstraintLayout myConstraintLayout = (ConstraintLayout) findViewById(R.id.content);
View textView1 = findViewById(R.id.textView1);
myConstraintLayout.removeView(textView1); // So long old textView1!
textView1.setId(1);
myConstraintLayout.addView(textView1); // Hello new textView1.
TextView textView2 = new TextView(this);
textView2.setId(2);
textView2.setText("HELLO");
myConstraintLayout.addView(textView2);
ConstraintSet constraintSet = new ConstraintSet();
constraintSet.clone(myConstraintLayout);
// Make sure to reconnect textView1 since it was added earlier.
constraintSet.connect(textView1.getId(),ConstraintSet.START,ConstraintSet.PARENT_ID,ConstraintSet.START);
constraintSet.connect(textView1.getId(),ConstraintSet.TOP,ConstraintSet.PARENT_ID,ConstraintSet.TOP);
int[] createBarrier_ids = {textView1.getId()};
constraintSet.createBarrier(3, Barrier.END,0, createBarrier_ids);
constraintSet.connect(textView2.getId(), ConstraintSet.START, 3, ConstraintSet.END,0);
constraintSet.connect(textView2.getId(), ConstraintSet.TOP, textView1.getId(), ConstraintSet.TOP,0);
constraintSet.applyTo(myConstraintLayout);
}
我一直在尝试使用 ConstraintSet 以编程方式向 Android Studio 中的约束布局添加障碍,但我无法让我的代码正常工作,最终结果应该只是一个 textView,然后它右侧的屏障,以及从屏障右侧开始的另一个文本视图。我正在使用 ConstraintSet.createBarrier 方法添加障碍,这就是应用程序中的结果:
“TextView1”“TextView2”
也就是说,textView2 从textView1 的末尾开始,不管textView1 有多长。这是 activity_main.xml:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/content"
xmlns:app="http://schemas.android.com/apk/res-auto">
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView 1"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
这是我在 MainActivity.java 中的代码:
package com.example.test_application;
import android.annotation.SuppressLint;
import android.os.Build;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.TextView;
import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AppCompatActivity;
import androidx.constraintlayout.widget.Barrier;
import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.constraintlayout.widget.ConstraintSet;
public class MainActivity extends AppCompatActivity {
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR1)
@SuppressLint("ResourceType")
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
LayoutInflater inflater = getLayoutInflater();
ConstraintLayout myConstraintLayout = (ConstraintLayout) findViewById(R.id.content);
View textView1 = findViewById(R.id.textView1);
textView1.setId(1);
TextView textView2 = new TextView(this);
textView2.setId(2);
textView2.setText("HELLO");
myConstraintLayout.addView(textView2);
ConstraintSet constraintSet = new ConstraintSet();
constraintSet.clone(myConstraintLayout);
int[] createBarrier_ids = {textView1.getId()};
constraintSet.createBarrier(3, Barrier.END,0, createBarrier_ids);
constraintSet.connect(textView2.getId(), ConstraintSet.START, 3, ConstraintSet.END,0);
constraintSet.connect(textView2.getId(), ConstraintSet.TOP, textView1.getId(), ConstraintSet.TOP,0);
constraintSet.applyTo(myConstraintLayout);
}
}
这是我运行时的结果:
请注意,在 textView1.setId(1)
行中,我如何将 textView1 的 ID 更改为 1(我也尝试使用 textView1.setId(View.generateViewId())
更改 ID 并得到相同的结果),当我禁用它时行,不要再次更改 textView1 的 ID 和 运行 代码,我得到了我想要的结果:
我做错了什么?为什么当我不更改 id 时它会起作用?我希望能够在我的代码中更改 ID。
我相信 ConstraintLayout 除了视图层次结构本身之外,还维护内部视图相关结构。当您更改 textView1
的 ID 时,该 ID 不会传播到这些其他内部结构。 (一个猜测,但我相信这是一个很好的。)
如果您必须更改视图的 id,我建议您将其从层次结构中删除并重新添加。这将强制 ConstraintLayout 接受您对其结构的更改。像这样:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
LayoutInflater inflater = getLayoutInflater();
ConstraintLayout myConstraintLayout = (ConstraintLayout) findViewById(R.id.content);
View textView1 = findViewById(R.id.textView1);
myConstraintLayout.removeView(textView1); // So long old textView1!
textView1.setId(1);
myConstraintLayout.addView(textView1); // Hello new textView1.
TextView textView2 = new TextView(this);
textView2.setId(2);
textView2.setText("HELLO");
myConstraintLayout.addView(textView2);
ConstraintSet constraintSet = new ConstraintSet();
constraintSet.clone(myConstraintLayout);
// Make sure to reconnect textView1 since it was added earlier.
constraintSet.connect(textView1.getId(),ConstraintSet.START,ConstraintSet.PARENT_ID,ConstraintSet.START);
constraintSet.connect(textView1.getId(),ConstraintSet.TOP,ConstraintSet.PARENT_ID,ConstraintSet.TOP);
int[] createBarrier_ids = {textView1.getId()};
constraintSet.createBarrier(3, Barrier.END,0, createBarrier_ids);
constraintSet.connect(textView2.getId(), ConstraintSet.START, 3, ConstraintSet.END,0);
constraintSet.connect(textView2.getId(), ConstraintSet.TOP, textView1.getId(), ConstraintSet.TOP,0);
constraintSet.applyTo(myConstraintLayout);
}