Как стать автором
Поиск
Написать публикацию
Обновить

Как я ботал андроид

Программирование отличается от других сфер деятельности, пожалуй, тем, что если бы «in real life» можно было бы наступить на такое количество граблей, набить столько шишек, как при общении с очередной development environment, то на бедном прогере и живого места не осталось бы. И ничего не поделать, чем больше багов я повидал, тем лучше мой код.

Но когда ты делаешь ошибку, сделанную еще полгода назад, это печально. Недавно я начал изучать андроид, но началась сессия, работа, и все приостановилось. А теперь не помню того, что добывал с такими потом и кровью. Вообще странно, когда я, будучи еще младшекурсником, писал всякие проекты на Qt, SDK от всяких вендоров, просто учил Java, не было столько тупых затыков, сколько их принес мне на блюдечке андроид. Сегодня вот целый день парился из-за одной строчки. Решено: буду вести лог полученных опытных знаний, чтобы не терять их и лучше закреплять. Уверен, что хотя бы одному начинающему android-программисту эти логи пригодятся (мне). Мб кто-то найдет хорошие вопросы для собеседования.


Вот вздумалось сегодня сделать GridView со списком установленных приложений и возможностью множественного выбора.

Все оч просто, нужны только:

1. mGrid.setChoiceMode(GridView.CHOICE_MODE_MULTIPLE_MODAL)

2. Адаптер, который будет поставлять Checkable-элементы

3. Реализованный интерфейс MultiChoiceModeListener, который собсно отвечает только за логику акшн-бара.

Все! Как показывают логи, для каждого элемента сетки вызывается метод setChecked(boolean) при каждой его перерисовке. Стоит чекнуть один элемент, перерисуются и все остальные на экране. Как я долго хотел присобачить свой костыль в виде какого-нибудь OnItemClickListener, который сам будет переключать checked/unchecked для элементов сетки…

Но и тут оказалось свое но. В адаптер я подал кастомный checkable view, который я выдувал из XML. «Случайно» я поставил android:clickable="true", после этого ничего больше не кликалось, не чекалось и вообще, и логи стали немыми, вызывается setChecked(false) и только при прокрутке.


Теперь о кастомных View. В документации оказалось все намного прозрачнее, чем на деле. Я всего-то хотел отнаследовать LinearLayout с интерфейсом Checkable. На Stackoverflow это оказалось популярным:

1. Класс, описывающий кастом вью должен быть Static. Оу… почти очевидно.

2. Если надо, прописываешь свои кастомные атрибуты в resources. А если НЕ надо? Оказывается, можно и не трогать тогда ничего.

3. Отнаследовался от стандартного view и передаешь в XML нечто вроде android:layout_width? Будь добр создать на этот случай и конструктор MyCustomStuff(Context context, AttributeSet attr) { super(context, attr); ... } Логично, но было уже не так очевидно.

4. Про внутренние классы в документации тоже сказали, только вот писать, оказывается нужно в кавычках, типа:

...

5. Ну, не забываем правильно указывать xmlns.

Выяснилась еще грубая ошибка. Ни в какой AdapterView нельзя вручную запихать children view. Вылетает UnsupportedOperationException: addView(View, LayoutParams) is not supported in AdapterView. У меня это возникло в inflater.inflate(R.layout.item, parent, true). Случаи, когда так можно накосячить, описали тут.


По мелочи еще: все атрибуты, выставляемые в коде, берут значения в пикселях, не в dp, sp или еще в чем. Поэтому для перевода dp в пиксели хорошо делать так: int value = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp_in_float, getResources().getDisplayMetrics());

Спать.
Теги:
Хабы:
Данная статья не подлежит комментированию, поскольку её автор ещё не является полноправным участником сообщества. Вы сможете связаться с автором только после того, как он получит приглашение от кого-либо из участников сообщества. До этого момента его username будет скрыт псевдонимом.