Android: ошибка выравнивания при создании/показе 9patch изображения
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 изображение прекрасно распределяется.
Я пробовал несколько разных методов, чтобы попытаться выяснить, где находится ошибка, и попытаться исправить ее или обойти. В том числе: используя ImageViews вместо Views (тот же эффект), используя android: scaleType = "fitXY" (та же проблема), проверяя во время выполнения, что ширина экрана и ширина "edit_tray" одинаковы (они есть), используя два разных изображения для градиента (как фон edit_tray) и значок (как ImageView src) (создайте еще одну проблему, когда два изображения не были наложены друг на друга. Исправлено установкой абсолютной высоты на обоих) и т.д.
Ответ, обходной путь и реальный вопрос
Я провел некоторое тестирование, используя несколько простых изображений NinePatch с шестью растяжимыми областями на каждую сторону. Я заметил, что были некоторые проблемы, отображающие их, по крайней мере, в одном из тестовых случаев (телефон, эмулятор, draw9patch, графическая компоновка в eclipse).
Я решил попытаться расширить изображение по горизонтали, чтобы было больше линейного градиента, показывающего на краях значка корзины. Я сделал изображение 128x64 (ранее 64x64). Я сделал больше краев части растяжимой части, чтобы попытаться обуздать любую плохую математику (?), Которая происходила с изображением. Draw9patch сообщил о плохих разделах, поэтому я вернул их только двум пикселям, по одному с обеих сторон. Это сработало! Значок находится прямо в центре экрана прямо сейчас! Я не знаю, почему, но без изменения фактической растяжимой части изображения, только изменяя ширину изображения до 128, он работает сейчас.
Я попробовал изменить размер изображения до 100 пикселей в ширину, чтобы удалить некоторые избыточные пиксели, и ошибка вернулась! Он не только вернулся, но иконка была размещена точно в том же месте, смещенном от центра экрана. Я не могу понять, почему так происходит.
У кого-нибудь есть идеи? Это ошибка?
В настоящее время я работаю с этими обходными решениями, описанными выше, но если у кого-то есть предложения, которые я слушаю.
Ответы
Ответ 1
Сделайте свое 9-образное изображение с помощью 4 points
, как я это сделал, и он будет работать.
![enter image description here]()
Советы по созданию 9 патч-изображений. (не дизайнер, рассказывающий вам мой фонд)
- Положите точки слева и сверху
- Если у вас есть текст или изображение между ними. Затем поместите точку слева
и справа от изображения, а также сверху и снизу этого изображения или текста.
- Всегда смотрите, чтобы пустое место осталось, а точки с обеих сторон (слева направо и сверху вниз) равны.
- Всегда проверяйте как только предварительный просмотр, так и правую сторону перед использованием проверки в 2x
до 6x
Ответ 2
Из моего опыта с инструментом 9-патчей для ничьей есть автоматическое смещение 1px на каждой стороне изображения. Учитывая эту информацию, если вы использовали только этот пиксельный сдвиг, ваш образ фактически не растягивался, как вы могли себе представить.
Это видно из того факта, что когда вы использовали смещение 2px, он работал идеально.
Кроме того, 9-патч-изображения имеют тенденцию проявляться в затмении именно так, как вы думаете... но затем появляются разные на телефоне/эмуляторе.
Изучение 9-патч-инструмента - это отличная вещь, так как это позволяет сделать большую настройку. Еще один совет, если вы хотите сделать что-то вроде замены любого андроидного 9-патча своими собственными изменениями - просто скопируйте 9patch, который существует в SDK, и измените его. По какой-то причине 9-кратные изображения в SDK имеют странные смещения. Выполнение этого гарантирует, что вы не получите странных ответов от ваших 9-патчей. Пример этого - я описываю editText в красном цвете, когда задан плохой ввод.
Изображения SDK можно найти на SDK- > платформах → [plateform-you-want] → data- > res-drawable- [you-choice]
Вы также можете посмотреть изображения SDK 9-patch, чтобы понять, как работает 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
Ответ 3
Возможно, это ошибка в графике с девятью патчами или просто ошибка, вызванная округлением.
Однако мне не нравится ваш подход к рисованию этого значка. Вы пытаетесь расположить элемент экрана с помощью чего-то, что не предназначено для этой задачи.
Вы должны сделать это другим способом: создать некоторый вид контейнера (FrameLayout) с фоном gradiend. Затем поверх этой позиции ImageView с корзиной. Ни одно из этих двух изображений не должно быть девятью патчами, градиенд заполняет весь вид, мусор может быть нарисован без масштабирования.
Несмотря на то, что в области просмотра мусора избыточно, время процессора не тратится в вычислениях с девятью патчами.
Вы использовали бы систему компоновки для точного позиционирования значка корзины. Разумеется, вы получите ожидаемый результат, так как макеты UI хорошо настроены и предназначены для позиционирования элементов экрана. Изображения с девятью патчами используются для других целей (где пиксели смещены здесь или там немного не имеет значения).
Ответ 4
Как сказал @jjNford - это плохая практика работать с изображениями таким образом.
Для этой задачи лучшим решением является создание значка "мусор" с прозрачным фоном и создание shape
drawable с градиентом. Таким образом, вы можете удалить ненужный 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"/>
Документы для рисования фигур.
ИЗМЕНИТЬ
Просто проверьте свое изображение - он отлично крахмальный на SE Xperia 2.3.3