Как стать автором
Обновить

Комментарии 83

[offtopic] А у вас много дискового пространства на media.omlet.ru? А то любой начинающий кулхацкер нагенерит вам картинок по самое нехочу :) [/offtopic]
а вы правы, убрал на всякий
Если бы lotas не сказал, я бы и не догадался. А теперь прям аж захотелось подставить вместо sеcret_domain тот самый секретный домен из предыдущего комментария… (=
Размеры в weight? Вы издеваетесь?
а что не так? (ну и занудства ради там не размеры а приоритет, с пикселями он совпадает для простоты)
Ну вообще-то в некоторых ситуациях это довольно полезный атрибут.
Надо выделать каждому дочернему слою одинаковое или соразмерное пространство? Пожалуйста.

Надо заставить элемент заполнить все пространство по центру, не тронув при этом крайние элементы? Запросто.
В определенных случаях полезно, но в данном конкретном, это просто издевательство, по производительности будет бить ужасно. Тем более не понятно зачем такие извраты.
Либо я не понял проблемы, которую Вы пытаетесь решить, либо Вы не читали гайдов.
Зачем хелпер, если все, что создается вполне можно создавать в xml и размеры указывать там?
Шрифт масштабировать под размер экрана — это вообще что и зачем?!
Все что я понял, Вы пытаетесь создать одинаковую картинку, растянутую на разные размеры экранов. Это полностью противоречит всем правилам разработки под андроид.
а можно ссылочку на гайды, конкретный раздел который нужно почитать?

Советы основаны на нашем опыте разработки нескольких сложных Android приложений, возможно, у вас другой опыт. Расскажите, о нем, кстати.
о, класс, спасибо!
Шрифт масштабировать под размер экрана — это вообще что и зачем?!

У меня подобная проблема, надо в приложении выводить текст пропорционально размеру экрана, если этого не делать, то надписи на больших экранах кажутся слишком мелкими, или наоборот — нормальные на больших, но слишком крупные на маленьких устройствах. В статье я увидел вариант решения, спасибо автору! Он не идеальный, но хоть какой-то.
А как надо? Как решить задачу красиво, по правилам разработки под андроид?
Используйте разные значения размера шрифта для разных разрешений экрана.
в values\dimens.xml text_size=16sp
в values-sw600dp\dimens.xml text_size=20sp
в values-sw720dp\dimens.xml text_size=20sp

Все прозрачно и понятно.
спасибо!
не за что, правда опечатку заметил.
В values-sw720dp конечно же 24. А если нужно 20, то папку values-sw720dp создавать не нужно, подтянется из values-sw600dp
Использовать вложенные LinearLayout и FrameLayout для отступов?
Месье знает толк в извращениях.

RelativeLayout позволит сразу разместить все элементы в одном ViewGroup, без накладных расходов на компоновку, перерисовку и измерение. А если очень нужна возможность задавать пространство, есть Space, в котором нет лишних расходов на перерисовку.
вот и я про то же — не слышал чтоб layout_margin маркировали deprecated
Это тот Space который с АПИ 14? Чем плох обычный View? Это конечно в том случае, если margin и padding не подходят.
Это тот Space, который есть в Support Library v7
View хуже тем, что работает медленнее, а Space специально облегчен для использования в качестве отступов.
И правда :) Заглянул в исходники, никогда бы не подумал что в draw() пустой вьюхи делается столько всего.
пс: по-хорошему вьюха должна бы наследовать спейс и переопределять нужные его методы, а то из иерархии классов совсем не очевидно что есть что-то легковеснее вьюхи.
ну как бы менять так кардинально иерархию, спустя столько версий, было бы ужасной идей.
Естественно, я имел ввиду если сначала так делать.
Просто интересно, есть ли какой-то другой вариант написания разметки кроме XML?
Нормального — нет.
А так — создаёте вьюшки в рантайме, добавляете нужные аттрибуты и фигачите в layout. Но зачем?
Никакой альтернативы а-ля html?
Сложно понять, что вы хотите. Layout XML это и есть a la HTML. Даже со стилями.
В коде, но зачем? Чем вас xml не устраивает?
— Автор почему-то по умолчанию считает, что дизайн макета нужно верстать пропорционально под все телефоны, хотя это совершенно необязательно. Какие-то элементы (кнопки, тулбары) вполне могут оставаться постоянного размера (с учетом dpi, разумеется), какие-то (например, текстовое поле для текстового же редактора, либо SurfaceView для видео) таки действительно нужно масштабировать под максимум свободного места на экране. Все зависит от задачи.
— Если у меня экран больше в два раза, это не значит, что я хочу видеть звездочки в ListViewItem в два раза больше. Это означает, что я хочу видеть в два раза больше элементов на экране, так что ListViewItem вообще не надо масштабировать.
— Если автор все же озадачился масштабированием всего и вся пропорционально экрану, то он должен озадачиться также масштабированием шрифтов, иначе они-таки вылезут за границы элемента. В статье об этом почему-то ни слова.
— Если автор все же озадачился масштабированием всего и вся пропорционально экрану, то у него все равно это получится некрасиво, ибо нужно учитывать, что пропорции у разных экранов — разные. Если везде просто домножать на dScale, оно поплывет, если же отдельно высоту на vScale, а ширину на hScale — у контролов разъедутся соотношения сторон.
— Вложенные LinearLayout нужно использовать очень осторожно. При большой вложенности обсчет прорисовки начинает жутко тормозить, так что с увеличением сложности дизайна нужно рассматривать варианты с RelativeLayout или рисованием кастомного контрола на Canvas.

