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.
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;
}
}
}