четверг, 23 сентября 2010 г.

Баг в Android или проблема Spinner в полноэкранном режиме

Вчера мой знакомый Максим Уханов написал мне в GTalk по поводу одной необычной проблемы. Он разрабатывает некое полноэкранное приложение, которое вызывает диалог c виджетом Spinner. И все было бы классно, но проявился баг - при нажатии на Spinner в полноэкранном режиме при появлении диалога выбора на 1-2 секунды появляется Status Bar. Это ситуация возникает в том случае, если в Spinner располагается большое количество элементов. Выглядит это примерно так:


Я начал исследовать исходные коды Spinner и обнаружил, что при отображении диалога с элементами при нажатии на Spinner создается диалог, который не учитывает вариант полноэкранного отображения. Выглядит код следующим образом.
@Override
public boolean performClick() {
boolean handled = super.performClick();
if (!handled) {
handled = true;
Context context = getContext();
final DropDownAdapter adapter = new DropDownAdapter(getAdapter());
AlertDialog.Builder builder = new AlertDialog.Builder(context);
if (mPrompt != null) {
builder.setTitle(mPrompt);
}
mPopup = builder.setSingleChoiceItems(adapter,
getSelectedItemPosition(), this).show();
}
return handled;
}

В голову пришло только одно решение, это создать свой класс на основе Spinner и перекрыть его метод performClick(). Но сложность заключается в том, что ссылка на диалог Spinner сохраняется в приватной переменной mPopup. Эту проблему мы обошли, используя рефлексию для доступа к этой переменной после создания диалога и вызова необходимого метода для установки свойств диалога для корректного отображения его в полноэкранном режиме. Чтобы повысить безопасность использования такого метода решения нашей проблемы, мы абстрагировались от названия поля mPopup и просто по циклу ищем переменную типа AlertDialog, таким образом даже если разработчики поменяют название переменной, наш код будет работать. Ниже представлен код нового класса:
package maximyudin.spinnerbug;

import java.lang.reflect.Field;

import android.app.AlertDialog;
import android.content.Context;
import android.util.AttributeSet;
import android.view.WindowManager;
import android.widget.Spinner;

public class NoTitleSpinner extends Spinner {
public NoTitleSpinner(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}

public NoTitleSpinner(Context context, AttributeSet attrs) {
super(context, attrs);
}

public NoTitleSpinner(Context context) {
super(context);
}

@Override
public boolean performClick() {
boolean status = super.performClick();
Field privateStringField = null;
try {
Field[] fields = Spinner.class.getDeclaredFields();
for (Field field : fields) {
if (field.getType().getName().equals(AlertDialog.class.getName())) {
privateStringField = field;
break;
}
}
if (privateStringField == null) {
return false;
}

privateStringField.setAccessible(true);
AlertDialog dialog = (AlertDialog) privateStringField.get(this);
dialog.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
} catch (IllegalArgumentException e) {
} catch (IllegalAccessException e) {
}
return status;
}
}

Теперь вам вместо Spinner надо в коде и в xml использовать наш NoTitleSpinner.
Полностью код проекта выложен тут.

P.S. Мы добавили этот баг в баг-репорт - следите за новостями тут - http://code.google.com/p/android/issues/detail?id=11419

вторник, 3 августа 2010 г.

Обзор Gigabyte GSmart G1305 (Codfish)

Некоторое время назад ко мне на тестирования попал тестовый образец первого смартфона от Gigabyte - GSmart G1305. По внешнему виду он меня изначально сильно испугал. Выглядел, как некачественная китайская подделка. Но после пристального рассмотрения аппарат показался мне довольно интересным.



Сразу, что бросилось в глаза - это сильно пачкающийся экран, на первой фотографии это хорошо заметно. Для начала приведу небольшую характеристику девайса. Аппарат базируется на ОС Android 1.6 (говорят будет апдейт до 2.1). Процессор у устройства довольной неплохой для такой ценовой категории - 600 МГц (Qualcomm MSM7227). Постоянная и оперативная память по 256 Мб, есть поддержка Bluetooth 2.0, Wi-Fi (802.11b/g), GPS. Девайс оснащен сенсорным экраном в 3,2 дюйма и 5 Мп камерой (с автофокусом и фотовспышкой). Также, что не маловажно, есть трекбол. Многие считают этот элемент управления бесполезным, но он очень удобен при навигации в ландшафтном режиме.

