+67
- 01
- 02
- 03
- 04
- 05
- 06
- 07
- 08
- 09
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
public final class SomeActivity extends Activity {
@Override
protected Dialog onCreateDialog(int id) {
Dialog dialog = null;
if (id == DialogGenerator.SETTINGS_DIALOG) {
dialog = mDialogGenerator.createSettingsDialog();
} {
dialog = super.onCreateDialog(id);
}
return dialog;
}
@Override
protected void onPrepareDialog(int id, Dialog dialog) {
super.onPrepareDialog(id, dialog);
if (id == DialogGenerator.SETTINGS_DIALOG) {
mDialogGenerator.prepareSettingsDialog((AlertDialog) dialog, someBoolValue, someObjectValue);
}
}
}
public final class DialogGenerator {
public Dialog createSettingsDialog() {
int dialogId = SETTINGS_DIALOG;
int titleId = R.string.settingsTitle;
String[] itemsArray = getStringArray(R.array.settings);
ThreeTypeOptionsAdapter adapter = new ThreeTypeOptionsAdapter(mControllerAsActivity, itemsArray,
mCheckableOptions, mTwoTextOptions);
AlertDialogCallback dialogCallback = new AlertDialogCallback(mControllerAsDialogHost, dialogId);
AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(mControllerAsActivity);
dialogBuilder.setTitle(titleId);
// костыль
dialogBuilder.setSingleChoiceItems(itemsArray, 0, null);
// конец костыля
dialogBuilder.setAdapter(adapter, dialogCallback);
AlertDialog dialog = dialogBuilder.create();
setMainListenersOnDialog(dialog);
dialog.getListView().setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
return dialog;
}
public void prepareSettingsDialog(AlertDialog dialog, boolean someBoolValue, String someStringValue) {
//костыль
ListView dialogList = dialog.getListView();
dialogList.clearChoices();
dialogList.setItemChecked(POSITION_FOR_BOOL, someBoolValue);
//конец костыля
ThreeTypeOptionsAdapter adapter = (ThreeTypeOptionsAdapter) dialogList.getAdapter();
adapter.setAdditionalValue(POSITION_FOR_STRING, someStringValue);
}
}
Задача: показать диалог, внутри которого есть 3 типа ячеек: выделяемые с чекбоксом справа, невыделяемые с дополнительной надписью справа, обычные невыделяемые.
Примерно так:
Use GPS checkbox
Selected country Russia
Launch some activity
В комментах к методам я описал костыль:
Здравствуйте, дорогие друзья. Сегодня мы с вами поговорим об уникальном виде животных, которых открыли только в конце XX века. Это, дорогие друзья, Ява-обезьяны. Давайте дружно откроем сырцы Андроид-СДК, а именно - класс com.android.internal.app.AlertController .AlertParams - и метод createListView(AlertController). Видите, одна обезьяна решила, что нам будет удобней, если диалог автоматом задисмиссится, когда мы щёлкнем по элементу списка в CHOICE_MODE_NONE, и OnClickListener будет не null? А теперь давайте перейдём в android.app.AlertDialog.Builder. Видите, там другая обезьяна решила, что для multi-choice списка нам не потребуется хитроумный адаптер? Поэтому, дорогие друзья, когда мы поставили кастомный адаптер (setAdapter()) и сопроводили его слушателем, то какой бы мы choice mode не ставили после AlertDialog.Builder.create(), диалог дисмиссился. Поэтому, дорогие друзья, пришлось пойти на хитрость и вначале установить single choice (чтобы флаг mIsSingleChoice стал true), а потом уже ставить адаптер.
Запостил:
QuickNick,
20 Февраля 2013
Непоследовательность АПИ чаще всего проистекает из сжатых сроков и наличия нескольких параллельно работающих авторов библиотек, а также отсутсвие чётких гайдлайнов\политик, способных применяться по отношению к мелочам.
Спроектировать АПИ, удобное и достаточное во всех практических случаях, задача архисложная.
просто надо отдавать себе отчет, что это процесс длительный и многоитерационный, т.к. редко известна нужная функциональность.
конечно, можно быть опытным фанатом какого-либо подхода и строить API исходя из множества аналогичных задач, но... но не всегда применимо, исходя из 2х предпосылок:
1. универсальное API избыточно (чит.: громоздко, со всеми вытекающими) в большинстве случаев.
2. аскетичное API делает невозможными многие вещи, либо провоцирует на хаки и прочее говно.
для размышления: Linux Kernel API, WinAPI, API стандартных библиотек PHP, Java...
Разумеется есть моменты когда тебя выводят из себя, но надо понимать, что ты тоже не всем, мягко говоря, нравишься. Не далее как неделю назад у меня
был конфликт с нашим "scrum masterom", из-за презентации нашего продукта. Конфликт прошёл, ошибку устранены, презентация прошла на ура. Но почему я стал чаще просматривать вакансии в других конторах? ))
Не говоря уже о том, что obj-c версия PureMVC не нужна. Не в смысле в этом проекте, а в смысле вообще.
С другой стороны, это штатный функционал меню. Зачем-то же его сделали?
var buttonNormalBg = cc.Sprite.create(gameBtnStates[purchaseState][0]);
var labelNormal = cc.LabelBMFont.create(title, s_futura_medium_fnt);
labelNormal.setScale(0.5*font_size_muiti pler);
labelNormal.setAnchorPoint( cc.p(0.5, 0.5) );
labelNormal.setAlignment( cc.TEXT_ALIGNMENT_CENTER );
labelNormal.setColor(c_gameModeFont);
var btnSize = buttonNormalBg.getContentSize();
Придется вспомнить делфи, мать ее.
var buttonNormalBg = cc.Sprite.create(gameBtnStates[purchaseState][0]);
var labelNormal = cc.LabelBMFont.create(title, s_futura_medium_fnt);
labelNormal.setScale(0.5*font_size_muiti pler);
labelNormal.setAnchorPoint( cc.p(0.5, 0.5) );
labelNormal.setAlignment( cc.TEXT_ALIGNMENT_CENTER );
labelNormal.setColor(c_gameModeFont);
var btnSize = buttonNormalBg.getContentSize();
Меня тут в час ночи выудили сегодня, я там буду.
Ибо там есть вполне годный PreferenceActivity который выглядит как и любое другое окно настроек в системе (что, имхо, очень круто, ибо унификация во все поля), описывается через xml, и в моем простейшем случае с govnotify даже не потребовал кода (кроме небольшого бойлерплейта).
XML описание: https://github.com/bormand/govnotify/blob/master/Govnotify/res/xml/preferences.xml
ДИЗАЙНЕРОПРОБЛЕМЫ тут в том, что дизайнеру захотелось выебнуться, показать настройки в диалоге, и он заставил программистов делать самопальные настройки.
P.S. Мое мнение никак не может считаться авторитетным. Одной серьезной проги (настройки пришлось делать самопальными, ДИЗАЙНЕРОПРОБЛЕМЫ, да), и вот этой игрушечной говнотифи явно не достаточно для того чтобы авторитетно судить о платформе.
«Java is a DSL for converting large XML files into long stacktraces»
С динамическими пунктами или извращенными типами настроек, конечно, придется повозиться, но они и нужны реже статики.
Что может быть удобней?
А вот убогое поделие под названием XSLT - это еще тот ужас.
Типичное ооп-говно. И это как раз пример того что js не виноват. Просто проектировзик компонент верноятно был болен жабизмом.
Как верно подметил Роман:
>вспоминаю Swing как страшный сон. Думается, XML гораздо компактнее.
Всю полезную информацию можно сохранить таким образом:
Юзая extend и настройки лейблов по дефолту можно далее укорачивать код.
Зато с помощью XSLT можно преобразовывать XSLT в XSLT, а затем проверять его по XSD схеме, преобразованной из XML с помощью XSLT!
Возможно проще чем на других языках.
http://www2.informatik.hu-berlin.de/~obecker/XSLT/quine/quine.xslt.html
QML смотрит на вас с негодованием. Там интерфейс описывается вполне декларативненько, не то что в коде про createGameButton.
Дык там и скрипты к этому QML на... js. Очень удобный инструмент на самом деле для всяких гламурных программ и несложных 2д игрушек. А вот разрабатывать с его помощью динамическую опердень с кучей форм кнопочек полей и базой данных я бы не стал, ибо стандартных контролов там кот наплакал.
Есть в этом сильное сходство с S-выражениями.