» Программирование Android

Иконки для пунктов меню в 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 в списке, так что не нужно никаких дополнительных извлечений или преобразований. А вот результат написанного кода:

Sasha Sas
2015-09-15 09:25:57
Просто и понятно. Спасибо.