Views are truncated when trying to add them at the same row using ConstraintLayout

53 views Asked by At

I'm trying to create my own multi button "custom view" that get it's attributes from an xml file. When trying to create a custom view with more than 3 button, some button are truncated (please see screenshot attached). Maybe someone encounter an issue like that (maybe the problem related to wrong use of ConstraintLayout "Packed Chain" style). Please notice that i have a Boolean parameter named "reversedOrder" in order to support some language that are written from RTL My Programmatic code is:

  public class MultiButton extends ConstraintLayout
{
    public static final int MAX_NUMBER_OF_BUTTONS = 5;
    @StyleableRes
    private int indexNumOfButtons = 0;

    @StyleableRes
    private int indexOfOrder = 1;

    @StyleableRes
    private int indexOfActiveButtonIndex = 2;

    @StyleableRes
    private int indexOfBackgroundSelectorResource = 3;

    @StyleableRes
    private int indexOfTextcolorSelectorResource = 4;

    private int numOfButtons;
    private int activeButtonIndex;


    private boolean reversedOrder;

    private Button[] allButtons;
    private View.OnClickListener[] additionalOnClickListeners;


    public MultiButton(Context context, AttributeSet attrs )
    {
        super(context,attrs);
        init(context,attrs);
    }

    private void init(Context context, AttributeSet attrs)
    {
        int[] sets = {R.attr.numOfButtons, R.attr.reversedOrder, R.attr.activeButtonIndex,R.attr.backgroundSelector,R.attr.textColorSelector};
        TypedArray typedArray = context.obtainStyledAttributes(attrs, sets);
        numOfButtons = typedArray.getInt(indexNumOfButtons,1);

        if (numOfButtons < 0)
        {
            numOfButtons = 1;
        }
        else if (numOfButtons > MAX_NUMBER_OF_BUTTONS)
        {
            numOfButtons = MAX_NUMBER_OF_BUTTONS;
        }

        allButtons = new Button[numOfButtons];
        int height = getHeight();
        for (int i =0; i<numOfButtons; i++)
        {
            allButtons[i] = new Button(context);
            allButtons[i].setText("" +i);
            allButtons[i].setHeight(height);
            allButtons[i].setWidth(0);
        }

        additionalOnClickListeners = new View.OnClickListener[numOfButtons];

        int backgroundSelectorResourceId = typedArray.getResourceId(indexOfBackgroundSelectorResource,0); //context.getResources().getDrawable(R.drawable.btn);
        int textColorSelectorResourceId = typedArray.getResourceId(indexOfTextcolorSelectorResource,0);

        reversedOrder = typedArray.getBoolean(indexOfOrder,false);
        for (int i=0; i< numOfButtons;  i++)
        {
            int currentIndex = reversedOrder ?  (numOfButtons-i-1) : i;
            allButtons[currentIndex].setId(generateViewId());
            addView(allButtons[currentIndex]);

            if (backgroundSelectorResourceId != 0) {
                Drawable buttonDrawable = context.getResources().getDrawable(backgroundSelectorResourceId);
                if (buttonDrawable != null) {
                    buttonDrawable.mutate();
                    allButtons[currentIndex].setBackground(buttonDrawable);
                }
            }

            if (textColorSelectorResourceId != 0)
            {
                ColorStateList colorStateList = context.getResources().getColorStateList(textColorSelectorResourceId);
                if (colorStateList !=null) {
                    allButtons[currentIndex].setTextColor(colorStateList);
                }
            }

            allButtons[currentIndex].setOnClickListener(new DefaultButtonListener(currentIndex));
        }

        ConstraintSet set = new ConstraintSet();
        set.clone(this);
        int[] chainIds = new int[numOfButtons];
        float[] chainWeights = new float[numOfButtons];
        for (int i=0; i<numOfButtons; i++)
        {
            int currentIndex = reversedOrder ?  (numOfButtons-i-1) : i;
            chainIds[currentIndex] = allButtons[currentIndex].getId();
            chainWeights[currentIndex] = 1;
        }
        for  (int i=1; i< numOfButtons ; i++)
        {
            if (reversedOrder)
            {
                set.connect(allButtons[i - 1].getId(), ConstraintSet.LEFT, allButtons[i].getId(), ConstraintSet.RIGHT);
            }
            else
            {
                set.connect(allButtons[i-1].getId(), ConstraintSet.RIGHT, allButtons[i].getId(),ConstraintSet.LEFT);
            }
        }

        if (reversedOrder)
        {
            set.connect(allButtons[0].getId(),ConstraintSet.RIGHT,ConstraintSet.PARENT_ID,ConstraintSet.RIGHT);
            set.connect(allButtons[numOfButtons-1].getId(),ConstraintSet.LEFT,ConstraintSet.PARENT_ID,ConstraintSet.LEFT);
        }

        else
        {
            set.connect(allButtons[0].getId(),ConstraintSet.LEFT,ConstraintSet.PARENT_ID,ConstraintSet.LEFT);
            set.connect(allButtons[numOfButtons-1].getId(),ConstraintSet.RIGHT,ConstraintSet.PARENT_ID,ConstraintSet.RIGHT);
        }

        set.createHorizontalChain(ConstraintSet.PARENT_ID,ConstraintSet.LEFT, ConstraintSet.PARENT_ID,ConstraintSet.RIGHT,chainIds,chainWeights,ConstraintSet.CHAIN_PACKED);
        set.applyTo(this);


        activeButtonIndex = typedArray.getInt(indexOfActiveButtonIndex,0);
        if (activeButtonIndex < 0 && activeButtonIndex > MAX_NUMBER_OF_BUTTONS -1)
        {
            activeButtonIndex = 0;
        }
        allButtons[activeButtonIndex].setSelected(true);
    }
}

xml layout:

<?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:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <TextView
        android:id="@+id/helloWorld"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <com.example.customviewapp.MultiButton
        android:layout_width="300dp"
        android:layout_height="50dp"
        app:layout_constraintTop_toBottomOf="@id/helloWorld"
        android:layout_marginTop="15dp"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:numOfButtons="4"
        app:activeButtonIndex="0"
        />

</androidx.constraintlayout.widget.ConstraintLayout>

Truncated Buttons

0

There are 0 answers