You can also try this custom view for ExpandablePanel found it somewhere when i needed to create something like this.
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Point;
import android.util.AttributeSet;
import android.util.Log;
import android.view.Display;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.Transformation;
import android.widget.LinearLayout;
public class ExpandablePanel extends LinearLayout {
private final int mHandleId;
private final int mContentId;
// Contains references to the handle and content views
private View mHandle;
private View mContent;
// Does the panel start expanded?
private boolean mExpanded = false;
// The height of the content when collapsed
private int mCollapsedHeight = 0;
// The full expanded height of the content (calculated)
private int mContentHeight = 0;
// How long the expand animation takes
private int mAnimationDuration = 0;
int height;
private Context context;
// Listener that gets fired onExpand and onCollapse
private OnExpandListener mListener;
public ExpandablePanel(Context context) {
this(context, null);
this.context = context;
}
public void setSize(int size) {
this.height = size;
}
/**
* The constructor simply validates the arguments being passed in and sets
* the global variables accordingly. Required attributes are 'handle' and
* 'content'
*/
public ExpandablePanel(Context context, AttributeSet attrs) {
super(context, attrs);
mListener = new DefaultOnExpandListener();
TypedArray a = context.obtainStyledAttributes(attrs,
R.styleable.ExpandablePanel, 0, 0);
// How high the content should be in "collapsed" state
mCollapsedHeight = (int) a.getDimension(
R.styleable.ExpandablePanel_collapsedHeight, 0.0f);
// How long the animation should take
mAnimationDuration = a.getInteger(
R.styleable.ExpandablePanel_animationDuration, 500);
int handleId = a.getResourceId(R.styleable.ExpandablePanel_handle, 0);
if (handleId == 0) {
throw new IllegalArgumentException(
"The handle attribute is required and must refer "
+ "to a valid child.");
}
int contentId = a.getResourceId(R.styleable.ExpandablePanel_content, 0);
if (contentId == 0) {
throw new IllegalArgumentException(
"The content attribute is required and must "
+ "refer to a valid child.");
}
mHandleId = handleId;
mContentId = contentId;
a.recycle();
}
// Some public setters for manipulating the
// ExpandablePanel programmatically
public void setOnExpandListener(OnExpandListener listener) {
mListener = listener;
}
public void setCollapsedHeight(int collapsedHeight) {
mCollapsedHeight = collapsedHeight;
}
public void setAnimationDuration(int animationDuration) {
mAnimationDuration = animationDuration;
}
/**
* This method gets called when the View is physically visible to the user
*/
@Override
protected void onFinishInflate() {
super.onFinishInflate();
mHandle = findViewById(mHandleId);
if (mHandle == null) {
throw new IllegalArgumentException(
"The handle attribute is must refer to an"
+ " existing child.");
}
mContent = findViewById(mContentId);
if (mContent == null) {
throw new IllegalArgumentException(
"The content attribute must refer to an"
+ " existing child.");
}
// This changes the height of the content such that it
// starts off collapsed
android.view.ViewGroup.LayoutParams lp = mContent.getLayoutParams();
lp.height = mCollapsedHeight;
mContent.setLayoutParams(lp);
// Set the OnClickListener of the handle view
mHandle.setOnClickListener(new PanelToggler());
}
/**
* This is where the magic happens for measuring the actual (un-expanded)
* height of the content. If the actual height is less than the
* collapsedHeight, the handle will be hidden.
*/
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
// First, measure how high content wants to be
mContent.measure(widthMeasureSpec, MeasureSpec.UNSPECIFIED);
mContentHeight = mContent.getMeasuredHeight();
Log.v("cHeight", mContentHeight + "");
Log.v("cCollapseHeight", mCollapsedHeight + "");
if (mContentHeight < mCollapsedHeight) {
mHandle.setVisibility(View.GONE);
} else {
mHandle.setVisibility(View.VISIBLE);
}
// Then let the usual thing happen
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
/**
* This is the on click listener for the handle. It basically just creates a
* new animation instance and fires animation.
*/
private class PanelToggler implements OnClickListener {
public void onClick(View v) {
Animation a;
if (mExpanded) {
a = new ExpandAnimation(mContentHeight, mCollapsedHeight);
mListener.onCollapse(mHandle, mContent);
} else {
a = new ExpandAnimation(mCollapsedHeight, mContentHeight);
mListener.onExpand(mHandle, mContent);
}
a.setDuration(mAnimationDuration);
mContent.startAnimation(a);
mExpanded = !mExpanded;
}
}
/**
* This is a private animation class that handles the expand/collapse
* animations. It uses the animationDuration attribute for the length of
* time it takes.
*/
private class ExpandAnimation extends Animation {
private final int mStartHeight;
private final int mDeltaHeight;
public ExpandAnimation(int startHeight, int endHeight) {
mStartHeight = startHeight;
mDeltaHeight = endHeight - startHeight;
}
@Override
protected void applyTransformation(float interpolatedTime,
Transformation t) {
android.view.ViewGroup.LayoutParams lp = mContent.getLayoutParams();
lp.height = (int) (mStartHeight + mDeltaHeight * interpolatedTime);
mContent.setLayoutParams(lp);
}
@Override
public boolean willChangeBounds() {
return true;
}
}
/**
* Simple OnExpandListener interface
*/
public interface OnExpandListener {
public void onExpand(View handle, View content);
public void onCollapse(View handle, View content);
}
private class DefaultOnExpandListener implements OnExpandListener {
public void onCollapse(View handle, View content) {
}
public void onExpand(View handle, View content) {
}
}
}