Леша, ты меня расстраиваешь =/
Толик, запятые, ну сколько раз я тебе говорил…
Володя, спасибо, подробный и обоснованный коментарий.

> Если автор все же озадачился масштабированием всего и вся пропорционально экрану, то он должен озадачиться также масштабированием шрифтов, иначе они-таки вылезут за границы элемента. В статье об этом почему-то ни слова.

Читаем еще раз :) или ctrl+f шрифты

Поделись, как у вас в StudioMobile принято, какие макеты рисует дизайнер, как верстаете, как проверяете?
Про шрифты не заметил, согласен.

На данный момент на моем проекте, увы, не идет никакой работы над дизайном под Android, за другие проекты и, соответственно, дизайнеров сказать не могу. По существующему коду — мелкие элементы (кнопки там всякие) имеют фиксированный размер под три разных типа экранов, layout-ы растягиваются под weight, в общем как обычно, экзотических сложностей я тут пока не обнаружил (= Разве что поотрывать руки тем, кто сделал три одинаковых xml в разных размерах (вместо того, чтобы заюзать стили), но это уже из другой оперы…
Странно выглядит этот комментарий от работающего там же человека )
давно нет
Хабрапрофиль устарел, я там уже полгода не работаю.
Перечитал статью еще раз. Вся статья — один большой косяк. Все кроме совета про использования nine-patch и xml для графики — вредные советы. Я бы спасался бегством от такого «гуру».
и ваша точка зрения, как надо?
На мой взгляд:
1. Дизайнер рисует 2-3 макета (скажем телефон и планшет), может еще пограничное что-то, например, nexus 7.
2. Макеты могут очень сильно отличаться, но тут фрагменты в помощь и папки layout-sw600dp например.
3. Верстаются макеты, а элементы тянутся по отдельности «по смыслу». Т.е. масштабируется не все подряд, а только то, что необходимо.
4. Контроллы на всех телефонах одинакового физического размера и размеры задаются в dp.
5. Шрифты задаются в sp, что бы дать возможность пользователю в настройках телефона поставить крупный шрифт например. Вдруг плохое зрение у пользователя?
6. В комментариях много уже написано, про избыточную вложенность примеров.
7. Задание размеров чего бы то ни было в коде — огромная редкость. И в этом случае все равно используются размеры из файлика dimen.xml.

