2

I have a Android ConstraintLayout inside a ScrollView. I add a few buttons and an ImageView to the Layout. One of the buttons should constrain to the bottom of the ImageView.

Here arises the problem: As soon as I set the image to resize to the bounds of the view (setAdjustViewBounds), the image is resized exactly as I want, but the button that should follow the ImageView is drawn at the bottom of the image, not beneath it.

See the following output: This is how it looks

When I add one more button, whose definition has to follow the ImageView-definition, then everything looks fine, even if its constraints have nothing to do with the image-constraints. If I move the definition of the additional button before the ImageView-definition I get the wrong output again, with the one additional button of course.

Here is the correct output: And this is how it should look

But I don't want any additional declarations after the ImageView just to make the Layout work.

Does anyone have an idea, what goes wrong here?

Here is my code that produces the wrong position of button2 (Test 2):

public class MainActivity extends AppCompatActivity {

int id = 1;

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

    ScrollView sv = new ScrollView(this);
    sv.setId(id++);

    ConstraintLayout mainLayout = new ConstraintLayout(this);
    mainLayout.setId(id++);
    mainLayout.setLayoutParams(new ConstraintLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));

    Button button = new Button(this);
    button.setId(id++);
    button.setText("Test");
    mainLayout.addView(button);

    Button button1 = new Button(this);
    button1.setId(id++);
    button1.setText("Test 1");
    mainLayout.addView(button1);

    ImageView image = new ImageView(this);
    image.setId(id++);
    image.setImageResource(R.drawable.img);
    image.setBackgroundColor(Color.parseColor("#0000FF"));
    image.setLayoutParams(new ConstraintLayout.LayoutParams(ConstraintLayout.LayoutParams.MATCH_CONSTRAINT, ConstraintLayout.LayoutParams.WRAP_CONTENT));
    image.setAdjustViewBounds(true);
    mainLayout.addView(image);

    Button button2 = new Button(this);
    button2.setId(id++);
    button2.setText("TEST 2");
    mainLayout.addView(button2);

    //getFragmentManager().beginTransaction().add(sv.getId(), BlankFragment.newInstance("Inhalt 1"), "someTag1").commit();

    sv.addView(mainLayout);

    ConstraintSet constraintSet = new ConstraintSet();
    constraintSet.clone(mainLayout);

    constraintSet.constrainWidth(button.getId(), constraintSet.MATCH_CONSTRAINT);
    constraintSet.connect(button.getId(), ConstraintSet.TOP, mainLayout.getId(), ConstraintSet.TOP, 10);
    constraintSet.connect(button.getId(), ConstraintSet.START, mainLayout.getId(), ConstraintSet.START, 50);
    constraintSet.connect(button.getId(), ConstraintSet.END, mainLayout.getId(), ConstraintSet.END, 50);

    constraintSet.constrainWidth(button1.getId(), constraintSet.MATCH_CONSTRAINT);
    constraintSet.connect(button1.getId(), ConstraintSet.TOP, button.getId(), ConstraintSet.BOTTOM, 10);
    constraintSet.connect(button1.getId(), ConstraintSet.START, button.getId(), ConstraintSet.START, 0);
    constraintSet.connect(button1.getId(), ConstraintSet.END, button.getId(), ConstraintSet.END, 700);

    constraintSet.constrainWidth(image.getId(), constraintSet.MATCH_CONSTRAINT);
    constraintSet.connect(image.getId(), ConstraintSet.TOP, button1.getId(), ConstraintSet.BOTTOM, 10);
    constraintSet.connect(image.getId(), ConstraintSet.START, button.getId(), ConstraintSet.START, 100);
    constraintSet.connect(image.getId(), ConstraintSet.END, button.getId(), ConstraintSet.END, 100);

    constraintSet.constrainWidth(button2.getId(), constraintSet.MATCH_CONSTRAINT);
    constraintSet.connect(button2.getId(), ConstraintSet.TOP, image.getId(), ConstraintSet.BOTTOM, 10);
    constraintSet.connect(button2.getId(), ConstraintSet.START, button.getId(), ConstraintSet.START, 0);
    constraintSet.connect(button2.getId(), ConstraintSet.END, button.getId(), ConstraintSet.END, 0);
    constraintSet.connect(button2.getId(), ConstraintSet.BOTTOM, mainLayout.getId(), ConstraintSet.BOTTOM, 10);

    constraintSet.applyTo(mainLayout);


    setContentView(sv);
}

}

And here is the code with the additional button, that moves button2 to the correct location. Nothing special, just the additional button.

public class MainActivity extends AppCompatActivity {

int id = 1;

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

    ScrollView sv = new ScrollView(this);
    sv.setId(id++);

