Nathalie
Nathalie

Reputation: 655

Android make a resizable split screen inside a contraintlayout

I want to have a splitter inside a contraintlayout to be able to change the relative size of 2 images view.

Example : when dragging the double arrow below should resize image1 / image2 according to arrow position.

Screen splitter

For this here is my 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:id="@+id/main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#FFFFFF">


    <ImageView
        android:id="@+id/image1"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:layout_gravity="center"
        android:layout_marginTop="8dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/main_divider_img" />


    <ImageView
        android:id="@+id/image2"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:layout_marginBottom="8dp"
        android:visibility="visible"
        app:layout_constraintBottom_toTopOf="@+id/main_divider_img"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />


    <ImageView
        android:id="@+id/main_divider_img"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:srcCompat="@drawable/divider" />



</androidx.constraintlayout.widget.ConstraintLayout>

And a have an onTouchListener on my divider image :

 View.OnTouchListener dividerTouchListener = new View.OnTouchListener() {

        private float  mInitialY;


        @Override
        public boolean onTouch(View view, MotionEvent motionEvent) {
            switch (motionEvent.getActionMasked()) {
                case MotionEvent.ACTION_DOWN:
                    mInitialY = view.getY() - motionEvent.getRawY();
                    break;
                case MotionEvent.ACTION_MOVE:
                    view.animate().y(motionEvent.getRawY() + mInitialY).setDuration(0).start()                  
                    break;
                default:
                    return false;
            }
            return true;

        }
    };

At start my spliter image is between images, but when I move it, the constraints on imageView1 and imageView2 are not updated and they are not resized, and my splitter images moves on screen independently of imageView1 and imageView2.

This is what I get

Result

And this is what I want :

Expected

How can I acheive this ?

Upvotes: 5

Views: 1367

Answers (1)

Nathalie
Nathalie

Reputation: 655

After trying more I found a somution using guide lines :

Both imageView and splitview are now constraint to the guideline

When moving the split image I change the guideline percent

Here is the 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:id="@+id/main"
    android:layout_width="match_parent"
    android:layout_height="match_parent">


    <ImageView
        android:id="@+id/image1"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:layout_gravity="center"
        android:background="@color/rejectedRed"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="@+id/guideline" />

    <ImageView
        android:id="@+id/image2"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:background="@color/acceptedGreen"
        android:visibility="visible"
        app:layout_constraintBottom_toTopOf="@+id/image1"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <androidx.constraintlayout.widget.Guideline
        android:id="@+id/guideline"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        app:layout_constraintGuide_percent="0.41" />

    <ImageView
        android:id="@+id/main_divider_img"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"

        android:layout_marginStart="8dp"
        app:layout_constraintBottom_toTopOf="@+id/guideline"
        app:layout_constraintStart_toEndOf="@+id/textView2"
        app:layout_constraintTop_toTopOf="@+id/guideline"
        app:srcCompat="@drawable/divider" />


</androidx.constraintlayout.widget.ConstraintLayout>

Here is the touchListener much simpler :

 @Override
        public boolean onTouch(View view, MotionEvent motionEvent) {
            int height = 0;
            switch (motionEvent.getActionMasked()) {
                case MotionEvent.ACTION_DOWN:
                    break;
                case MotionEvent.ACTION_MOVE:
                    height = ((ConstraintLayout) findViewById(R.id.main)).getHeight();
                    Guideline guideLine = (Guideline) findViewById(R.id.guideline);
                    ConstraintLayout.LayoutParams params = (ConstraintLayout.LayoutParams) guideLine.getLayoutParams();
                    params.guidePercent = (motionEvent.getRawY()) / height;
                    guideLine.setLayoutParams(params);

                    break;
                default:
                    return false;
            }
            return true;

        }

I hope it can help somebody.

Upvotes: 7

Related Questions