Pull to refresh

Диалоговое окно Android с «иконифицированным» меню

Development for Android *
Некоторое время назад меня увлекла идея разработки приложений под платформу Android. Дабы не заниматься изучением платформы на простых hello-world программках решил сделать что-то такое, что позволило бы освоиться с UI частью фреймворка, работой с БД, сетью и социальными сервисами.
Идея была придумана до одурения простая и я бы даже сказал, тупая. И вот когда я начал что-то делать то тут резко захотелось мне сделать красивое диалоговое окно с выбором пункта меню с иконками. Такой диалог присутствует в стандартном Андроиде, например, долгий тап на рабочем столе открывает диалог выбора добавляемого контента (виджет, обоины и т.д.). Итак, добро пожаловать под кат…


Как было упомянуто выше передо мной стояла задача сделать диалоговое окно типа такого:

Погуглив некоторое время и почитав официальные доки по платформе я так и не нашел, как реализовать подобный диалог. После некоторого времени копания я нашел результат, который быстрее всего будет очевидным для опытных Андроид-разработчиков.
Ответ оказался прост и лежал он на поверхности. Суть его состоит в том, что для диалогового билдера нужно просто подставить соответствующий провайдер данных (есстественно, провайдер нужно самим написать).
Итак, сейчас будет некоторое количество кода с комментариями о том, что происходит.

Список (провайдер) возможных типов аккаунтов


  1. public final class AccountTypesProvider {
  2.   public static List<AccountType> accountTypes = Collections.unmodifiableList(Arrays.asList(
  3.       new AccountType(AccountType.TWITTER_ACCOUNT, "Twitter", R.drawable.twitter_icon_big),
  4.       new AccountType(AccountType.FACEBOOK_ACCOUNT, "Facebook", R.drawable.facebook_icon_big),
  5.       new AccountType(AccountType.BUZZ_ACCOUNT, "Google Buzz", R.drawable.buzz_icon_big),
  6.       new AccountType(AccountType.LINKEDIN_ACCOUNT, "LinkedIn", R.drawable.linkedin_icon_big),
  7.       new AccountType(AccountType.VKONTAKTE_ACOUNT, "ВКонтакте", R.drawable.vkontakte_icon_big)
  8.   ));
  9. }
* This source code was highlighted with Source Code Highlighter.

Это простая обертка вокруг списка возможных типов аккаунтов. Тип аккаунта здесь простой POJO класс, который состоит из идентификатора (константа), названия сервиса и идентификатора ресурса иконки для данного типа сервиса.

ListAdapter для отображения списка типов аккаунтов в заданном layout'е


  1. public final class AccountsTypesListAdapter extends ArrayAdapter<AccountType> {
  2.   private Activity context;
  3.   private List<AccountType> accountTypes;
  4.   
  5.   public AccountsTypesListAdapter(Activity context, List<AccountType> accountTypes) {
  6.     super(context, R.layout.select_account_item, accountTypes);
  7.     
  8.     this.context = context;
  9.     this.accountTypes = accountTypes;
  10.   }
  11.   
  12.   @Override
  13.   public View getView(int position, View convertView, ViewGroup parent) {
  14.     LayoutInflater inflater = context.getLayoutInflater();
  15.     View row = inflater.inflate(R.layout.select_account_item, parent, false);
  16.     
  17.     TextView label = (TextView) row.findViewById(R.id.text_item);
  18.     label.setText(accountTypes.get(position).title);
  19.     
  20.     ImageView icon = (ImageView) row.findViewById(R.id.icon_item);
  21.     icon.setImageResource(accountTypes.get(position).bigIconId);
  22.     
  23.     return row;
  24.   }
  25. }
* This source code was highlighted with Source Code Highlighter.


Для начала нужно передать в конструктор список типов, с которым будет работать адаптер списка. Привязка конкретного item'а к лэйауту происходит в переопределенном методе getView(). В нем загружается лэйаут из указанного ресурса, извлекаются виджеты и в них записываются данные об конкретном элементе списка. Кстати, индекс этого элемента автоматически доступен через параметр position.

Данный лист-адаптер работает с таким вот лэйаутом


  1. <?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3.   android:orientation="horizontal" android:layout_width="fill_parent"
  4.   android:layout_height="fill_parent" android:padding="10px">
  5.   
  6.   <ImageView android:id="@+id/icon_item" android:layout_width="wrap_content"
  7.     android:layout_height="fill_parent"/>
  8.     <TextView android:id="@+id/text_item" android:layout_width="wrap_content"
  9.       android:layout_height="fill_parent" android:paddingLeft="10px"
  10.       android:paddingTop="5px" android:textStyle="bold"
  11.       android:textColor="#000000"/>
  12. </LinearLayout>
* This source code was highlighted with Source Code Highlighter.


Все, что теперь осталось — это привязать разработанный лист-адаптер к конкретному диалоговому окну
  1. public static void showSelectAccountTypeDialog(Activity context, String title, OnClickListener dialogListener) {
  2.     AlertDialog.Builder builder = new AlertDialog.Builder(context);
  3.     builder.setTitle(title);
  4.     builder.setAdapter(new AccountsTypesListAdapter(context, AccountTypesProvider.accountTypes), dialogListener);
  5.     builder.create().show();
  6.   }
* This source code was highlighted with Source Code Highlighter.


и вызвать в нужном месте activity диалог
  1. private void displaySelectAccountTypeDialog() {
  2.     ApplicationDialogs.showSelectAccountTypeDialog(this, "Select network", new OnClickListener() {
  3.       @Override
  4.       public void onClick(DialogInterface dialogInterface, int selectedItemId) {
  5.         setupAccount(selectedItemId);
  6.       }
  7.     });
  8.   }
* This source code was highlighted with Source Code Highlighter.


Диалог после своего завершения вернет индекс выбранного item'а параметром selectedItemId в листенер, который указан при вызове диалога. В данном простом случае этот индекс будет совпадать с ID типа аккаунта (item'а в списке), поэтому никаких дополнительных преобразований или извлечений не требуется. Для моей задачи этого индекса более чем достаточно.

В итоге у меня получился такой вот симпатичный диалог


Может я в данном топике просто описал прописные истины, может нет. Решать, как говорится, Вам, Хабраюзеры…

Спасибо и удачи всем в увлекательном процессе разработки под Android-платформу ;)
Tags: AndroidAndroid SDK
Hubs: Development for Android
Total votes 87: ↑81 and ↓6 +75
Comments 38
Comments Comments 38

Popular right now