Что касается вашего примера, то тут масштабировать ничего не надо. При какой-то ширине можно сделать 2 колонки например, что бы не было большого количества пустого пространства, а не показывать звездочки в 10 сантиметров высотой на планшетах.

А вообще смотрите DevBytes и Android Design in Action на youtube. Там много советов по best practice верстки под андроид.
Xml-drawables, особенно многослойные, зачастую, рисуются намного медленнее и требуют больше ресурсов, чем 9-patch соответствующего формата. Так что я бы остерегся называть совет по-максимуму использовать xml-drawables не вредным.
Тут есть о чем разговаривать. Вы правы когда-то стоит, когда-то — нет. Но это не так однозначно, как все остальное на мой взгляд.
Вложенные LinearLayout? Nine-patch не надо растягивать?

Сомнительная статья…
Тут уже много сказали. Я бы от себя добавил, что, вкладывая друг в друга LinearLayout'ы c весами (nested weights), вы каждый раз убиваете милого утёнка. И чем больше вложенность, тем больше утят погибает экспоненциально.
А почему? и как правильно?
В документации, а также в различных докладах, разработчики андроид говорят, что каждый раз, когда вы используете layout_weight, измерение компонентов происходит в два прохода, соответственно, это быстро растет, когда у вас вложенные LinearLayouts. Как правильно — зависит от ситуации. Обычно стремятся минимизировать вложенность, например, помощи RelativeLayout.
Ты умеешь делать пропорциональное деление экрана с помощью RelativeLayout? Научи меня
Даша, если тебе нужно сделать пропорциональное деление — используй веса, почему нет, я кажется не отговариваю их использовать, я отговариваю их нестить друг в друга. А если у тебя все настолько сложно, что нужно пропорционально поделить пропорционально поделенное, то, может быть нужно использовать другой layout? GridLayout, например?
Не обо мне речь. Данную конкретную задачу RelativeLayout не решает и никоим образом не может оптимизировать.
Возможно, ты хотел сказать, что дизайнеру надо придумать такое представление экрана, чтобы и смотрелось хорошо, и версталось без вложенных весов. Это я тоже так думаю, да )
Ну, как сказать… это не совсем то, что я имел ввиду. Далеко не всегда мы можем заставить дизайнера что-то изменить, иногда дизайны идут «сверху», с этим ничего не поделаешь. Если есть возможность работать напрямую с дизайнером, да еще и знакомым с гайдлайнами — это чудо, как хорошо, но, такое бывает не всегда. Я говорил, что мы, как _разработчики_ обладаем достаточным арсеналом, чтобы любую задачу реализовать несколькими способами, и это наша ответственность выбрать наиболее оптимальный. Ты зачем-то прицепилась к RelativeLayout, который я привел как пример, но это далеко не единственный layout, который есть, их больше, для разных целей, кроме того, на крайний случай, в нетривиальной ситуации, можно написать свой, который будет делать твою узкую задачу в 100 раз лучше и быстрее, чем существующий универсальный с кучей костылей. (минусую, если что, не я :)).
И это вы называете «без боли»?
В нашем проекте мы с дизайнером работаем так:

Дизайнер предоставляет макет с отступами и размерами (dp), шрифтами (sp) и цветами в разрешении xhdpi.
Затем с помощью android-ui-utils.googlecode.com/hg/asset-studio/dist/index.html генерируются 9patch под все dpi. Косяки генератора исправляются вручную.
Все цвета вынесены в colors.xml, все простейшие drawable заданы в xml. Все свойства виджетов заданы в styles.xml и применяются в качестве темы оформления.
Под планшеты создаются отдельные layout, которые вмещаются больше инфы и т.д. (с применением фрагментов).

Используется RelativeLayout по максимуму, где только можно. Поскольку вложенные вьюшки, а тем более LinearLayout очень сильно сказываются на производительности, а на телефонах с 2.3.3 вообще вызывают stackoverflow exception при отрисовке, если приложение обладает достаточно мощным интерфейсом с кучей элементов.

