1

我一直在尝试使用 ConstraintSet 以编程方式向 Android Studio 中的约束布局添加障碍,但我无法让我的代码正常工作,最终结果应该只是一个 textView,然后是右侧的障碍,以及另一个 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);
    }
}

这是我运行它时的结果:

结果改变id

请注意,当我禁用该行并且不更改 textView1 的 id 并再次运行代码时,我如何textView1.setId(1)将 textView1 的 id 更改为 1(我也尝试使用更改 id并获得相同的结果)textView1.setId(View.generateViewId())我得到了我想要的结果:

结果不改变id

我究竟做错了什么?为什么我不更改ID时它会起作用?我希望能够在我的代码中更改 id。

4

1 回答 1

1

我相信除了视图层次结构本身之外, ConstraintLayout还维护与视图相关的内部结构。当您更改 的 id 时textView1,该 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);
}
于 2021-10-21T20:31:51.450 回答