Пользовательские блесны / выпадающее меню


В приложении Astrid Tasks есть кнопка. При нажатии на кнопку появляется выпадающее меню.

Введите описание изображения здесь

Введите описание изображения здесь

Это в основном спиннер, но в виде выпадающего списка.

Кто-нибудь знает, как сделать что-то подобное? Это виджет, который я просто не вижу?

1 19

1 ответ:

Как оригинальный автор этого (я один из основных разработчиков Android для Astrid), я был бы рад поделиться тем, как Астрид это делает. Я выложу основы здесь, но вы можете найти более подробную информацию в нашем репозитории github (https://github.com/todoroo/astrid основная идея состоит в том, чтобы расширить QuickActionWidget GreenDroid, как предлагает Хенри. Подкласс выглядит примерно так:

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>

Тогда вы можете просто добавить простого помощника метод класса popover для добавления представлений (т. е. строк с дополнительными слушателями) в основной текст popover:

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

После создания экземпляра всплывающего окна вы можете показать его, вызвав

menuPopover.show(anchorView);

Это несколько упрощенная версия - на практике мы прикрепляем некоторую дополнительную информацию, слушателей и т. д. к этим представлениям, чтобы заставить их действительно делать что-то при нажатии. Если вы хотите, вы можете проверить полный код на https://github.com/todoroo/astrid - класс является ком.Тодору.Астрид.пользовательский интерфейс.MainMenuPopover.

Спасибо за использование Астрид!