суббота, 19 июня 2010 г.

Мои статьи в PDF

Добавил новый блок на сайте Мои статьи в PDF. Находится он справа, думаю заметите. Сделано это для того, чтобы вам не искать по всему блогу эти статьи, а быстро получать к ним доступ в удобном виде. Там будут постоянные ссылки на мои статьи в формате PDF для печати. Пока я подготовил только одну статью, которую недавно писал о Toast. Немного ее поредактировал, но суть осталась такая же.

P.S. Постепенно выложу свои старые статьи, ну и конечно буду писать новые.

вторник, 11 мая 2010 г.

Использование NumberPicker и кастомизация его внешнего вида

Внимание. Данное решение с NumberPicker не работает на прошивках 2.2 и выше. Другое решение - взять класс NumberPicker из исходных кодов Android и использовать его. Постараюсь переписать статью в ближайшее время.

Наверно многие из вас использовали такие виджеты, как DatePicker и TimePicker. Но функциональность этих виджетов ограничена возможностью выбора даты и времени, но мне захотелось большего - использовать данную функциональность для выбора любого числа в заданном диапазоне (как в контроле NumericUpDown в C#). Такая возможность существует. Виджеты DatePicker и TimePicker основаны на системном виджете NumberPicker, который вы не можете использовать из коробки. Для его использования потребуется написать небольшое количество кода.

Для начала добавим NumberPicker в наш главный layout, xml-код выглядит следующим образом:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<com.android.internal.widget.NumberPicker
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/numTestNumberPicker"
android:layout_centerInParent="true">
</com.android.internal.widget.NumberPicker>
</RelativeLayout>

воскресенье, 4 апреля 2010 г.

Подкаст о началах разработки под Android

Сегодня вышел подкаст, записанный буквально сегодня с утра.

В помощь начинающему разработчику под OS Android: интервью с Максимом Юдиным (JQ Soft)

- Небольшой рассказ о Максиме Юдине, JQ Soft и их программах
- Какие бывают средства разработки для Android
- Требования к начинающему разработчику: что знать, что читать, где искать
- Как заработать на разработке ПО под Android, способы и хитрости
- Какое будущее у разработки под Android OS

Послушать

среда, 31 марта 2010 г.

Использование стороннего шрифта в TextView

В поставку Android входит всего 3 шрифта для использования программистами - Sans, Serif, Monospace, которые вы обычно устанавливаете через свойство android:typeface. Иногда возникает необходимость использовать сторонний шрифт, допустим DS-Digital Bold. Делается это довольно просто.

Вы должны положить ваш шрифт в папку проекта по следующему пути - assets/fonts, папка fonts не обязательна, можно положить непосредственно в assets.

Чтобы использовать этот шрифт для текста в TextView необходимо написать следующий код:
TextView tvName = (TextView) findViewById(R.id.tvName);
Typeface digitalFont = Typeface.createFromAsset(this.getAssets(), "fonts/digital.ttf");
tvName.setTypeface(digitalFont);
Результат показан на картинке ниже.

воскресенье, 28 марта 2010 г.

Оповещение пользователя: Toast

Начинаю цикл статей о способах оповещения пользователя. Цикл рассчитан на новичков. Существует три способа оповещения пользователя: через Toast, через Notification и через различные виды Dialog. Сегодня я расскажу об использовании первого типа оповещения - Toast.

пятница, 5 февраля 2010 г.

Пресс-релиз клиента SuperJob.ru для Android готов

     


После двух месяцев с момента окончания разработки и помещения его на Android Market наконец-то SuperJob.ru написали пресс-релиз к моему приложению. Приложение можно скачать, как на их сайте, так и в Android Market и SlideMe.org.

понедельник, 4 января 2010 г.

SuperJob - официальный клиент для SuperJob.ru


Сравнительно недавно сделал бесплатного клиента для портала по поиску работы SuperJob.ru. Клиент официальный, сделан специально для SuperJob на заказ. В Android Market клиент висит сравнительно давно, популярность пока очень мала, но, надеюсь, после официального пресс-релиза, который планируется после новогодних праздников, количество скачиваний возрастет. Также клиент можно скачать с сайта SlideMe.org.

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

Ниже приведу скриншоты программы, чтобы наглядно был виден ее функционал.