Иконки для пунктов меню в Android-приложении
Важная составляющая пользовательского интерфейса, в том числе приложений для операционной системы Android – меню. Красивые иконки для каждого пункта меню – красивое, а часто и полезное дополнение для оболочки.
Простейший пример – привычное долгое нажатие на рабочем столе, после которого появляется диалог с выбором добавляемого элемента.
Мы рассмотрим создание диалогового окна, схожего вот с таким:
Сделать это не слишком сложно. Суть – для диалогового элемента нужно подставить правильный ContentProvider (предварительно написанный для данной цели). Рассмотрим код с комментариями, что он делает. Итак, ContentProvider возможных типов аккаунтов:
public final class AccountTypesProvider { public static List<AccountType> accountTypes = Collections.unmodifiableList(Arrays.asList( new AccountType(AccountType.TWITTER_ACCOUNT, "Twitter", R.drawable.twitter_icon_big), new AccountType(AccountType.FACEBOOK_ACCOUNT, "Facebook", R.drawable.facebook_icon_big), new AccountType(AccountType.BUZZ_ACCOUNT, "Google Buzz", R.drawable.buzz_icon_big), new AccountType(AccountType.LINKEDIN_ACCOUNT, "LinkedIn", R.drawable.linkedin_icon_big), new AccountType(AccountType.VKONTAKTE_ACOUNT, "ВКонтакте", R.drawable.vkontakte_icon_big) )); }
Строки кода выше – простая обертка вокруг списка возможных типов аккаунтов. Тип аккаунта – простой класс POJO, состоящий из идентификатора, являющегося константой, названия сервиса, а также идентификатора ресурса иконки для указанного сервиса.
А вот ListAdapter для отображения списка типов аккаунтов в указанном layout:
public final class AccountsTypesListAdapter extends ArrayAdapter<AccountType> { private Activity context; private List<AccountType> accountTypes; public AccountsTypesListAdapter(Activity context, List<AccountType> accountTypes) { super(context, R.layout.select_account_item, accountTypes); this.context = context; this.accountTypes = accountTypes; } @Override public View getView(int position, View convertView, ViewGroup parent) { LayoutInflater inflater = context.getLayoutInflater(); View row = inflater.inflate(R.layout.select_account_item, parent, false); TextView label = (TextView) row.findViewById(R.id.text_item); label.setText(accountTypes.get(position).title); ImageView icon = (ImageView) row.findViewById(R.id.icon_item); icon.setImageResource(accountTypes.get(position).bigIconId); return row; } }
В первую очередь, нам нужно переделать список типов, с которым будет происходить работа адаптера списка, в конструктор. Привязка каждого item к layout происходит в переопределенном методе getView(). В нем же загружается layout из прописанного ресурса, извлекаются виджеты, в которые записывается информация о конкретном элементе списка, индекс которого доступен автоматически через параметр position.
Данный ListAdapter работает со следующим layout:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="horizontal" android:layout_width="fill_parent" android:layout_height="fill_parent" android:padding="10px"> <ImageView android:id="@+id/icon_item" android:layout_width="wrap_content" android:layout_height="fill_parent"/> <TextView android:id="@+id/text_item" android:layout_width="wrap_content" android:layout_height="fill_parent" android:paddingLeft="10px" android:paddingTop="5px" android:textStyle="bold" android:textColor="#000000"/> </LinearLayout>
Единственное, что нужно сделать – привязать разработанный ListAdapter к конкретному диалоговому окну:
public static void showSelectAccountTypeDialog(Activity context, String title, OnClickListener dialogListener) { AlertDialog.Builder builder = new AlertDialog.Builder(context); builder.setTitle(title); builder.setAdapter(new AccountsTypesListAdapter(context, AccountTypesProvider.accountTypes), dialogListener); builder.create().show(); }
После этого в нужном месте вызывается Activity-диалог:
private void displaySelectAccountTypeDialog() { ApplicationDialogs.showSelectAccountTypeDialog(this, "Select network", new OnClickListener() { @Override public void onClick(DialogInterface dialogInterface, int selectedItemId) { setupAccount(selectedItemId); } }); }
После завершения диалог возвратит индекс выбранного item параметром selectedItemId в listener, указанный при вызове диалога. В нашем примере индекс будет совпадать с ID типа аккаунта – item в списке, так что не нужно никаких дополнительных извлечений или преобразований. А вот результат написанного кода:
Просто и понятно. Спасибо.