web-dev-qa-db-ja.com

カスタムスピナー/ドロップダウンメニュー

アプリAstridTasksには、ボタンがあります。ボタンを押すと、ドロップダウンメニューが表示されます。

enter image description here

enter image description here

これは基本的にスピナーですが、ドロップダウンリスト形式です。

誰かが似たようなことをする方法を知っていますか?これは私が見ないウィジェットですか?

19
Cole

これの元の作者として(私はAstridの主要なAndroid開発者の1人です)Astridがどのようにそれを行うかを共有できれば幸いです。ここに基本を投稿しますが、あなたは詳細については、githubリポジトリ( https://github.com/todoroo/astrid )を参照してください。基本的な考え方は、hanryが提案するようにGreenDroidのQuickActionWidgetを拡張することです。サブクラスは次のようになります。

public class MenuPopover extends QuickActionWidget {

    protected DisplayMetrics metrics;
    protected LinearLayout content;

    public MenuPopover(Context context) {
        super(context);
        setContentView(R.layout.my_layout);

        content = (LinearLayout) getContentView().findViewById(R.id.content);
        metrics = context.getResources().getDisplayMetrics();

        setFocusable(true);
        setTouchable(true);
    }

    @Override
    protected void populateQuickActions(List<QuickAction> quickActions) {
        // Do nothing
    }

    @Override
    protected void onMeasureAndLayout(Rect anchorRect, View contentView) {
        contentView.setLayoutParams(new     FrameLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,     ViewGroup.LayoutParams.WRAP_CONTENT));
        contentView.measure(MeasureSpec.makeMeasureSpec(getScreenWidth(),     MeasureSpec.EXACTLY),
                ViewGroup.LayoutParams.WRAP_CONTENT);

        int rootHeight = contentView.getMeasuredHeight();

        int offsetY = getArrowOffsetY();
        int dyTop = anchorRect.top;
        int dyBottom = getScreenHeight() - anchorRect.bottom;

        boolean onTop = (dyTop > dyBottom);
        int popupY = (onTop) ? anchorRect.top - rootHeight + offsetY : anchorRect.bottom -  offsetY;

        setWidgetSpecs(popupY, onTop);
    }
}

レイアウトファイルmy_layout.xmlは非常にシンプルです。

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
    xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:layout_width="wrap_content"
    Android:layout_height="wrap_content">
    <RelativeLayout
        Android:layout_width="wrap_content"
        Android:layout_height="wrap_content"
        Android:paddingLeft="10dip">

        <LinearLayout
                Android:id="@+id/content"
                Android:layout_width="fill_parent"
                Android:layout_height="wrap_content"
                Android:layout_below="@+id/gdi_arrow_up"
                Android:orientation="vertical"/>

        <ImageView
            Android:id="@+id/gdi_arrow_up"
            Android:layout_width="27dip"
            Android:layout_height="27dip"
            Android:layout_marginLeft="-10dip"
            Android:scaleType="fitCenter"
            Android:layout_marginBottom="-8dip"
            Android:src="?attr/asListArrowUp" />

        <ImageView
            Android:id="@+id/gdi_arrow_down"
            Android:layout_width="27dip"
            Android:layout_height="27dip"
            Android:scaleType="fitCenter"
            Android:layout_marginBottom="-8dip"
            Android:layout_below="@Android:id/list"/>

        </RelativeLayout>
</FrameLayout>

次に、ポップオーバークラスに単純なヘルパーメソッドを追加するだけで、ポップオーバーの本体にビュー(つまり、オプションのリスナーを含む行)を追加できます。

public void addViewToContent(View v, OnClickListener listener) {
    content.addView(v);
    if (listener != null) {
        v.setOnClickListener(listener);
    }
}

ポップアップのインスタンスを作成した後、次を呼び出すことで表示できます。

menuPopover.show(anchorView);

これはやや簡略化されたバージョンです。実際には、これらのビューにいくつかの追加情報やリスナーなどを添付して、クリックされたときに実際に動作するようにします。必要に応じて、完全なコードを https://github.com/todoroo/astrid で確認できます-クラスはcom.todoroo.astrid.ui.MainMenuPopoverです。

Astridをご利用いただきありがとうございます。

55
sboz88