Соответственно, под все dpi все прекрасно тянется, шрифты увеличиваются вместе с системными, как и положено.

Не совсем понял смысла статьи, т.к. в гайдах все описано, как создавать дизайн под различные экраны и плотность точек.
Можно ссылку на гайды «как создавать дизайн под различные экраны и плотность точек»?

И было бы интересно посмотреть на пример макета, может у себя попробуем внедрить такой формат.
Когда-то, давным давно, года три назад, просьба предоставить ссылку на какой-то гайд по Андроиду была вполне нормальным явлением. Информации было мало, и мы тогда собирали ее буквально по крупицам, обменивались опытом с коллегами, молились на одинокие статьи Романа Ги, Кирилла Мотье. Но сейчас, в 2013… Информации столько, она разжевывается так подробно, что только ленивый ее не найдет. d.android.com, d.adnroid.com/design, каналы Android Developers c часами материала с IO, DevBytes, ADIA, многочисленные комьюнити в G+, странички известных людей в G+…
не, не, это все понятно. Мне интересны именно гайды «все описано, как создавать дизайн под различные экраны и плотность точек». Зачем уходить в дебри, я задал простой вопрос.
Ссылки вам написали выше. Удивительно, что вы взялись за разработку приложения, не изучив гайды. Я думал, уже прошло время, когда приложения делались абы как.
layout_weight это хорошая штука, но пренебрегать ей не надо — слишком много телефону пересчитывать приходится перед показом. Насчёт px вообще не понял зачем? Есть ведь dp и sp чтоб как раз этими пересчётами не заниматься
Ничего себе вы тут на советовали:

— Кучу костылей для масштабирования размеров разметки и шрифтов, когда специально для этого есть dp, sp и куча идентификаторов ресурсов.
— Усложнение кода, там где это не надо.
— Использование весов там где не нужно, будет страдать производительность
— Лишние вьюшки, которые там совсем не нужны. Можно спокойно выкинуть 2-3-4. А если экран у устройства большой, и видно скажем 10 элементов в списке, это мы получим 20-30-40 сэкономленных вью.
— как работает gravity, из вашей разметки я вижу вы тоже не понимаете. Там только первый по делу, остальные 3 не нужны.
— что будет если повернуть телефон?

Еще и заголовок — «Верстка Android макетов без боли»

>Разработчики же часто понятия не имеют как правильно растягивать элементы и масштабировать шрифты.
значит это не разработчик.

>Nine-patch нужно нарезать под все dpi: ldpi mdpi tvdpi hdpi, xhdpi, xxhdpi
Сильно уж однозначный совет. Не обязательно пилить под все, вообще не помню когда последний раз видел ldpi.
Да и ресурсы в основном только выборочно раскидывают, в зависимости от типа.
Или тот же xxhdpi, если для него не будет, это не сильно критично. А вот иконку приложения туда кинуть нужно обязательно.
Тоже самое и tvdpi. TvDpi это только телики и Nexus 7, на нем в полне нормально выглядят иконки с hdpi

В общем нужно что бы были картинки для mdpi, hdpi, xhdpi, и иконка приложения в xxhdpi.
Остальные по желанию, и то имеет смысл только, если ваш дизайнер «вылизывает» иконки, и подгоняет каждый пиксел.

>наш логотип в размере 500x500 со сплешскрина
это вам не айфон, тут приложения моментально запускаются. Сплэшсрин на андроиде не используется.

>при первом запуске масштабировать изображение до нужного размера и кешировать результат.
Если картинка прям такая огромная, что у вас валится с OOM, то во первых неплохо бы
1. поработать над картинкой и уменьшить ее размер. Есть куча способов это сделать. Начиная от оптимизаторов пнг, заканчивая сохранением с уменьшением палитры.
2. загружать в память уменьшенную картинку, для этого не нужно ничего и никуда кэшировать. Вот тут подробнее: developer.android.com/training/displaying-bitmaps/load-bitmap.html

