Android: can height of SlidingDrawer be set with wrap_content? Android: can height of SlidingDrawer be set with wrap_content? android android

Android: can height of SlidingDrawer be set with wrap_content?


The onMeasure() method of the SlidingDrawer class basically overrides the layout modes to fill_parent, this is why layout_height="wrap_content" is not working.

To get around this, you can extend SlidingDrawer with a re-implemented onMeasure() method that honors the layout_width and layout_height attributes. You can then use this custom class in your XML layout by replacing <SlidingDrawer ...> with <fully.qualified.package.ClassName ...>.

Note that since the drawer will no longer be filling the parent layout, you will have to enclose it in a LinearLayout with the gravity attribute set to the edge where the drawer should be.

Below are a class I have created for this purpose and an example layout.

WrappingSlidingDrawer class :

import android.content.Context;import android.util.AttributeSet;import android.view.View;import android.widget.SlidingDrawer;public class WrappingSlidingDrawer extends SlidingDrawer {    public WrappingSlidingDrawer(Context context, AttributeSet attrs, int defStyle) {        super(context, attrs, defStyle);        int orientation = attrs.getAttributeIntValue("android", "orientation", ORIENTATION_VERTICAL);        mTopOffset = attrs.getAttributeIntValue("android", "topOffset", 0);        mVertical = (orientation == SlidingDrawer.ORIENTATION_VERTICAL);    }    public WrappingSlidingDrawer(Context context, AttributeSet attrs) {        super(context, attrs);        int orientation = attrs.getAttributeIntValue("android", "orientation", ORIENTATION_VERTICAL);        mTopOffset = attrs.getAttributeIntValue("android", "topOffset", 0);        mVertical = (orientation == SlidingDrawer.ORIENTATION_VERTICAL);    }    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        int widthSpecMode = MeasureSpec.getMode(widthMeasureSpec);        int widthSpecSize =  MeasureSpec.getSize(widthMeasureSpec);        int heightSpecMode = MeasureSpec.getMode(heightMeasureSpec);        int heightSpecSize =  MeasureSpec.getSize(heightMeasureSpec);        if (widthSpecMode == MeasureSpec.UNSPECIFIED || heightSpecMode == MeasureSpec.UNSPECIFIED) {            throw new RuntimeException("SlidingDrawer cannot have UNSPECIFIED dimensions");        }        final View handle = getHandle();        final View content = getContent();        measureChild(handle, widthMeasureSpec, heightMeasureSpec);        if (mVertical) {            int height = heightSpecSize - handle.getMeasuredHeight() - mTopOffset;            content.measure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(height, heightSpecMode));            heightSpecSize = handle.getMeasuredHeight() + mTopOffset + content.getMeasuredHeight();            widthSpecSize = content.getMeasuredWidth();            if (handle.getMeasuredWidth() > widthSpecSize) widthSpecSize = handle.getMeasuredWidth();        }        else {            int width = widthSpecSize - handle.getMeasuredWidth() - mTopOffset;            getContent().measure(MeasureSpec.makeMeasureSpec(width, widthSpecMode), heightMeasureSpec);            widthSpecSize = handle.getMeasuredWidth() + mTopOffset + content.getMeasuredWidth();            heightSpecSize = content.getMeasuredHeight();            if (handle.getMeasuredHeight() > heightSpecSize) heightSpecSize = handle.getMeasuredHeight();        }        setMeasuredDimension(widthSpecSize, heightSpecSize);    }    private boolean mVertical;    private int mTopOffset;}

Example layout (assuming WrappingSlidingDrawer is in package com.package) :

<FrameLayout android:layout_width="fill_parent"             android:layout_height="fill_parent">    ... stuff you want to cover at full-size ...    <LinearLayout android:layout_width="fill_parent"              android:layout_height="fill_parent"              android:gravity="bottom"              android:orientation="vertical">        <com.package.WrappingSlidingDrawer android:layout_width="fill_parent"                           android:layout_height="wrap_content"                           android:content="@+id/content"                           android:handle="@+id/handle">            ... handle and content views ...        </com.package.WrappingSlidingDrawer>    </LinearLayout></FrameLayout>


just set to pmargin in sliding drawer in your xml

android:layout_marginTop="50dip"


seydhe's answer has a small issue.

The first argument to the getAttributeIntValue needs to be the full namespace, not just "android". So the code snippet should be:

final String xmlns="http://schemas.android.com/apk/res/android";int orientation = attrs.getAttributeIntValue(xmlns, "orientation", SlidingDrawer.ORIENTATION_VERTICAL); mTopOffset = attrs.getAttributeIntValue(xmlns, "topOffset", 0);

I was having trouble getting this to work with a horizontal sliding drawer until I realized that it was not finding the orientation attribute and was therefore treating it as vertical.