Java – Expand and collapse the Relativelayout with the click of a button

Expand and collapse the Relativelayout with the click of a button… here is a solution to the problem.

Expand and collapse the Relativelayout with the click of a button

I have this RelativeLayout which expands and collapses when the button is clicked
It works fine on one button.
I want to reuse the same method on more than two RelativeLayouts
In the same layout
and use the other two buttons to expand.

This code works fine. Just want more layouts to do the same.

Layout:
enter image description here

Here is my code :

<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:scrollbars="none">

<LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

<RelativeLayout

android:layout_width="fill_parent"
            android:layout_height="64dp"
            android:background="#FFF"
            android:orientation="vertical">

<TextView

android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="Title"
                android:textSize="20sp" />

<Button
                android:id="@+id/viewmore"
                android:layout_width="80dp"
                android:layout_height="match_parent"
                android:layout_marginLeft="280dp"
                android:background="@null"
                android:text="viewmore" />

</RelativeLayout>

<RelativeLayout

android:visibility="gone"
            android:id="@+id/expandable"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:animateLayoutChanges="true"
            android:background="@color/colorAccent"
            android:orientation="vertical">

<TextView

android:layout_width="match_parent"
                android:layout_height="133dp"
                android:text="Text messaging, or texting, is the act of composing and sending electronic messages, typically consisting of alphabetic and numeric characters"
                android:textSize="20sp" />

</RelativeLayout>

<RelativeLayout

android:layout_width="match_parent"
            android:layout_height="wrap_content">

<TextView
                android:id="@+id/textView4"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="Title 2"
                android:textSize="20sp" />

<Button
                android:id="@+id/viewmore1"
                android:layout_width="80dp"
                android:layout_height="match_parent"
                android:layout_marginLeft="280dp"
                android:background="@null"
                android:text="viewmore" />

</RelativeLayout>

<RelativeLayout
            android:visibility="gone"
            android:animateLayoutChanges="true"
            android:id="@+id/expandable1"
            android:layout_width="match_parent"
            android:layout_height="100dp"
            android:layout_marginTop="30dp"
            android:background="@color/colorPrimary">

<TextView

android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="Text messaging, or texting, is the act of composing and sending electronic messages, typically consisting of alphabetic and numeric characters"
                android:textSize="20sp" />

</RelativeLayout>

<RelativeLayout

android:layout_width="match_parent"
            android:layout_height="wrap_content">

<TextView

android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="Title 3"
                android:textSize="20sp" />

<Button
                android:id="@+id/viewmore2"
                android:layout_width="80dp"
                android:layout_height="match_parent"
                android:layout_marginLeft="280dp"
                android:background="@null"
                android:text="viewmore" />

</RelativeLayout>

<RelativeLayout
            android:visibility="gone"
            android:animateLayoutChanges="true"
            android:id="@+id/expandable2"
            android:layout_width="match_parent"
            android:layout_height="100dp"
            android:layout_marginTop="30dp"
            android:background="@color/colorPrimary">

<TextView

android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="Text messaging, or texting, is the act of composing and sending electronic messages, typically consisting of alphabetic and numeric characters"
                android:textSize="20sp" />

</RelativeLayout>

</LinearLayout>
</ScrollView>

Source code:

RelativeLayout relativeLayout, relativeLayout1, relativeLayout2;
    Button viewmore, viewmore1, viewmore2;
    ValueAnimator mAnimator;

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.viewmore);

relativeLayout = (RelativeLayout) findViewById(R.id.expandable);
        relativeLayout1 = (RelativeLayout) findViewById(R.id.expandable1);
        relativeLayout2 = (RelativeLayout) findViewById(R.id.expandable2);

viewmore = (Button) findViewById(R.id.viewmore);
        viewmore1 = (Button) findViewById(R.id.viewmore1);
        viewmore2 = (Button) findViewById(R.id.viewmore2);

viewmore.setOnClickListener(this);
        viewmore1.setOnClickListener(this);
        viewmore2.setOnClickListener(this);

relativeLayout.getViewTreeObserver().addOnPreDrawListener(
                new ViewTreeObserver.OnPreDrawListener() {

@Override
                    public boolean onPreDraw() {
                        relativeLayout.getViewTreeObserver().removeOnPreDrawListener(this);
                        relativeLayout.setVisibility(View.GONE);

final int widthSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
                        final int heightSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
                        relativeLayout.measure(widthSpec, heightSpec);

mAnimator = slideAnimator(0, relativeLayout.getMeasuredHeight());
                        return true;
                    }
                });

}

private void expand() {

relativeLayout.setVisibility(View.VISIBLE);
        mAnimator.start();
    }

private void collapse() {
        int finalHeight = relativeLayout.getHeight();

ValueAnimator mAnimator = slideAnimator(finalHeight, 0);

mAnimator.addListener(new Animator.AnimatorListener() {
            @Override
            public void onAnimationEnd(Animator animator) {
                Height=0, but it set visibility to GONE
                relativeLayout.setVisibility(View.GONE);
            }

@Override
            public void onAnimationStart(Animator animator) {
            }

@Override
            public void onAnimationCancel(Animator animator) {
            }

@Override
            public void onAnimationRepeat(Animator animator) {
            }
        });
        mAnimator.start();
    }