Вывод: гайдланы не читали, андроид видим впервые, зато даем советы другим.
С удовольствием подпишусь под каждым словом. Интересно, что при общем и заслуженном негативе в комментариях, сама статья ушла далеко в плюс, что значит, многие воспользуются этими «полезными» советами…
НЛО прилетело и опубликовало эту надпись здесь
Если статья уйдёт далеко в минус — её могут спрятать в черновик. В комментариях много полезных советов есть, жаль будет, если они пропадут вместе со статьей.

Так что по мне лучше уж так, чем «справедливая кара» за вредные советы.
>это вам не айфон, тут приложения моментально запускаются.
спасибо посмеялся, вот для затравки www.google.com/search?q=App+takes+too+long+to+start-up&oq=App+takes+too+long+to+start-up
может приложения и работают быстрее?

>Если картинка прям такая огромная, что у вас валится с OOM, то во первых неплохо бы
24mb на процесс, 20 картинок 500x500 хватит, неоднократно сталкивались с такой ситуацией

А подскажите, какие Android приложения вы сделали? Возможно, слишком разный опыт.
Этот линк должен что-то означать? Может, конечно, у нас Гуглы разные, но тем не менее:
android App takes too long to start-up: Результатов: примерно 1 310 000 000
iphone App takes too long to start-up: Результатов: примерно 1 410 000 000
Впрочем, в любом случае, выборки эти сильно разбавлены результатами, не имеющими отношения к поставленному вопросу, так что вопрос об их репрезентативности даже не стоит.

И, кстати, я не в курсе, как там все работает под iOS, но в Андроиде приложения действительно запускаются крайне быстро. Другое дело, что запуск отдельно взятой тяжелой Activity может затянуться, но это уже совсем другая история. В тех приложениях, в разработке которых я принимал участие, в большинстве случаев сплэш-скрин использовался для того, чтобы пару секунд пропиарить логотипчик компании. И только в некоторых случаях там выполнялась какая-то заметная и затратная по времени работа, вроде загрузки .obb-файлов (если они по какой-то причине не подтянулись с маркета сами).
Простите, мне показалось, или вы действительно только что привели в качестве аргумента, что приложения медленно запускаются ссылку на вопрос на SO, где человек загружает 50 экранов в ViewFlipper при запуске приложения? Вы нас троллите?
да, ссылка так себе ~__~ но вот получше stackoverflow.com/questions/8642730/splash-screen-in-android-application

Мне показалось бредовым утверждение «на android нет поддержки splash screen, потому что приложения запускаются мгновенно» но это не так, чудес не бывает. Висит черный экран, когда на ios есть возможность впихнуть туда картинку.

Или гугл пишет «If your application has a time-consuming initial setup phase, consider showing a splash screen or rendering the main view as quickly as possible, indicate that loading is in progress and fill the information asynchronously. In either case, you should indicate somehow that progress is being made, lest the user perceive that the application is frozen.»
developer.android.com/training/articles/perf-anr.html

Хотя что это я :) Спор не о чем.
Сплэшскрин, да, имеет смысл, если там действительно надо первоначально МНОГО сделать, как то заполнить базу, сделать 50 запросов на сервер, что бы подготовить все и тд. Но практика показывает, что сплэшскрин ставят после айфона, просто, потому что, потому.
что-то мы не туда ушли, я нигде не говорил, что сплеш-скрин нужен в Android приложениях, а приложение что в статье никогда не существовало, это три картинки для примера.

У меня нет под рукой android, но стало интересно, как происходит на нем загрузка инстаграмма или фейсбука, например. Что происходит после нажатия на иконку.
У инстаграмма нету, фэйсбук там что то первоначально делает. На фэйсбук бы я не стал ориентироваться, так как они совсем не показатель, то они вебвью используют, то 600+ вью создают, проблем у них много, приложение тормозное, вот только недавно, кое как они начали что то исправлять.

