web-dev-qa-db-ja.com

Android:SlidingDrawerの高さをwrap_contentで設定できますか?

全画面幅を占めるSlidingDrawerを実装しようとしていますが、その高さはその内容によって動的に決定されます。つまり、幅の場合は標準のfill_parentレイアウト動作、高さの場合はwrap_contentです。それはまさにレイアウトXML(下記参照)で指定した方法ですが、スライド式引き出しは常に全画面の高さまで開きます。コンテンツの高さはさまざまですが、通常は画面の高さの約半分しかないため、その下に大きな隙間ができます。コンテンツが画面の下部にきちんと収まるようにしたいです。

私はそれを修正するために考えることができるすべてを試してみましたが、今のところ何も機能していません。 SlidingDrawerlayout_heightを特定の値(たとえば、160dip)に設定した場合、それは機能しますが、それは必要ではありません。動的でなければなりません。もちろん、すべての子要素の高さもwrap_contentに設定されていることを確認しました。

SlidingDrawerのドキュメントはこれについて少しあいまいであり、私がどちらを求めているかを示す例は見つかりませんでした。誰かが私が間違っているところを見ることができるなら、あなたの助けに本当に感謝しています!

<RelativeLayout
    Android:layout_width="fill_parent"
    Android:layout_height="fill_parent" >

    <ViewFlipper
        Android:id="@+id/ImageFlipper"
        Android:layout_width="fill_parent"
        Android:layout_height="fill_parent" >

        <ImageView
            Android:id="@+id/imageView0"
            Android:layout_width="fill_parent"
            Android:layout_height="fill_parent"
            Android:scaleType="centerCrop" />

        <ImageView
            Android:id="@+id/imageView1"
            Android:layout_width="fill_parent"
            Android:layout_height="fill_parent"
            Android:scaleType="centerCrop" />

        <ImageView
            Android:id="@+id/imageView2"
            Android:layout_width="fill_parent"
            Android:layout_height="fill_parent"
            Android:scaleType="centerCrop" />

    </ViewFlipper>

    <SlidingDrawer
        Android:id="@+id/infoDrawer"
        Android:layout_width="fill_parent"
        Android:layout_height="wrap_content"
        Android:handle="@+id/infoDrawerHandle"
        Android:content="@+id/infoDrawerContent"
        Android:allowSingleTap="false"
        Android:layout_alignParentBottom="true"
        Android:orientation="vertical" >

        <!-- Sliding drawer handle -->
        <ImageView
            Android:id="@id/infoDrawerHandle"
            Android:src="@drawable/info_handle_closed"
            Android:layout_width="wrap_content" 
            Android:layout_height="wrap_content" />

        <!-- Sliding drawer content: a scroller containing a group of text views
        laid out in a LinearLayout -->
        <ScrollView
            Android:id="@id/infoDrawerContent"
            Android:background="@drawable/info_background"
            Android:layout_width="wrap_content"
            Android:layout_height="wrap_content"
            Android:fillViewport="false" >

            <LinearLayout
                Android:id="@id/infoDrawerContent"
                Android:orientation="vertical"
                Android:layout_width="wrap_content"
                Android:layout_height="wrap_content"
                Android:paddingRight="5dip" >

                <TextView
                    Android:id="@+id/infoTitle"
                    Android:layout_width="wrap_content"
                    Android:layout_height="wrap_content"
                    Android:textColor="#ffffff"
                    Android:textSize="16dip"
                    Android:textStyle="bold" />

                <TextView
                    Android:id="@+id/infoCreator"
                    Android:layout_width="wrap_content"
                    Android:layout_height="wrap_content"
                    Android:textColor="#ffffff"
                    Android:textSize="14dip"
                    Android:textStyle="italic"
                    Android:paddingBottom="10dip" />

                <TextView
                    Android:id="@+id/infoDescription"
                    Android:layout_width="wrap_content"
                    Android:layout_height="wrap_content"
                    Android:textColor="#ffffff"
                    Android:textSize="14dip"
                    Android:paddingBottom="10dip" />

                <TextView
                    Android:layout_width="wrap_content"
                    Android:layout_height="wrap_content"
                    Android:textColor="#ffcc00"
                    Android:textSize="14dip"
                    Android:textStyle="bold"
                    Android:text="@string/heading_pro_tip" />

                <TextView
                    Android:id="@+id/infoProTip"
                    Android:layout_width="wrap_content"
                    Android:layout_height="wrap_content"
                    Android:textColor="#ffcc00"
                    Android:textSize="14dip" />

            </LinearLayout>    

        </ScrollView>

    </SlidingDrawer>

</RelativeLayout>
56
Mark Whitaker

SlidingDrawerクラスのonMeasure()メソッドは、基本的にレイアウトモードを_fill_parent_にオーバーライドします。これが_layout_height="wrap_content"_が機能しない理由です。

