VanessaF
VanessaF

Reputation: 793

How to contrain a view programmatically to parent in ConstraintLayout

I would like to create a TextView (or any other view) programatically using the constraint layout. The textView would look like this in 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" />

So it should be constrained to the parents in all sides and then I can use the bias parameters to change its position dynamically. How can I implement this? I had a look at the answers given here ConstraintLayout: change constraints programmatically but there the objects are not constrained to the parents and no vertical and horizontal bias is used to position it dynamically as I am intending. Any idea if and how this would be possible within a Fragment (I use the Single-Activity Multiple-Fragments approach)?

Update: I could now insert a custom view (instead of a TextView) inside a constrained layout programmatically. However, setting the orientation using the code constraintSet.setHorizontalBias(view.getId(), 0.56f);does not have any effect (no mather, which numbers I use). The custom view is always at the top left corner.

Here you can see the code of the whole fragment(I denoted the important part):

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();
        }

Any ideas why setting the horizontal or vertical orientation in the constraint layout does not have any effect?

Upvotes: 3

Views: 5750

Answers (1)

Andrew
Andrew

Reputation: 10222

From the docs there is a PARENT_ID in the ConstraintSet to use as the ID of constraints.

Also set setHorizontalBias and setVerticalBias methods as well.

The accepted answer of you referenced slashdot question shows you how to use a ConstraintSet

Upvotes: 2

Related Questions