如何在ConstraintLayout中以编程方式将视图约束到其父布局?

3

我想使用约束布局程序化地创建一个TextView(或任何其他视图)。这个textView在XML中看起来像这样:

<TextView
    android:id="@+id/textView_Test"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Test "
    android:textSize="19sp"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintVertical_bias="0.16"
    app:layout_constraintHorizontal_bias="0.02"
    app:layout_constraintTop_toTopOf="parent" />

所以它应该在所有方面都受到父级的限制,然后我可以使用偏置参数来动态更改它的位置。我该如何实现这一点?我查看了这里给出的答案 ConstraintLayout: change constraints programmatically 但是那里的对象没有受到父级的限制,并且没有使用垂直和水平偏差来实现我想要的动态定位。有什么想法能否在Fragment中实现这个功能(我使用Single-Activity Multiple-Fragments方法)?
更新: 我现在可以在约束布局中编程方式地插入自定义视图(而不是TextView)。但是,使用代码 constraintSet.setHorizontalBias(view.getId(), 0.56f); 来设置方向没有任何效果(无论使用哪些数字)。自定义视图始终位于左上角。
这里可以看到整个片段的代码(我标注了重要部分):
public class Test extends Fragment implements Runnable {

    /*
    Game variables
     */

    public static final int DELAY_MILLIS = 100;
    public static final int TIME_OF_A_LEVEL_IN_SECONDS = 90;
    private int currentTimeLeftInTheLevel_MILLIS;
    private Handler handler = new Handler();
    private FragmentGameBinding binding;

    private boolean viewHasBeenCreated = false;


    public Test() {
        // Required empty public constructor
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        binding = FragmentGameBinding.inflate(inflater, container, false);
        container.getContext();
        viewHasBeenCreated = true;
        startRound();
        return binding.getRoot();


    }

    public void startRound () {
        currentTimeLeftInTheLevel_MILLIS =TIME_OF_A_LEVEL_IN_SECONDS * 1000;
        updateScreen();
        handler.postDelayed(this, 1000);

    }
    private void updateScreen() {
        binding.textViewTimeLeftValue.setText("" + currentTimeLeftInTheLevel_MILLIS/1000);

        /*
        IMPORTANT PART: This should create a simple custom UI element
         */
        View view = new View(getActivity());
        view.setLayoutParams(new ViewGroup.LayoutParams(200, 200));
        Drawable dr = ContextCompat.getDrawable(getActivity(),R.drawable.light_bulb_layer_list);
        view.setBackground(dr);
        view.setId(View.generateViewId());

        ConstraintLayout constraintLayout = binding.constraintLayout;
        ConstraintSet constraintSet = new ConstraintSet();
        constraintSet.clone(constraintLayout);
        constraintSet.connect(view.getId(),ConstraintSet.BOTTOM, ConstraintSet.PARENT_ID,ConstraintSet.BOTTOM,0);
        constraintSet.connect(view.getId(),ConstraintSet.TOP,ConstraintSet.PARENT_ID ,ConstraintSet.TOP,0);
        constraintSet.connect(view.getId(),ConstraintSet.LEFT,ConstraintSet.PARENT_ID ,ConstraintSet.LEFT,0);
        constraintSet.connect(view.getId(),ConstraintSet.RIGHT,ConstraintSet.PARENT_ID ,ConstraintSet.RIGHT,0);
        constraintSet.setHorizontalBias(view.getId(), 0.56f);
        constraintSet.setVerticalBias(view.getId(), 0.5f);
        constraintSet.applyTo(constraintLayout);
        constraintLayout.addView(view);
    }

    private void countDownTime(){
        currentTimeLeftInTheLevel_MILLIS = currentTimeLeftInTheLevel_MILLIS -DELAY_MILLIS;
        updateScreen();
    }

    @Override
    public void run() {
        if(viewHasBeenCreated) {
            countDownTime();
        }

有没有想法,为什么在约束布局中设置水平或垂直方向时没有任何效果?


在克隆约束之前必须先添加视图。 - Cheticamp
@Cheticamp:感谢您的回答。当我在constraintLayout.addView(view);之后非常末尾设置constraintSet.clone(constraintLayout);时,什么也没有改变。自定义视图位于左上角,并且在约束布局中设置水平或垂直方向仍然没有任何效果。我还尝试了设置constraintSet.applyTo(constraintLayout);并更改了一些语句的顺序。要么什么都不会发生(更改方向没有任何效果),要么自定义视图覆盖整个显示屏。 - VanessaF
1
你发布的代码没问题。你只需要将 addView() 移动到克隆之前。你希望添加的视图 ID 被约束集知道。 - Cheticamp
非常感谢Cheticamp提供的巨大帮助,我真的非常感激。 - VanessaF
1个回答

2
从文档中可以看出,在ConstraintSet中有一个PARENT_ID用作约束的ID。
同时,还需要设置setHorizontalBiassetVerticalBias方法。
你引用的slashdot问题的被接受的答案展示了如何使用ConstraintSet

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接