Android:制作/显示9patch图像时的对齐错误

15

NinePatch:

垃圾桶图标 NinePatch 图片

截图:

NinePatch 对齐不准确的截图

布局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”是UI元素,可进行开关控制。当关闭编辑模式时,“edit_tray”(包括垃圾桶图标)会被隐藏。当打开编辑模式时,“edit_tray”会被显示,并覆盖在ScrollView内容上。

垃圾桶图标由两个元素组成:图标本身和它后面的线性渐变。NinePatch图像包含三个可伸缩区域和一个静态区域以适应这些元素。图像中央的垃圾桶图标是静态的,应该直接出现在屏幕底部的水平中心位置。渐变应该从一边延伸到另一边并覆盖在屏幕底部。

问题?

NinePatch图像在图像水平两侧仅包含一个像素的可伸缩区域。理论上,这样的效果应该是垃圾桶图标会直接出现在中心(左边的1个像素等于右边的1个像素)。然而,如上面的截图所示,情况并非如此。注意:该截图来自我的测试手机——T-Mobile G2。在模拟器中也可以看到同样的问题。但是,在draw9patch预览和eclipse图形布局视图中,图像是完全分配的。

我尝试了几种不同的方法,试图找出错误在哪里,并尝试修复它或解决它。包括:使用ImageView而不是View(相同效果),使用android:scaleType="fitXY"(相同问题),在运行时检查屏幕宽度和“edit_tray”宽度是否相同(它们是相同的),使用两个不同的图像作为渐变(作为edit_tray背景)和图标(作为ImageView src)(会导致另一个问题,即两个图像未重叠。通过在两个图像上设置绝对高度来解决)。等等。

答案、解决方法和真正的问题

我使用一些具有每侧最多六个可伸缩区域的简单NinePatch图像进行了一些测试。我注意到在至少一个测试情况下(手机、模拟器、draw9patch、eclipse图形布局)存在一些显示问题。

我决定尝试水平扩展图像,以便在垃圾桶图标的边缘显示更多线性渐变。我将图像大小调整为128x64(之前为64x64)。我使更多的边缘成为可拉伸部分,以尝试遏制可能发生在图像上的任何错误计算。Draw9patch报告了糟糕的部分,因此我将它放回到只有两个像素,一个在每侧。它奏效了!图标现在直接位于屏幕中心!我不知道为什么,但是只要改变图像的宽度到128,而不改变图像的可拉伸部分,它现在就能工作。

我尝试将图像重新调整到大约100像素宽以去除一些冗余像素,结果错误又出现了!不仅如此,图标的位置与屏幕中心相同的偏移量。我无法理解为什么会这样。

有人有任何想法吗?这是一个错误吗?

目前,我通过上述的解决方法解决了这个问题,但如果有人有任何建议,我会倾听。

4个回答

6

按照我所做的方式,使用4个点来制作您的9 Patch图像,它将正常工作。

enter image description here

创建9 Patch图像的技巧(不是设计师,只是告诉您我的方法)

  • 在左侧和顶部放置点。
  • 如果您在中间有一些文本或图像,则将点放在图像的左侧和右侧以及该图像或文本的顶部和底部。
  • 始终确保左右两侧(左-右和上-下)的空间数量和点的数量相等。
  • 在使用2x到6x之前,请始终检查预览或右侧。

我得检查一下。我没有添加底部补丁,因为我想让垃圾桶保持在底部。我没有意识到仅指定6个补丁可能会破坏Nine-Patch。 - SubOne

1

可能是在九宫格绘制中出现了错误,或者只是由于四舍五入导致的错误。

然而,我不喜欢你绘制这个图标的方法。您尝试使用未设计用于此任务的内容来定位屏幕元素。

您应该以其他方式绘制:创建一些容器视图(FrameLayout),并带有渐变背景。然后在其上方定位具有删除图标的ImageView。这两个图像都无需使用九宫格图像,渐变将填充整个视图,垃圾桶将绘制而不进行缩放。 虽然在垃圾桶视图区域存在过度绘制,但CPU时间不会浪费在九宫格区域计算上。

您可以使用布局系统精确定位垃圾桶图标。当然,您将获得预期的结果,因为UI布局经过良好调整,专门用于定位屏幕元素。九宫格图像用于其他用途(其中稍微移动一下的像素不应该有影响)。


1

根据我使用9-patch工具的经验,每个图像的每一侧都有一个自动1像素偏移量。如果您只使用了这个1像素的偏移量,那么您的图像实际上并没有被拉伸成您想象的那样。

这可以通过使用2像素偏移量时完美工作来看出。

此外,9-patch图像往往会在eclipse中以您期望的方式显示...但在手机/模拟器上却表现不同。

学习9-patch工具是非常好的,因为它允许更大的自定义。另一个提示是,如果您想要像替换任何android 9-patch一样进行自己的修改-那么只需复制SDK中存在的9patch并进行修改。由于某种原因,SDK中的9patch图像具有奇怪的偏移量。这样做将确保您不会从9-patches获得奇怪的响应。例如,当输入错误时,我用红色勾画出editText。

SDK图像可以在SDK->平台->[您选择的平台]->数据->res-drawable-[您的选择]中找到

您还可以查看SDK 9-patch图像以帮助理解9-patch工具的工作原理。

希望这能提供更多的见解。

以下是一些好的链接: 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


我不知道你在前两段中想表达什么。看起来你没有回答实际问题或提供相关信息。 - SubOne
抱歉尝试给你我的见解。 - jjNford

0

正如@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"/>

形状可绘制文档

编辑

请检查您的图片 - 在SE Xperia 2.3.3上可以很好地拉伸。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接