Android — макет панели мониторинга с фоном из списка состояний, который можно нарисовать только для значка

#android #android-layout

#Android #android-макет

Вопрос:

Я пытаюсь создать макет панели мониторинга. Он отличается от панели управления Google i / o в том смысле, что фон значка изображения и текста под значком отличается.

Другими словами, значок (только изображение) имеет StateListDrawable в качестве фона, в то время как текст имеет прозрачный фон. Один из способов сделать это — поместить эту комбинацию изображения и текста в LinearLayout и использовать ее в макете панели мониторинга для каждого элемента, который кажется не таким простым. Это единственный способ, которым я мог это сделать? или есть лучшее и простое решение?

Обновление: Вы можете использовать настройки проекта здесь и поэкспериментировать.

  • В файле макета dashboard2.xml используется DashboardLayout класс Google. В основном действии я просто настраиваю содержимое представления на dashboard2

  • В этом проекте вы найдете список состояний, который можно нарисовать в drawable папке по имени dashboard_icon_bg_selector.xml . Я хочу, чтобы фон всех значков панели мониторинга отображался в этом списке состояний.

Приветствуются любые предложения.

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

1. не могли бы вы, пожалуйста, опубликовать картинку, на которой вы хотите, чтобы это выглядело? И, может быть, о том, как это выглядит сейчас?

2. Пожалуйста, проверьте обновление. Я разместил ссылку на настройку проекта. Загрузите его, и вы сможете попробовать сами.

Ответ №1:

Одно из возможных решений, о котором я могу подумать, — использовать LayerDrawable в качестве верхнего элемента вашего TextView. Я обрисую идею, перечислю некоторые детали и прикреплю ссылку на измененный пример проекта ниже.

Код для кнопки (в файле макета):

 <Button android:id="@ id/home_btn_schedule"
    style="@style/DPDashBoardButton"
    android:text="button 1"
    android:drawableTop="@drawable/dashboard_icon_bg_selector" />
  

Два слоя отрисовки, один для состояния «нажато / сфокусировано / выбрано» и по одному для любого другого состояния (rest):

dashboard_icon_layer_background_selected.xml:

 <?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@drawable/dashboard_icon_background_selected" />
    <item android:bottom="14dip">
        <bitmap android:src="@drawable/btn_star_big_on_pressed"
            android:gravity="center" />
    </item>
</layer-list>
  

dashboard_icon_layer_background_rest.xml:

 <?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@drawable/dashboard_icon_background_rest" />
    <item android:bottom="14dip">
        <bitmap android:src="@drawable/btn_star_big_on_rest"
            android:gravity="center" />
    </item>
</layer-list>
  

Некоторые особенности для этого конкретного примера:

  • Причина, по которой на изображения звездочек ссылаются как на растровое изображение, заключается в том, чтобы запретить Android масштабировать их до полной ширины и высоты контейнера. Расстояние до низа добавляется для фактического центрирования звезды относительно фонового изображения (textSize = 12 плюс 2 для заполнения), что, честно говоря, довольно некрасиво для такого жесткого кода. Без этого смещения центрированная гравитация поместит изображение звезды в центр всего контейнера, включая пространство, добавляемое текстом.
  • Таким образом, замена элемента растровым изображением на <item android:drawable="@drawable/btn_star_big_on_rest" /> приведет к увеличению масштаба изображения звезды. Просто попробуйте один раз, чтобы понять эффект.
  • Это явление весьма прискорбное, поскольку мы потенциально могли бы ссылаться на другой xml, который можно нарисовать с помощью приведенного выше, используя все его уже определенные состояния! Вот почему мне на самом деле пришлось скопировать два изображения звезд из репозитория Android: вы не можете ссылаться на xml, который можно нарисовать в качестве источника растрового изображения, и на фактические изображения также нельзя публично ссылаться. Попробуйте заменить определение растрового изображения на <item android:drawable="@android:drawable/btn_star" /> , чтобы увидеть, как изображение увеличивается, но сохраните предопределенные состояния без изменений.
  • Потенциально вы могли бы обойти проблему масштабирования, создав 9 фрагментов из изображений звезд, создав StateListDrawable для разных состояний и сославшись на результирующий xml, который можно отобразить в элементе слоя. Хотя Android по-прежнему растягивает все изображение до полного размера контейнера, 9patches могут гарантировать, что масштабируются только прозрачные пиксели.
  • // Редактировать: я понял, что у этого подхода есть еще одно ограничение, поскольку нажатие на текст не приведет к изменению состояния значка. Возможно, это то, что вам нужно, но лично я бы сказал, что с точки зрения пользователя было бы разумно, чтобы все это реагировало на события касания…