    ConstraintLayout mainLayout = new ConstraintLayout(this);
    mainLayout.setId(id++);
    mainLayout.setLayoutParams(new ConstraintLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));

    Button button = new Button(this);
    button.setId(id++);
    button.setText("Test");
    mainLayout.addView(button);

    Button button1 = new Button(this);
    button1.setId(id++);
    button1.setText("Test 1");
    mainLayout.addView(button1);

    ImageView image = new ImageView(this);
    image.setId(id++);
    image.setImageResource(R.drawable.img);
    image.setBackgroundColor(Color.parseColor("#0000FF"));
    image.setLayoutParams(new ConstraintLayout.LayoutParams(ConstraintLayout.LayoutParams.MATCH_CONSTRAINT, ConstraintLayout.LayoutParams.WRAP_CONTENT));
    image.setAdjustViewBounds(true);
    mainLayout.addView(image);

    //Even when button3 is left inside the example, but its declaration (next four lines) are moved above the imageview-initialization, the error occurs
    Button button3 = new Button(this);
    button3.setId(id++);
    button3.setText("Test 3");
    mainLayout.addView(button3);

    Button button2 = new Button(this);
    button2.setId(id++);
    button2.setText("TEST 2");
    mainLayout.addView(button2);

    //getFragmentManager().beginTransaction().add(sv.getId(), BlankFragment.newInstance("Inhalt 1"), "someTag1").commit();

    sv.addView(mainLayout);

    ConstraintSet constraintSet = new ConstraintSet();
    constraintSet.clone(mainLayout);

    constraintSet.constrainWidth(button.getId(), constraintSet.MATCH_CONSTRAINT);
    constraintSet.connect(button.getId(), ConstraintSet.TOP, mainLayout.getId(), ConstraintSet.TOP, 10);
    constraintSet.connect(button.getId(), ConstraintSet.START, mainLayout.getId(), ConstraintSet.START, 50);
    constraintSet.connect(button.getId(), ConstraintSet.END, mainLayout.getId(), ConstraintSet.END, 50);

    constraintSet.constrainWidth(button1.getId(), constraintSet.MATCH_CONSTRAINT);
    constraintSet.connect(button1.getId(), ConstraintSet.TOP, button.getId(), ConstraintSet.BOTTOM, 10);
    constraintSet.connect(button1.getId(), ConstraintSet.START, button.getId(), ConstraintSet.START, 0);
    constraintSet.connect(button1.getId(), ConstraintSet.END, button.getId(), ConstraintSet.END, 700);

    constraintSet.constrainWidth(image.getId(), constraintSet.MATCH_CONSTRAINT);
    constraintSet.connect(image.getId(), ConstraintSet.TOP, button1.getId(), ConstraintSet.BOTTOM, 10);
    constraintSet.connect(image.getId(), ConstraintSet.START, button.getId(), ConstraintSet.START, 100);
    constraintSet.connect(image.getId(), ConstraintSet.END, button.getId(), ConstraintSet.END, 100);

    constraintSet.constrainWidth(button3.getId(), constraintSet.MATCH_CONSTRAINT);
    constraintSet.connect(button3.getId(), ConstraintSet.TOP, button.getId(), ConstraintSet.BOTTOM, 10);
    constraintSet.connect(button3.getId(), ConstraintSet.START, button.getId(), ConstraintSet.START, 700);
    constraintSet.connect(button3.getId(), ConstraintSet.END, button.getId(), ConstraintSet.END, 0);

    constraintSet.constrainWidth(button2.getId(), constraintSet.MATCH_CONSTRAINT);
    constraintSet.connect(button2.getId(), ConstraintSet.TOP, image.getId(), ConstraintSet.BOTTOM, 10);
    constraintSet.connect(button2.getId(), ConstraintSet.START, button.getId(), ConstraintSet.START, 0);
    constraintSet.connect(button2.getId(), ConstraintSet.END, button.getId(), ConstraintSet.END, 0);
    constraintSet.connect(button2.getId(), ConstraintSet.BOTTOM, mainLayout.getId(), ConstraintSet.BOTTOM, 10);

    constraintSet.applyTo(mainLayout);


    setContentView(sv);
}

}

B. P.
  • 31
  • 3
  • Which version of `ConstraintLayout` are you using? – Cheticamp Jan 02 '18 at 23:28
  • I am not able to reproduce your results. Try using [View#generateViewId()](https://developer.android.com/reference/android/view/View.html#generateViewId()) instead of `id++` in case there is some conflict. (I think that's unlikely, but it's worth a try and a better way to do it anyway.) This requres API 17+. – Cheticamp Jan 03 '18 at 00:16
  • Thanks Cheticamp, your hint to check the version was very good. I updated to the latest (1.1.0-beta4) and now everything looks fine. Mine was 1.0.2. – B. P. Jan 03 '18 at 10:02

1 Answers1

1

Cheticamp's hint to check for the version was the solution. After updating to the latest ConstraintLayout version, currently 1.1.0-beta4, everything looks good. Seemed to be a problem of my older version, which was 1.0.2.

Cheticamp
  • 61,413
  • 10
  • 78
  • 131
B. P.
  • 31
  • 3