Android: ошибка выравнивания при создании / отображении изображения 9 патчей - PullRequest
15 голосов
/ 20 июля 2011

NinePatch:

Trash can icon NinePatch image

Снимок экрана:

Screenshot of NinePatch misalignment

Макет XML:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical"
    android:background="#ffffff">

    <LinearLayout
        android:id="@+id/edit_tray"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true">

        <View
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:background="@drawable/trash"/>

    </LinearLayout>

</RelativeLayout>

ЖелаемыйРезультаты:

«edit_tray» представляет элемент пользовательского интерфейса, который будет переключаться.Когда режим редактирования выключен, «edit_tray» (и, следовательно, значок корзины) «исчезли».Когда режим редактирования включен, «edit_tray» отображается и накладывается на содержимое ScrollView.

У значка корзины есть два элемента: сам значок и линейный градиент позади него.Изображение NinePatch содержит три растягиваемые области и одну статическую область для размещения этих элементов.Значок корзины в центре рисунка является статичным и должен отображаться непосредственно в центре по горизонтали и в нижней части экрана.Градиент должен растягиваться по нижней части экрана от одной стороны к другой.

Ошибка?

Изображение NinePatch содержит только один пиксель растягиваемой области с обеих сторон изображения по горизонтали.Эффект должен состоять в том, что значок мусорной корзины появляется прямо в центре (1 пиксель слева == 1 пиксель справа).Однако, как вы можете видеть на скриншоте выше, это не так.Примечание: этот скриншот был взят с моего тестового телефона T-Mobile G2.Тот же эффект можно увидеть в эмуляторе.Однако в предпросмотре draw9patch и в представлении eclipse Graphical Layout изображение идеально распределено.

Я пробовал несколько разных способов, чтобы попытаться выяснить, где находится ошибка, и попытаться исправить ее или обойти ее.,Включая: использование ImageViews вместо Views (тот же эффект), использование android: scaleType = "fitXY" (та же проблема), проверка во время выполнения, что ширина экрана и ширина edit_tray одинаковы (они есть),использование двух разных изображений для градиента (в качестве фона edit_tray) и значка (как для ImageView src) (создайте еще одну проблему, когда два изображения не накладывались друг на друга. Исправлено установкой абсолютной высоты на обоих) и т. д.

Ответ, обходной путь и реальный вопрос

Я провел некоторое тестирование, используя несколько простых изображений NinePatch с до шести растягиваемых областей на стороне.Я заметил, что были некоторые проблемы с отображением их по крайней мере в одном из тестовых случаев (телефон, эмулятор, draw9patch, Graphical Layout в Eclipse).

Я решил попытаться расширить изображение по горизонтали, чтобы было большелинейный градиент, показывающий по краям значок корзины.Я сделал изображение 128х64 (ранее 64х64).Я сделал больше краев частью растягиваемой части, чтобы попытаться обуздать любую плохую математику (?), Которая происходила с изображением.Draw9patch сообщил о плохих сечениях, поэтому я вернул его на два пикселя, по одному с каждой стороны.Это сработало!Значок находится прямо в центре экрана!Я не знаю почему, но не меняя фактическую растягиваемую часть изображения, а только изменяя ширину изображения до 128, она работает сейчас.

Я попытался изменить размер изображения до 100px в ширину, чтобыудалите несколько лишних пикселей и ошибка вернулась!Мало того, что это возвратилось, но значок был помещен в точно то же самое пятно, смещенное от центра экрана.Я не могу понять, почему это произошло именно так.

У кого-нибудь есть идеи?Это ошибка?

В настоящее время у меня есть эта работа с учетом обходных путей, которые я описал выше, но если у кого-то есть какие-либо предложения, я слушаю.

Ответы [ 4 ]

5 голосов
/ 06 апреля 2012

Создайте изображение 9 Patch с помощью 4 points, как я сделал в этом ... и оно будет работать.

enter image description here

Советы по созданию 9 Patch Image. (Не дизайнер, рассказывающий вам мои основы)

  • Поместите точки слева и сверху
  • Если у вас есть текст или изображение между ними, то поставьте точку наслева и справа от изображения и сверху и снизу этого изображения или текста.
  • Всегда следите за тем, чтобы слева не было места и не было точек с обеих сторон (слева-справа и сверху-снизу).
  • Всегда проверяйте один раз в окне предварительного просмотра или справа, прежде чем использоватьОт 2 до 6
1 голос
/ 02 апреля 2012

Возможно, это ошибка в рисовании из девяти патчей или просто ошибка, возникшая из-за округления .

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

Вы должны нарисовать его другим способом: создать некоторое представление контейнера (FrameLayout) с фоном градиента.Затем поверх этой позиции ImageView с мусорным баком.Ни одно из этих двух изображений не должно быть с девятью заплатами, градиент заполнит весь вид, мусорная корзина будет нарисована без масштабирования.Несмотря на то, что в области просмотра корзины есть перерасход, время процессора не тратится впустую при вычислениях областей с девятью участками.

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

1 голос
/ 16 марта 2012

Из моего опыта с инструментом draw 9-patch есть автоматическое смещение в 1px на каждой стороне изображения.Учитывая эту информацию, если вы использовали только это смещение в один пиксель, ваше изображение фактически не растягивалось так, как вы себе представляете.

Это видно по тому факту, что при использовании смещения в 2 пикселя оно работало идеально.

Кроме того, изображения из 9 патчей имеют тенденцию показывать в затмении именно то, что вы думаете ... но затем они выглядят по-другому на телефоне / эмуляторе.

Изучение инструмента из 9 патчейDef отличная вещь, поскольку это позволяет большую настройку.Еще один совет: если вы хотите сделать что-то вроде замены 9-патча Android на свои собственные изменения, просто скопируйте 9-патч, который существует в SDK, и измените его.По какой-то причине изображения 9patch в SDK имеют странные смещения.Это гарантирует, что вы не получите странных ответов от ваших 9-патчей.Пример этого - я обрисовываю editText красным, когда дается неправильный ввод.

Изображения SDK можно найти в SDK-> платформах -> [plateform-you-want] -> data-> res-drawable- [you-choice]

Вы также можете посмотреть образы 9-патчей SDK, чтобы понять, как работает инструмент 9-патчей.

Надеюсь, что это даст немного больше понимания.

Вот несколько хороших ссылок: http://developer.android.com/guide/developing/tools/draw9patch.html http://android10.org/index.php/articlesother/279-draw-9-patch-tutorial http://jaanus.com/post/7878186745/how-does-androids-nine-patch-tool-work-from-a

0 голосов
/ 03 апреля 2012

Как сказал @jjNford, работать с изображениями таким способом - плохая практика.

Для этой задачи лучшим решением является создание значка «мусор» с прозрачным фоном и создание shape для рисования с градиентом. Таким образом, вы можете удалить ненужные LinearLayout и использовать только ImageView:

<ImageView
    android:id="@+id/edit_tray"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_alignParentBottom="true"
    android:src="@drawable/trash"
    android:background="@drawable/gradient_background"/>

Документы для рисования формы .

EDIT

Просто проверьте свое изображение - оно отлично работает на SE Xperia 2.3.3

...