1. Java / Говнокод #12615

    +67

    1. 01
    2. 02
    3. 03
    4. 04
    5. 05
    6. 06
    7. 07
    8. 08
    9. 09
    10. 10
    11. 11
    12. 12
    13. 13
    14. 14
    15. 15
    16. 16
    17. 17
    18. 18
    19. 19
    20. 20
    21. 21
    22. 22
    23. 23
    24. 24
    25. 25
    26. 26
    27. 27
    28. 28
    29. 29
    30. 30
    31. 31
    32. 32
    33. 33
    34. 34
    35. 35
    36. 36
    37. 37
    38. 38
    39. 39
    40. 40
    41. 41
    42. 42
    43. 43
    44. 44
    45. 45
    46. 46
    47. 47
    48. 48
    49. 49
    50. 50
    51. 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

    Комментарии (48) RSS

    • В 7й строке else при копаписте потерялся, или его там не было изначально?
      Ответить
    • это сайт говнокодов, а не рефератов. Нахуя столько текста?
      Ответить
    • Описание гавно, таких умников всегда терпеть не мог. Когда они лажают - это проба пера а если ктото другой - тупой придурок.
      Ответить
      • Откроем клуб избивания подобных ногами?
        Ответить
        • Вы просто не умеете их готовить ) Вот, например, у меня на QuickNick'а компромат есть, это помогает:)
          Ответить
    • <Language>-обезьян хватает для любого более-менее популярного Language.

      Непоследовательность АПИ чаще всего проистекает из сжатых сроков и наличия нескольких параллельно работающих авторов библиотек, а также отсутсвие чётких гайдлайнов\политик, способных применяться по отношению к мелочам.

      Спроектировать АПИ, удобное и достаточное во всех практических случаях, задача архисложная.
      Ответить
      • На момент написания коммента я был более нетерпимым к таким недоработкам.
        Ответить
      • > Спроектировать АПИ, удобное и достаточное во всех практических случаях, задача архисложная.
        просто надо отдавать себе отчет, что это процесс длительный и многоитерационный, т.к. редко известна нужная функциональность.
        конечно, можно быть опытным фанатом какого-либо подхода и строить API исходя из множества аналогичных задач, но... но не всегда применимо, исходя из 2х предпосылок:
        1. универсальное API избыточно (чит.: громоздко, со всеми вытекающими) в большинстве случаев.
        2. аскетичное API делает невозможными многие вещи, либо провоцирует на хаки и прочее говно.

        для размышления: Linux Kernel API, WinAPI, API стандартных библиотек PHP, Java...
        Ответить
    • Насчет нетерпимости - если ты обычный программист, то это может привести к конфликтам с коллегами, а если руководитель - к потере работников.
      Разумеется есть моменты когда тебя выводят из себя, но надо понимать, что ты тоже не всем, мягко говоря, нравишься. Не далее как неделю назад у меня
      был конфликт с нашим "scrum masterom", из-за презентации нашего продукта. Конфликт прошёл, ошибку устранены, презентация прошла на ура. Но почему я стал чаще просматривать вакансии в других конторах? ))
      Ответить
      • В тот отдельно взятый промежуток времени в нетерпимость QuickNick была просто жизненно необходима: http://govnokod.ru/9614
        Не говоря уже о том, что obj-c версия PureMVC не нужна. Не в смысле в этом проекте, а в смысле вообще.
        Ответить
    • Если не секрет, зачем вам понадобилось идти против ведрогайдлайнов и писать свой велосипед вместо готового PreferenceActivity?
      Ответить
      • Привет R&D.
        С другой стороны, это штатный функционал меню. Зачем-то же его сделали?
        Ответить
        • Внесу поправку: не меню, а диалога/алерта/всплывающего окна.
          Ответить
      • Согласно функциональному описанию, опции должны были показываться в диалоге. Программисты (в том числе, и главный) не имеют решающего слова при обсуждении дизайна.
        Ответить
        • Этот коментарий, да на говнотехзадание
          Ответить
          • Придется вспомнить делфи, мать ее.

            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();
            Ответить
            • hormand 2 часа назад # 0
              Придется вспомнить делфи, мать ее.

              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();
              Ответить
    • Кстате, QuickNick. Возможно, это тебя заинтересует: hackday.ru/events/hackday-24
      Меня тут в час ночи выудили сегодня, я там буду.
      Ответить
    • АНДРОИДОПРОБЛЕМЫ
      Ответить
      • Не совсем. Это ДИЗАЙНЕРОПРОБЛЕМЫ.

        Ибо там есть вполне годный PreferenceActivity который выглядит как и любое другое окно настроек в системе (что, имхо, очень круто, ибо унификация во все поля), описывается через xml, и в моем простейшем случае с govnotify даже не потребовал кода (кроме небольшого бойлерплейта).

        XML описание: https://github.com/bormand/govnotify/blob/master/Govnotify/res/xml/preferences.xml

        ДИЗАЙНЕРОПРОБЛЕМЫ тут в том, что дизайнеру захотелось выебнуться, показать настройки в диалоге, и он заставил программистов делать самопальные настройки.

        P.S. Мое мнение никак не может считаться авторитетным. Одной серьезной проги (настройки пришлось делать самопальными, ДИЗАЙНЕРОПРОБЛЕМЫ, да), и вот этой игрушечной говнотифи явно не достаточно для того чтобы авторитетно судить о платформе.
        Ответить
        • > описывается через xml
          «Java is a DSL for converting large XML files into long stacktraces»
          Ответить
          • Ну, в данном случае, XML вполне к месту. Декларативное описание же, покрывающее 99.9% потребностей.

            С динамическими пунктами или извращенными типами настроек, конечно, придется повозиться, но они и нужны реже статики.
            Ответить
            • Тут, да. Согласен.
              Ответить
            • С моей точки зрения мало что может смотреться хуже, чем конструирование интерфейса на жабе. Вспоминаю Swing как страшный сон. Думается, XML гораздо компактнее.
              Ответить
              • Может. Конструирование интерфейса в js.
                Ответить
                • Неправда, в JS легко можно обёртку написать, которая ещё и в более компактном виде будет представлять интерфейс (в виде JSON-объекта, например).
                  Ответить
                • Как раз js - охуенен. json (который компактней xmlя раза в 2), встроенный в язык.
                  Что может быть удобней?
                  А вот убогое поделие под названием XSLT - это еще тот ужас.
                  Ответить
                  • Я просто оставлю это здесь:
                    createGameButton:function(title, purchaseState, gameData)
                    		{
                    			var textShift = cc.p(4,3);
                    
                    			var buttonNormalBg = cc.Sprite.create(gameBtnStates[purchaseState][0]);
                    			var labelNormal = cc.LabelBMFont.create(title, s_futura_medium_fnt);
                    			labelNormal.setScale(0.5*font_size_muitipler);
                    			labelNormal.setAnchorPoint( cc.p(0.5, 0.5) );
                    			labelNormal.setAlignment( cc.TEXT_ALIGNMENT_CENTER );
                    			labelNormal.setColor(c_gameModeFont);
                    			var btnSize = buttonNormalBg.getContentSize();
                    
                    			labelNormal.setPosition(cc.p((gameBtnStateTextShifts[purchaseState]-4)/2, (btnSize.height+3)/2));
                    
                    
                    			buttonNormalBg.addChild(labelNormal);
                    
                    			var buttonSelectedBg = cc.Sprite.create(gameBtnStates[purchaseState][1]);
                    			var labelSelected = cc.LabelBMFont.create(title, s_futura_medium_fnt);
                    			labelSelected.setScale(0.5*font_size_muitipler);
                    			labelSelected.setAnchorPoint( cc.p(0.5, 0.5) );
                    			labelSelected.setAlignment( cc.TEXT_ALIGNMENT_CENTER );
                    			labelSelected.setColor(c_gameModeFont);
                    			labelSelected.setPosition(cc.p(71, 30));
                    			labelSelected.setPosition(cc.p((gameBtnStateTextShifts[purchaseState]+4)/2, (btnSize.height-3)/2));
                    			buttonSelectedBg.addChild(labelSelected);
                    
                    			var button = cc.MenuItemSprite.create(buttonNormalBg, buttonSelectedBg, function(e) {
                    				if (button.getParent().getParent().getParent().tag["expanded"]) // Ну раз разрешили говнокодить - получайте )
                    				 	this.onNewGame(gameData); 
                    				}, this);
                    			button.setAnchorPoint(cc.p(0.5,0.5));
                                                   button.setEnabled(purchaseState == PURCHASE_OK);
                    			return button;
                    		}
                    Ответить
                    • labelSelected.setScale(0.5*font_size_muitipler);
                      			labelSelected.setAnchorPoint( cc.p(0.5, 0.5) );
                      			labelSelected.setAlignment( cc.TEXT_ALIGNMENT_CENTER );
                      			labelSelected.setColor(c_gameModeFont);
                      			labelSelected.setPosition(cc.p(71, 30));
                      			labelSelected.setPosition(cc.p((gameBtnStateTextShifts[purchaseState]+4)/2, (btnSize.height-3)/2));

                      Типичное ооп-говно. И это как раз пример того что js не виноват. Просто проектировзик компонент верноятно был болен жабизмом.
                      Как верно подметил Роман:
                      >вспоминаю Swing как страшный сон. Думается, XML гораздо компактнее.

                      Всю полезную информацию можно сохранить таким образом:
                      buttonNormalBg:[
                      	init:function(){return cc.Sprite.create(gameBtnStates[purchaseState][0]);}
                      	,labelNormal :{
                      		Scale:0.5*font_size_muitipler
                      		,AnchorPoint: cc.p(0.5, 0.5)
                      		,Alignment: cc.TEXT_ALIGNMENT_CENTER
                      		,Color:c_gameModeFont
                      	}
                      ]
                      
                      buttonSelectedBg:[
                      	init:function(){return cc.Sprite.create(gameBtnStates[purchaseState][1]);}
                      	,labelSelected:{
                      		Scale:0.5*font_size_muitipler
                      		,AnchorPoint:cc.p(0.5, 0.5)
                      		,Alignment:cc.TEXT_ALIGNMENT_CENTER
                      		,Color:c_gameModeFont
                      		,Position(cc.p((gameBtnStateTextShifts[purchaseState]+4)/2, (btnSize.height-3)/2)
                      	}
                      ;
                      Ответить
                      • Тут же легко видеть, что у нас имеются общие куски структур:
                        Scale:0.5*font_size_muitipler
                        		,AnchorPoint:cc.p(0.5, 0.5)
                        		,Alignment:cc.TEXT_ALIGNMENT_CENTER
                        		,Color:c_gameModeFont

                        Юзая extend и настройки лейблов по дефолту можно далее укорачивать код.
                        Ответить
                      • Да-да, вот примерно таким json'ом в QML описываются интерфейсы.
                        Ответить
                  • > А вот убогое поделие под названием XSLT - это еще тот ужас.
                    Зато с помощью XSLT можно преобразовывать XSLT в XSLT, а затем проверять его по XSD схеме, преобразованной из XML с помощью XSLT!
                    Ответить
                    • di-caprio-cobb-inception.gif
                      Ответить
                      • Преобразование XSLT в XSLT с помощью XSLT, добавляющее поддержку циклов: http://www2.informatik.hu-berlin.de/~obecker/XSLT/loop-compiler/loop-compiler.xslt.html
                        Ответить
                    • А можно ли написать квайн на XSLT?
                      Ответить
                      • Полагаю да. substring - твой друг.
                        Возможно проще чем на других языках.
                        Ответить
                      • > А можно ли написать квайн на XSLT?
                        http://www2.informatik.hu-berlin.de/~obecker/XSLT/quine/quine.xslt.html
                        Ответить
                • > Конструирование интерфейса в js.
                  QML смотрит на вас с негодованием. Там интерфейс описывается вполне декларативненько, не то что в коде про createGameButton.
                  Ответить
                  • * created by nokia, influenced by js
                    Ответить
                    • > influenced
                      Дык там и скрипты к этому QML на... js. Очень удобный инструмент на самом деле для всяких гламурных программ и несложных 2д игрушек. А вот разрабатывать с его помощью динамическую опердень с кучей форм кнопочек полей и базой данных я бы не стал, ибо стандартных контролов там кот наплакал.
                      Ответить
                      • Весь прикол js, в том что его нативный формат сериализации данных и есть язык.
                        Есть в этом сильное сходство с S-выражениями.
                        Ответить
                      • Но я весь мокрый от слёз!
                        Ответить
      • Ну, строго говоря, это уже ПЛАТФОРМОПРОБЛЕМЫ
        Ответить

    Добавить комментарий