Ilnar Karimov
Ilnar Karimov

Reputation: 339

ExpandablePanel Layout

My expandable panel is not working as it should. I'll show the pictures:

In normal state it should be like this

enter image description here

After expand, it should be like this

enter image description here

And after collapse it should return to normal state.

Now it work like here:

Normal state:

enter image description here

After expand it works like collapse state:

enter image description here.

And i have not to use expandable list view, i need layout works like expandable view.

So, what's wrong with code?

public class ExpandablePanel extends LinearLayout {

private int mHandleId;
private int mContentId;
private int mViewGroupId;

private boolean isViewGroup;

private View mHandle;
private View mContent;
private ViewGroup viewGroup;

private boolean mExpanded = false;
private int mCollapsedHeight = 0;
private int mContentHeight = 0;
private int mAnimationDuration = 0;

private OnExpandListener mListener;

public ExpandablePanel(Context context) {
    this(context, null);
}

public ExpandablePanel(Context context, AttributeSet attrs) {
    super(context, attrs);
    if (!isInEditMode()) {
        init(context, attrs);
    }
}

private void init (Context context, AttributeSet attrs) {

    if (isInEditMode()) return;

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

    int isViewGroupId = a.getResourceId(R.styleable.ExpandablePanel_isviewgroup, 0);
    int viewGroupId = a.getResourceId(R.styleable.ExpandablePanel_viewgroup, 0);
    isViewGroup = a.getBoolean(R.styleable.ExpandablePanel_isviewgroup, false);
    if (isViewGroup) {
        mViewGroupId = viewGroupId;
    }
    else {
        mViewGroupId = 0;
    }

    mHandleId = handleId;
    mContentId = contentId;

    a.recycle();
}

public void setOnExpandListener(OnExpandListener listener) {
    mListener = listener;
}

public void setCollapsedHeight(int collapsedHeight) {
    mCollapsedHeight = collapsedHeight;
}

public void setAnimationDuration(int animationDuration) {
    mAnimationDuration = animationDuration;
}

@Override
protected void onFinishInflate() {
    super.onFinishInflate();

    mHandle = findViewById(mHandleId);
    if (mHandle == null) {

        if (!isInEditMode()) {
            throw new IllegalArgumentException(
                    "The handle attribute is must refer to an"
                            + " existing child.");
        }
    }
    if(mViewGroupId != 0) {
        viewGroup = (ViewGroup) findViewById(mViewGroupId);
    }


    mContent = findViewById(mContentId);
    if (mContent == null) {

        if (!isInEditMode()) {
            throw new IllegalArgumentException(
                    "The content attribute must refer to an"
                            + " existing child.");
        }
    }

    if (!isInEditMode()) {
        android.view.ViewGroup.LayoutParams lp = mContent.getLayoutParams();
        lp.height = mCollapsedHeight;
        mContent.setLayoutParams(lp);

        mHandle.setOnClickListener(new PanelToggler());
    }
}

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    // First, measure how high content wants to be
    if (isInEditMode()) return;

    mContent.measure(widthMeasureSpec, MeasureSpec.UNSPECIFIED);
    mContentHeight = mContent.getMeasuredHeight();

    if (mContentHeight < mCollapsedHeight) {
        viewGroup.setVisibility(View.GONE);

    } else {
        viewGroup.setVisibility(View.VISIBLE);
    }

    // Then let the usual thing happen
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}

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);
        if(mContent.getLayoutParams().height == 0) //Need to do this or else the animation will not play if the height is 0
        {
            android.view.ViewGroup.LayoutParams lp = mContent.getLayoutParams();
            lp.height = 1;
            mContent.setLayoutParams(lp);
            mContent.requestLayout();
        }
        mContent.startAnimation(a);
        mExpanded = !mExpanded;
    }
}

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

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) {}
}

XML

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
          xmlns:example="http://schemas.android.com/apk/res-auto"
          android:layout_width="fill_parent"
          android:layout_height="match_parent"
          xmlns:app="http://schemas.android.com/tools">

<ExpandablePanel
    android:id="@+id/expandablePanel"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    example:collapsedHeight="50dip"
    example:content="@+id/group_layout"
    example:handle="@+id/group_layout"
    example:isviewgroup="true"
    example:viewgroup="@+id/childLayout" >

    <LinearLayout
        android:layout_width="match_parent"
        android:id="@+id/group_layout"
        android:padding="10dp"
        android:orientation="horizontal"
        android:layout_height="wrap_content">
        </LinearLayout>

    </LinearLayout>

    <LinearLayout
        android:layout_marginLeft="35dp"
        android:layout_width="match_parent"
        android:id="@+id/childLayout"
        android:padding="10dp"
        android:orientation="horizontal"
        android:layout_height="wrap_content">
    </LinearLayout>
<ExpandablePanel>
</LinearLayout>

Upvotes: 1

Views: 307

Answers (1)

IntelliJ Amiya
IntelliJ Amiya

Reputation: 75788

First Of all please set Open-Close Tag This way

Whats Your Problem

Your Root Layout LinearLayout Close Tag . Please how-to-implement-expandable-panels-in-android Check this .

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              xmlns:example="http://schemas.android.com/apk/res-auto"
              android:layout_width="fill_parent"
              android:layout_height="match_parent"
              xmlns:app="http://schemas.android.com/tools">

    <ExpandablePanel
        android:id="@+id/expandablePanel"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        example:collapsedHeight="50dip"
        example:content="@+id/group_layout"
        example:handle="@+id/group_layout"
        example:isviewgroup="true"
        example:viewgroup="@+id/childLayout" >

        <LinearLayout
            android:layout_width="match_parent"
            android:id="@+id/group_layout"
            android:padding="10dp"
            android:orientation="horizontal"
            android:layout_height="wrap_content">

        </LinearLayout>



        <LinearLayout
            android:layout_marginLeft="35dp"
            android:layout_width="match_parent"
            android:id="@+id/childLayout"
            android:padding="10dp"
            android:orientation="horizontal"
            android:layout_height="wrap_content">
        </LinearLayout>
    <ExpandablePanel>

</LinearLayout>

Upvotes: 1

Related Questions