Надеюсь, это имеет смысл! Просто чтобы показать вам результат: слева все находится в состоянии покоя, справа нажата верхняя левая кнопка.

Сжатый проект здесь.

Измененный пример проекта

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

1. Я не могу получить доступ к проекту. Не могли бы вы, пожалуйста, проверить это один раз?

2. ваш ответ, похоже, решает мою проблему. У меня есть еще один день, чтобы присудить награду. Я предоставлю его вам вскоре после ознакомления с проектом.

3. Я дважды проверил, но проблем с загрузкой измененного проекта не возникло. В любом случае, я также загрузил zip-файл в Google Docs и обновил ссылку в своем ответе. Надеюсь, это сработает!

Ответ №2:

Разве вы не можете использовать просто a TextView и установить его фоном StateListDrawable ? Если вам нужно немного места для «значка» выше, вы могли бы установить значение тяжести TextView снизу и установить для него фиксированную высоту.

Редактировать: Еще лучше, вы можете использовать drawableTop свойство:

  <TextView
    android:id="@ id/textView1"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:gravity="bottom|center"
    android:text="Example"
    android:drawableTop="@drawable/statelist"
    android:drawablePadding="5dp"/>
  

Правка 2: Следуя примеру Google, вы можете задать стиль для кнопки / TextView. Он изменил цвет фона, потому что это поведение системы по умолчанию. Попробуйте следующее:

main_layout.xml

 <?xml version="1.0" encoding="utf-8"?>
<org.demo.DashboardLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" >

    <TextView
        style="@style/DashboardTextView"
        android:drawableTop="@drawable/state_list_drawable"
        android:text="Item1" />

    <TextView
        style="@style/DashboardTextView"
        android:drawableTop="@drawable/state_list_drawable"
        android:text="Item2" />

    <TextView
        style="@style/DashboardTextView"
        android:drawableTop="@drawable/state_list_drawable"
        android:text="Item3" />

    <TextView
        style="@style/DashboardTextView"
        android:drawableTop="@drawable/state_list_drawable"
        android:text="Item4" />

    <TextView
        style="@style/DashboardTextView"
        android:drawableTop="@drawable/state_list_drawable"
        android:text="Item5" />

    <TextView
        style="@style/DashboardTextView"
        android:drawableTop="@drawable/state_list_drawable"
        android:text="Item6" />

</org.demo.DashboardLayout>
  

И добавьте это в свой values/styles.xml :

 <style name="DashboardTextView">
    <item name="android:layout_gravity">center_vertical</item>
    <item name="android:layout_width">wrap_content</item>
    <item name="android:layout_height">wrap_content</item>
    <item name="android:gravity">center_horizontal</item>
    <item name="android:drawablePadding">2dp</item>
    <item name="android:background">@null</item>
    <item name="android:clickable">true</item>
    <item name="android:textColor">#ffffff</item> <!-- White, you can change your text color here -->
</style>    
  

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

1. Я добавил больше информации. Пожалуйста, взгляните на это. Это может вам помочь.

2. Я добавил правку 2 выше, посмотрим, поможет ли это!

3. Я не пробовал делать это таким образом. Я включу и скоро сообщу вам о наблюдениях. Спасибо.

4. Я разместил ссылку на настройку проекта. Вы можете поэкспериментировать с ним. Спасибо.

Ответ №3:

Кажется, это было бы легко решить с использованием изображений 9patch в качестве ресурсов для ваших различных состояний и списка состояний в качестве фонового отображения или TextView, с drawableTop, установленным на значок… если вы не хотите, чтобы значок изменился так же, как и фон?