Пользовательские блесны / выпадающее меню
В приложении Astrid Tasks есть кнопка. При нажатии на кнопку появляется выпадающее меню.
Это в основном спиннер, но в виде выпадающего списка.
Кто-нибудь знает, как сделать что-то подобное? Это виджет, который я просто не вижу?
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.
Спасибо за использование Астрид!