Reputation: 1109
I'm trying to build an activity with 3 imageViews according to the following layout:
<------W-------> <------W-------->
^ +---------------+--------+---------------+
| | | | |
| | | | |
H | A | B | C |
| | | (1:3) | |
| | | | |
v +---------------+--------+---------------+
I tried multiple solutions and could never find one that works. The last one uses :
match_constraint
dimensionsWhile I would expect that the solver would make the desired layout instead it seems the chain defines a similar width to all views as seen in the screenshot.
I also tried using a LinearLayout
but it doesn't seem possible to fix the aspect ratio of items inside one.
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.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">
<ImageView
android:id="@+id/imageView1"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="@android:color/holo_blue_bright"
app:layout_constraintBottom_toTopOf="@+id/guideline"
app:layout_constraintDimensionRatio=""
app:layout_constraintEnd_toStartOf="@+id/imageView2"
app:layout_constraintHorizontal_chainStyle="spread"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.0"
app:srcCompat="@mipmap/ic_launcher" />
<ImageView
android:id="@+id/imageView2"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="@android:color/holo_blue_bright"
app:layout_constraintBottom_toTopOf="@+id/guideline"
app:layout_constraintDimensionRatio="1:3"
app:layout_constraintEnd_toStartOf="@+id/imageView3"
app:layout_constraintStart_toEndOf="@+id/imageView1"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.0"
app:srcCompat="@mipmap/ic_launcher" />
<ImageView
android:id="@+id/imageView3"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="@android:color/holo_blue_bright"
app:layout_constraintBottom_toTopOf="@+id/guideline"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/imageView2"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.0"
app:srcCompat="@mipmap/ic_launcher" />
<android.support.constraint.Guideline
android:id="@+id/guideline"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_percent="0.3333" />
<android.support.constraint.Guideline
android:id="@+id/guideline3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_percent="0.6666666666" />
</android.support.constraint.ConstraintLayout>
Thanks a lot!
Upvotes: 8
Views: 5240
Reputation: 5589
I think the ConstraintLayout won't be able to handle all the restrictions put upon the middle view in terms of height or width, aspect ration, and boundaries, so this solution has part implemented in the xml and a final adjustment programatically.
It separates the three images with guidelines, and when the layout is rendered, it recalculates the position of the guidelines.
Layout
<android.support.constraint.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:id="@+id/mainLayout"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.constraint.Guideline
android:id="@+id/guidelineV33"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_percent="0.3333" />
<android.support.constraint.Guideline
android:id="@+id/guidelineH33"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.3333" />
<android.support.constraint.Guideline
android:id="@+id/guidelineH66"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.6666" />
<ImageView
android:id="@+id/ivA"
android:layout_width="0dp"
android:layout_height="0dp"
android:src="@drawable/ic_launcher_foreground"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toLeftOf="@id/guidelineH33"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toTopOf="@id/guidelineV33"/>
<ImageView
android:id="@+id/ivB"
android:layout_width="0dp"
android:layout_height="0dp"
android:src="@drawable/ic_launcher_foreground"
app:layout_constraintLeft_toRightOf="@id/guidelineH33"
app:layout_constraintRight_toLeftOf="@id/guidelineH66"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toTopOf="@id/guidelineV33"
/>
<ImageView
android:id="@+id/ivC"
android:layout_width="0dp"
android:layout_height="0dp"
android:src="@drawable/ic_launcher_foreground"
app:layout_constraintLeft_toRightOf="@id/guidelineH66"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toTopOf="@id/guidelineV33"/>
</android.support.constraint.ConstraintLayout>
Activity
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.constraint.ConstraintLayout;
import android.support.constraint.ConstraintSet;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.ViewTreeObserver;
public class SO50626509Activity extends AppCompatActivity {
private static final String TAG = SO50626509Activity.class.getName();
ConstraintLayout cl;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.so50626509_layout);
cl = findViewById(R.id.mainLayout);
ViewTreeObserver observer = cl.getViewTreeObserver();
observer.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
adjustLayout();
cl.getViewTreeObserver().removeOnGlobalLayoutListener(this);
}
});
}
private void adjustLayout(){
int height = (int) (cl.getMeasuredHeight() * 0.3333);
int width = cl.getMeasuredWidth();
int middleWidth = height / 3;
int g33 = (width - middleWidth) / 2;
int g66 = g33 + middleWidth;
ConstraintSet set = new ConstraintSet();
set.clone(cl);
set.setGuidelinePercent(R.id.guidelineH33,((float) g33 / (float) width));
set.setGuidelinePercent(R.id.guidelineH66,((float) g66 / (float) width));
set.applyTo(cl);
}
}
Upvotes: 0
Reputation: 62831
There are probably several approaches to doing what you ask. Here is one approach:
The key to this layout is to set up the center image first as defined in the XML. Once the center image is established, it becomes easier to define the left and right images.
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<ImageView
android:id="@+id/imageViewLeft"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="@+id/imageCenter"
app:layout_constraintEnd_toStartOf="@+id/imageCenter"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@+id/imageCenter"
app:srcCompat="@color/colorPrimary" />
<ImageView
android:id="@+id/imageCenter"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintDimensionRatio="W,1:3"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHeight_percent="0.33"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.0"
app:srcCompat="@color/colorAccent" />
<ImageView
android:id="@+id/imageViewRight"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="@+id/imageCenter"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/imageCenter"
app:layout_constraintTop_toTopOf="@+id/imageCenter"
app:srcCompat="@color/colorPrimary" />
</android.support.constraint.ConstraintLayout>
Upvotes: 5