Стилизация приложений часть первая

    Coloroid
    Все идет хорошо, вы успешно пишете свои великолепные (ну у кого-как) приложения, даже бывает публикуете их на маркете, но возникает проблема: весь интерфейс уж слишком скучен и однообразен, черный фон (в некоторых селениях белый) и стандартные элементы уж слишком приелись…

    Ну или пойдем по другому пути — у вас имеется своя контора Васей Пупкиных с некой деятельностью в мировой сети (допустим продажа хомячков), и (о ужас!) у вас есть целый сайт. Сайт, ага, сайт то у нас красивый, зелененький/красненький/желтенький ну и т.д. и есть программа-клиент для этого сайта, и мы хотим раскрасить свое приложение в цвета сайта.

    Это статья о том, как можно стилизовать свое приложение под конкретные цвета, а не ограничиваться цветами Андроида

    Русско-язычной информации по этой теме мало, будем восполнять запасы.

    1. Выбираем цветовую гамму

    Тут вроде все понятно — какой хотим, такой и выбираем. В статье будем придерживаться всей цветовой гаммы, во избежании комментариев типа «А зелененький круче»

    1.1. Подготавливаем список цветов

    Фон окон: #370903 — не отвлекающий темно-красный цвет
    Текст: #F0E68C цвет хаки (желтый в общем)
    Кнопки: Градиент от #7FA40E до #B7EF8E — зеленые оттенки
    Прогресс-бар: Градиент от #2E6FC8 до #759BFB — ну а куда без синего?

    2. Ну кто там сказал поехали?

    Начинаем собственно наш процесс

    2.1. Скучная теория

    Как вы догадались, мы не будем изобретать супер-велосипеды, ведь все давно реализовано в Андроиде. Приложение может содержать свои стили и прямо таки намекать Андроиду, на что будут распространятся эти стили. Стиль — это обычный XML ресурс (ну не только XML, но в рамках этой статьи мы будем говорить именно о нем), который должен храниться в папке res/values вашего приложения.

    2.2. Пишем стиль

    Создаем файл res/values/theme.xml (название файла непринципиально, можно писать хоть в strings.xml) и пишем в него следующее:

    <?xml version="1.0" encoding="utf-8"?>
    <resources>
        <style name="HabraTheme" parent="@android:style/Theme.Black">
        </style>
    </resources>
    


    Здесь тегом <style> мы создаем новый стиль с названием HabraTheme и наследованием от системного стиля Theme.Black (наследование необязательное). Теперь для дальнейшего тестирования стиля нам потребуется прописать его для активити (или всего приложения) в AndroidManifest.xml:

    <activity
        ...
        android:theme="@style/HabraTheme" >
        ...
    </activity>
    


    Для применения стиля на все приложение необходимо его прописать не в тег <activity>, а тег <application>.

    Фон окон:
    Прописываем внутрь тега <style> новый тег <item> с параметром name=«android:windowBackground» и содержимым #370903:

    <style name="HabraTheme" parent="@android:style/Theme.Black">
        <item name="android:windowBackground">#370903</item>
    </style>
    


    На самом деле писать цвета прямо в тег item считается плохим тоном, лучше вынести их в отдельный список цветов, но здесь мы экономим место.

    Текст:
    Тег <item> с параметром name=«android:textColor» и содержимым #F0E68C:
    <item name="android:textColor">#F0E68C</item>
    


    Кнопки:
    С кнопками сложней всего, нам придется создать еще 4 дополнительных файла в папке res/drawable:

    hbutton_normal.xml
    <?xml version="1.0" encoding="utf-8"?>
    <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle" >
        <corners android:radius="12px" />
        <gradient
            android:angle="90"
            android:endColor="#B7EF8E"
            android:startColor="#7FA40E"
            android:type="linear" />
        <padding
            android:bottom="7px"
            android:left="4px"
            android:right="4px"
            android:top="7px" />
    </shape>
    

    Здесь мы используем XML-Drawable для создания фигуры кнопки. Задаем наш градиент, скругление в 12 пикселей и отступы для текста кнопки

    hbutton_focused.xml
    <?xml version="1.0" encoding="utf-8"?>
    <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle" >
        <corners android:radius="12px" />
        <gradient
            android:angle="90"
            android:endColor="#79C83F"
            android:startColor="#7FA40E"
            android:type="linear" />
        <padding
            android:bottom="7px"
            android:left="4px"
            android:right="4px"
            android:top="7px" />
    </shape>
    

    А это состояние сфокусированной кнопки (не нажатой!), мы просто чуть меняем endColor

    hbutton_pressed.xml
    <?xml version="1.0" encoding="utf-8"?>
    <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle" >
        <corners android:radius="12px" />
        <gradient
            android:angle="270"
            android:endColor="#79C83F"
            android:startColor="#7FA40E"
            android:type="linear" />
        <padding
            android:bottom="7px"
            android:left="4px"
            android:right="4px"
            android:top="7px" />
        <stroke
            android:width="2px"
            android:color="#52B10C" />
    </shape>
    

    Это фигура нажатой кнопки, помимо изменения цветов мы добавляем рамку (stroke) толщиной в 2 пикселя так-же зеленого цвета

    Осталось объединить эти фигуры в одну кнопку:

    hbutton.xml
    <?xml version="1.0" encoding="utf-8"?>
    <selector xmlns:android="http://schemas.android.com/apk/res/android">
    	<item android:drawable="@drawable/hbutton_focused" android:state_focused="true"></item>
    	<item android:drawable="@drawable/hbutton_pressed" android:state_pressed="true"></item>
    	<item android:drawable="@drawable/hbutton_normal"></item>
    </selector>
    

    Здесь мы указываем, какому состоянию принадлежит какая фигура

    Теперь возвращаемся в theme.xml и создаем новый стиль:
    <style name="HabraThemeButton" parent="@android:style/Widget.Button">
        <item name="android:background">@drawable/hbutton</item>
    </style>
    


    И указываем стиль для кнопки в HabraTheme:
    <item name="android:buttonStyle">@style/HabraThemeButton</item>
    


    ProgressBar мы реализовывать не будем, это будет вашим домашним заданием:)

    Наш конечный результат:


    P.S. В изучении стилей очень помогают исходные ресурсы Андроида, расположенные по адресу android-sdk/platform/platform-*/data/res/values/themes.xml
    Share post
    AdBlock has stolen the banner, but banners are not teeth — they will be back

    More
    Ads

    Comments 38

      +10
      а можно увидеть результат?
        +8
        Пожалуйста:)
        +1
        Спасибо, отличная статья, улетела в избранное.
          +4
          Главное не переборщить и не превратить андроид в винмобайл (не путать с windows phone), где каждое приложение имеет «свой стиль» :)
            –3
            Ну это проблемы винмобайл:)
              +1
              Да и кажется там стили создаются не так элегантно, как в Андроиде. (сори, винмобайл со внутренней стороны вообще невидел, могу и ошибаться)
                –3
                Да и в WP7 врядли что-то изменилось
                  0
                  WP7 не видел, спорить не буду :)
                    0
                    И не стоит минусовать. Сразу ведь сказал, что ни с винм, ни wp дела неимел, могу ошибаться. Обьясните мне преимущества платформы, это будет куда полезнее, чем молчаливые минусы
                      –1
                      Возьми да посмотри, в youtube забей Windows phone 7:
                      www.youtube.com/watch?v=IlsK6-y6cSw
                      www.youtube.com/watch?v=cBISUhRIiSE
                      www.youtube.com/watch?v=Upn6j0Vm4Cw

                        0
                        Я не про саму платфоррму WP7, она таки гораздо лучше той-же вм6, я про сторону коддинга на нее
                          0
                          Так это совсем просто — вот.
                        0
                        Так раз не видели и дела не имели — зачем писать «вряд ли что-то изменилось»? Я обычно вообще молчу про вещи, с которыми не знаком, уж в особенности касательно негативных выводов.
                          0
                          Я же не сказал, что вообще невидел. Я работал и с wm и с вм, но только со стороны пользователя. Писать программы под них мне неприходилось, но я с удовольствием напишу парочку-других, когда это будет нужнно. Может даже чему-нибуь научусь новому для остальных платформ
                            0
                            *WP, а не WM
                    0
                    Статья хорошая, спасибо. Но не раскрыто самое главное — реализация механизма смены тем для одного и того же приложения(скины). Ведь это можно делать практически в один вызов.
                      +1
                      Ну само хранение скинов есть статья Создаем модульное приложение (искать лень), а смена скинов — метод setTheme(int theme) для активити и getApplicationContext().setTheme(int theme) для всего приложения, в чем проблемы?
                      0
                      А для диалоговых окон подобный подход применим?
                        +1
                        Да, для любых View, только вне пределах Context нельзя будет изменить тему, они берут ее из активити (если она была передана как Context) или из приложения (если было послано приложение в Context).
                        –2
                        А почему еще каждому атрибуту свой отдельный XML namespace не выделили?
                        Было бы еще больше букаф ;)

                        Но это уже претензии не к автору статьи
                          +1
                          Можно было пройтись обфускатором, скомпилить xml в бинарный вид, запаковать в tar.gz.bz2 и оставить тему с текстом 'вот вам архив, копайте'.
                          Но это не хабра-вей
                            0
                            Не, я о себе как о кодере забочусь, мне же потом к каждому атрибуту еще префиксы печатать — а это время и ненужный мусор на экране
                              0
                              Вы там в калькуляторе что-ли работаете? Во всех современных IDE есть такая хорошая функция, как автодополнение кода
                                0
                                По букве a — дополнится namespace, а не конкретный атрибут, который имеется ввиду — или вы работаете в настолько современных IDE, что они по начальной букве namespace сразу предлагают именно тот атрибут, о котором вы думаете? :)
                                  0
                                  Я работаю в настолько современных, что можно просто неписать нс, он подставится автоматически
                                    –1
                                    и какой именно? именно тот, о котором вы в именно тот момент думаете?
                          +4
                          честно говоря бесят приложения с «веселым» интерфейсом, стараюсь сразу от них избавляться
                            +3
                            'Веселый интерфейс' и нормальный гуи немного разные вещи
                              0
                              согласен, поэтому и удаляю
                                +1
                                Таки да, если намудрить со стилями, то получится совершенно некрасивое приложение с нечитабельным текстом. В таком случае проще найти замену приложению (ну или распаковать апк приложения и поставить стандартные стили)
                              +1
                              Согласен. Хотелось бы знать, можно ли заставить приложение использовать нативные цвета.
                                0
                                Самый верный вариант — вскрытие. С помощью APKTool распаковвывваем приложение, находим темы и удаляем оттуда все теги item, собираем назад, устанавливаем. Профит:)
                                  0
                                  За неимением более изящного способа, автоматизировать бы этот процесс. ☺
                                    +4
                                    Вы только-что подсказали мне очень хорошую идею для онлайн сервиса:)
                                –2
                                Пора бы гуглу вводить жесткие гайды и премодерацию приложений в маркете.
                                0
                                Вообще, мне как веб-разработчику гораздо проще создать страничку с дизайном приложения, а поом уже перенести в андроид
                                  +1
                                  Для кнопки, кстати, не обязательно четыре файла делать, можно описать все внутри тегов item в селекторе.
                                    0
                                    Спасибо, буду знать

                                  Only users with full accounts can post comments. Log in, please.