Ну не чему там тормозить, если вы только не грузите кучу данных. Да даже если на 100-200ms, задержка, можно тот самый «черный» экран облагородить, что то совсем легкое, цвет, например, поменять и тд. Рулится все из темы.
> спасибо посмеялся, вот для затравки www.google.com/search?q=App+takes+too+long+to+start-up&oq=App+takes+too+long+to+start-up
Во первых там не понятно, что такое по ссылке.
Во вторых сама активити по себе не сильно тяжелая, если старт долгий, значит вы чет там делаете не так. Может сплэшскрин в основном треде грузите. Может что то еще плохое делаете. Можно сделать замеры, посмотреть в логат, может там хореограф ругается и тд. Сплэшскрин не нужен, для такой простой проги.
В третьих, у нас есть(у вас есть) простая активити, так вы тратите время на создание временной + время на загрузку здорового битмапа + еще скорее все таймер стоит. За то время пока там сплэшскрин все это делает, активити уже 5-10 раз успеет запуститься.

>24mb на процесс, 20 картинок 500x500 хватит, неоднократно сталкивались с такой ситуацией
Написано было про одну картинку. ОК 20 картинок, в чем проблема?
1. Делаете кэш в памяти
2. загружаете сразу с нужными Bitmap.Options, что бы не занимало много памяти. Еще можно поиграть с Bitmap.Config.RGB_565
3. выгружаете не нужные, по мере заполнения
Подробнее здесь: developer.android.com/training/displaying-bitmaps/index.html

Не можете осилить сами, возьмите библиотеку:
github.com/nostra13/Android-Universal-Image-Loader
Из личных наблюдений: weight — вещь весьма относительная. Например, если создать layout типа такого:

LinearLayout
Button android:weight=«1»
Button android:weight=«1»
/LinearLayout

то это еще не значит, что кнопки будут строго одинакового размера.
P.S. Что-то тэг code съедается, оставлю так
будут, если вы им обеим поставите layout_width=«match_parent»
вообще-то 0dp стоит ставить для улучшения производительности, если про горизонтальный linearlayout идет речь (если вертикальный, то соответственно высоте 0dp)
Да, действительно, вы правы, спасибо. Я забыл об этом. Суть моего коммента была, что не «wrap_layout», ибо тогда они не будут одинаково растянуты в зависимости от их содержимого. Держите плюсик.
Lint он всегда подсветит в разметке, если забудете :)
Если б все еще lint смотрели, жить было бы легче. А то порой открываешь проекты, которые приходят на поддержку, а там банально используется api старшей версии, хотя минималка другая, а ведь lint это сразу говорит :(
Спасибо всем.
Вы хотели сказать в «sp»? :)
Да, прошу прощения, конечно в sp.
Ребята, вам стоит срочно задуматься об изменении подхода. То что вы советует, это просто ужас
Ладно еще вложенные вьюхи с весом, которые бьют по отрисовке.
Так у вас же по коду, куча магических чисел, а что если нужно изменить верстку? Правки xml уже недостаточно, нужно бегать по коду и править эти магические числа. А как же адаптивная верстка? Зачем просто растягивать?

У нас в компании делаются макеты для xhdpi hadnset (640x960), делается нарезка для mdpi, hdpi, xhdpi. Далее в xml проставляются необходимые отступы, шрифты и прочее согласно mdpi. При адаптации для таблеток, делаются доп layout некоторых экранов, где необходим. Или в самом простом случае, просто dimen.xml с размерами для таблеток.
Также не стоит забывать про фрагменты.

PS: почитайте все-таки гайдлайны, посмотрите devbytes и т.д.

Ну и почитайте гайдлайны, посомтрите вуминеуы
Какая еще адаптивная верстка, если часть верстки находится в коде, а изменения dp/sp/px и любых других измерительных чисел происходит при помощи вспомогательного класса?
А я о чем и написал?
Зарегистрируйтесь на Хабре , чтобы оставить комментарий