これを回避するには、_layout_width_および_layout_height_属性を尊重する再実装されたonMeasure()メソッドでSlidingDrawerを拡張できます。その後、_<SlidingDrawer ...>_を_<fully.qualified.package.ClassName ...>_に置き換えることにより、XMLレイアウトでこのカスタムクラスを使用できます。

ドロワーは親レイアウトを埋めないため、引出しがあるべきEdgeに設定された重力属性を持つLinearLayoutでドロワーを囲む必要があることに注意してください。

以下は、この目的のために作成したクラスとレイアウトの例です。

WrappingSlidingDrawerクラス:

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

レイアウト例(WrappingSlidingDrawerがパッケージ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>
_
126
seydhe

あなたのXMLのスライド引き出しでpmarginに設定するだけです

Android:layout_marginTop="50dip"
5
A B

seydheの答えには小さな問題があります。

GetAttributeIntValueの最初の引数は、「Android」だけでなく、完全な名前空間である必要があります。したがって、コードスニペットは次のようになります。

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

水平方向のスライドドロワーでこれを機能させるのに問題がありましたが、それが方向属性を見つけられず、それを垂直として扱っていたことがわかりました。

5
museofwater

文字列をハードコーディングせずにパラメーターを読み取ることをお勧めします。

    int attrOrientation = Android.R.attr.orientation;
    int attrTopOffset = Android.R.attr.topOffset;

    int[] attrIds = new int [] {attrOrientation, attrTopOffset}; 

    TypedArray a = context.obtainStyledAttributes(attrs, attrIds);
    int orientation = a.getInt(0, SlidingDrawer.ORIENTATION_VERTICAL);
    topOffset = a.getDimension(1, 0);
    a.recycle(); 

    isVertical = (orientation == SlidingDrawer.ORIENTATION_VERTICAL);

別の問題はonMeasureにあります。

次のコードを使用しました。

    if (isVertical) {
        int height = heightSpecSize - handle.getMeasuredHeight() - topOffset;
        getContent().measure(MeasureSpec.makeMeasureSpec(widthSpecSize, MeasureSpec.UNSPECIFIED), MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY));
        heightSpecSize = handle.getMeasuredHeight() + topOffset + content.getMeasuredHeight();
        widthSpecSize = content.getMeasuredWidth();
        if (handle.getMeasuredWidth() > widthSpecSize) widthSpecSize = handle.getMeasuredWidth();
    } else {
        int width = widthSpecSize - handle.getMeasuredWidth() - topOffset;
        getContent().measure(MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(heightSpecSize, MeasureSpec.UNSPECIFIED));
        widthSpecSize = handle.getMeasuredWidth() + topOffset + content.getMeasuredWidth();
        heightSpecSize = content.getMeasuredHeight();
        if (handle.getMeasuredHeight() > heightSpecSize) heightSpecSize = handle.getMeasuredHeight();
    }
4
kingston

残念ながら、高さを設定することはできませんが、その反対です。 topOffset属性は、スライド式引き出しの高さを決定しますが、その高さではなく、何を削るかを決定します。

2
schwiz

わたしにはできる:

private SlidingDrawer rightSlidingPanel = null;

 @Override 
public void onCreate( Bundle savedInstanceState )
{
...
    rightSlidingPanel = (SlidingDrawer) findViewById( R.id.rightSlidingPanel );
    rightSlidingPanel.post( new Runnable() 
            {
                @Override
                public void run()
                {
                    rightSlidingPanel.getLayoutParams().width = findViewById( R.id.sliding_content2 ).getMeasuredWidth() + findViewById( R.id.sliding_handle ).getMeasuredWidth();
                }

            });
}

XMLレイアウト:

...
    <SlidingDrawer
            Android:id="@+id/rightSlidingPanel"
            Android:layout_width="wrap_content"
            Android:layout_height="match_parent"
            Android:layout_alignParentRight="true"
            Android:layout_alignParentTop="true"
            Android:allowSingleTap="true"
            Android:animateOnClick="true"
            Android:content="@+id/sliding_content"
            Android:handle="@+id/sliding_handle"
            Android:orientation="horizontal" >

            <Button
                Android:id="@+id/sliding_handle"
                style="@style/toolbar_button"
                Android:layout_width="30dp"
                Android:layout_height="wrap_content"
                Android:height="40dp"
                Android:text="&lt;"
                Android:width="25dp" />

            <LinearLayout
                Android:id="@+id/sliding_content"
                Android:layout_width="wrap_content"
                Android:layout_height="wrap_content"
                Android:gravity="top"
                Android:orientation="vertical" >

                <LinearLayout
                    Android:id="@+id/sliding_content2"
                    Android:layout_width="wrap_content"
                    Android:layout_height="match_parent"
                    Android:layout_gravity="center_vertical"
                    Android:layout_weight="1"
                    Android:gravity="center_horizontal" >

...
                </LinearLayout>
            </LinearLayout>
        </SlidingDrawer>
...
0
Alex K