Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is the margin parameter in ConstraintSet.connect() meant to be in px or dp?

val margin = 8
ConstraintSet().apply {
  connect(anId, ConstraintSet.START, anotherId, ConstraintSet.START, margin)
}

Is margin applied as pixels or density-dependent pixels?

Various articles scattered around the web and apocryphal knowledge seem not to agree on one or the other. I'm looking for official documentation or source evidence.

like image 818
nukeforum Avatar asked May 22 '19 21:05

nukeforum


3 Answers

The margin parameter should be supplied in pixels.

I ended up tracing the ConstraintSet.applyTo(ConstraintLayout) down to ConstraintSet.applyToInternal(ConstraintLayout) and found that here, each child of a ConstraintLayout has its LayoutParams copied and passed to ConstraintSet.Constraint.applyTo(LayoutParams). Which then copies all the parameters (without modification) from the ConstraintSet.Constraint into the LayoutParams and then assigns the modified LayoutParams back to the child. I think this is concrete evidence that the supplied margin parameters should follow the LayoutParams rules.

in ConstraintSet.java

    this.applyToInternal(constraintLayout);
    constraintLayout.setConstraintSet((ConstraintSet)null); }

at applyToInternal(ConstraintLayout) declaration

    int count = constraintLayout.getChildCount();

    //...

    LayoutParams param;
    for(int i = 0; i < count; ++i) {
        View view = constraintLayout.getChildAt(i);
        //...
        param = (LayoutParams)view.getLayoutParams();
        constraint.applyTo(param);
        view.setLayoutParams(param);
        //...
    }

    //...

at applyTo(LayoutParams) declaration

    //...
    param.leftMargin = this.leftMargin;
    param.rightMargin = this.rightMargin;
    param.topMargin = this.topMargin;
    param.bottomMargin = this.bottomMargin;
    //...
like image 79
nukeforum Avatar answered Sep 27 '22 23:09

nukeforum


The margin, padding, constraint ... APIs all work in pixels. If you have DPs, you have to convert those to pixels first.

like image 23
Francesc Avatar answered Sep 28 '22 01:09

Francesc


In general, Java/Kotlin work with px. There's no official documentation that I can find (or anything in the source code of ConstraintSet or Constraint) that says this outright.

If you look at the source code for ViewGroup.MarginLayoutParams, however, you will find this code:

public MarginLayoutParams(Context c, AttributeSet attrs) {
    ...
    int margin = a.getDimensionPixelSize(
                com.android.internal.R.styleable.ViewGroup_MarginLayout_layout_margin, -1);
    if (margin >= 0) {
        leftMargin = margin;
        topMargin = margin;
        rightMargin= margin;
        bottomMargin = margin;
    }
    ...
}

It should be plain to see (from the call to getDimensionPixelSize()) that the units for margin here are px. I think it is reasonable to say that MarginLayoutParams is the "original" source of truth for margins, and I would generally expect things that emulate this behavior (like ConstraintSet) to follow the same pattern.

Note that ConstraintLayout.LayoutParams is a subclass of ViewGroup.MarginLayoutParams.

like image 35
Ben P. Avatar answered Sep 27 '22 23:09

Ben P.