private ValueAnimator slideAnimator(int start, int end) {

ValueAnimator animator = ValueAnimator.ofInt(start, end);

animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator valueAnimator) {
                Update Height
                int value = (Integer) valueAnimator.getAnimatedValue();

ViewGroup.LayoutParams layoutParams = relativeLayout.getLayoutParams();
                layoutParams.height = value;
                relativeLayout.setLayoutParams(layoutParams);
            }
        });
        return animator;
    }

@Override
    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.viewmore:

if (relativeLayout.getVisibility() == View.GONE) {
                    expand();
                } else {
                    collapse();
                }

break;

case R.id.viewmore1:

break;

case R.id.viewmore2:

break;

}
    }

Solution

To continue your method, you must apply the code to all three parts of your layout. To do this, you need to change several methods to accept RelativeLayout as a parameter.

First, in your onClick listener, populate the case block so that each block calls expand() to target RelativeLayout and maximum height. Call collapse() with the target RelativeLayout. Then you need to modify expand() and collapse() to handle the new parameters:

You’ll notice in the code below that I’ve changed how and where animators are created. Animators need to handle each RelativeLayout.

Therefore, onClick() calls expand(), which calls slideAnimator(). For each call, the affected RelativeLayout is passed as a parameter. In this way, you can summarize your code to use multiple RelativeLayouts.

The predraw listener also needs to measure each scalable RelativeLayout.

Here’s it all:

MainActivity.xml

public class MainActivity extends AppCompatActivity
    implements View.OnClickListener {

RelativeLayout relativeLayout, relativeLayout1, relativeLayout2;
    Button viewmore, viewmore1, viewmore2;
    int height, height1, height2;

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.viewmore);

relativeLayout = (RelativeLayout) findViewById(R.id.expandable);
        relativeLayout1 = (RelativeLayout) findViewById(R.id.expandable1);
        relativeLayout2 = (RelativeLayout) findViewById(R.id.expandable2);

viewmore = (Button) findViewById(R.id.viewmore);
        viewmore1 = (Button) findViewById(R.id.viewmore1);
        viewmore2 = (Button) findViewById(R.id.viewmore2);

viewmore.setOnClickListener(this);
        viewmore1.setOnClickListener(this);
        viewmore2.setOnClickListener(this);

relativeLayout.getViewTreeObserver().addOnPreDrawListener(
            new ViewTreeObserver.OnPreDrawListener() {

@Override
                public boolean onPreDraw() {
                    relativeLayout.getViewTreeObserver().removeOnPreDrawListener(this);
                    relativeLayout.setVisibility(View.GONE);
                    relativeLayout1.setVisibility(View.GONE);
                    relativeLayout2.setVisibility(View.GONE);

final int widthSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
                    final int heightSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
                    relativeLayout.measure(widthSpec, heightSpec);
                    height = relativeLayout.getMeasuredHeight();
                    relativeLayout1.measure(widthSpec, heightSpec);
                    height1 = relativeLayout.getMeasuredHeight();
                    relativeLayout2.measure(widthSpec, heightSpec);
                    height2 = relativeLayout.getMeasuredHeight();
                    return true;
                }
            });
    }

private void expand(RelativeLayout layout, int layoutHeight) {
        layout.setVisibility(View.VISIBLE);
        ValueAnimator animator = slideAnimator(layout, 0, layoutHeight);
        animator.start();
    }

private void collapse(final RelativeLayout layout) {
        int finalHeight = layout.getHeight();
        ValueAnimator mAnimator = slideAnimator(layout, finalHeight, 0);

mAnimator.addListener(new Animator.AnimatorListener() {
            @Override
            public void onAnimationEnd(Animator animator) {
                Height=0, but it set visibility to GONE
                layout.setVisibility(View.GONE);
            }

@Override
            public void onAnimationStart(Animator animator) {
            }

@Override
            public void onAnimationCancel(Animator animator) {
            }

@Override
            public void onAnimationRepeat(Animator animator) {
            }
        });
        mAnimator.start();
    }

private ValueAnimator slideAnimator(final RelativeLayout layout, int start, int end) {
        ValueAnimator animator = ValueAnimator.ofInt(start, end);

animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator valueAnimator) {
                Update Height
                int value = (Integer) valueAnimator.getAnimatedValue();

ViewGroup.LayoutParams layoutParams = layout.getLayoutParams();
                layoutParams.height = value;
                layout.setLayoutParams(layoutParams);
            }
        });
        return animator;
    }

@Override
    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.viewmore:
                if (relativeLayout.getVisibility() == View.GONE) {
                    expand(relativeLayout, height);
                } else {
                    collapse(relativeLayout);
                }
                break;

case R.id.viewmore1:
                if (relativeLayout1.getVisibility() == View.GONE) {
                    expand(relativeLayout1, height1);
                } else {
                    collapse(relativeLayout1);
                }
                break;

case R.id.viewmore2:
                if (relativeLayout2.getVisibility() == View.GONE) {
                    expand(relativeLayout2, height2);
                } else {
                    collapse(relativeLayout2);
                }
                break;
        }
    }
}

Related Problems and Solutions