如何完全覆盖 9-PATCH-PNG?
我尝试通过将半透明 PNG 文件放在按钮背景和按钮图标上来实现悬停效果(按下按钮时的效果)。不幸的是,按钮背景文件是 9-PATCH-PNG,这会在这里造成一些麻烦:它“吞噬”其图层顶部的所有内容,并且不允许覆盖 9-patch-png 的可拉伸区域(周围的细光线) 。 换句话说,9 PATCH PNG 的顶部和左侧边缘的黑线不仅会导致拉伸,还会导致填充行为。
删除 9-Patch-Information 并不是一个好的解决方案。
在这里你可以看到我的按钮。蓝色背景是 9 PATCH PNG。按钮周围的细光线是不需要的。
该图层列表分配给按钮属性“background”:
<?xml version="1.0" encoding="utf-8"?>
<layer-list
xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:drawable="@drawable/home_btn_bg_blue_without_padding" />
<item>
<bitmap
android:src="@drawable/home_icon_test"
android:gravity="center" />
</item>
<item
android:drawable="@drawable/layer_black_50" />
</layer-list>
将图层的偏移设置为“-1 " 在每个边界上都是无效的。你们有建议吗?
更新
我尝试了以下操作,这将避免缩放,建议来自此处。但也不起作用:
<!-- To avoid scaling, the following example uses a <bitmap> element with centered gravity: -->
<item>
<bitmap android:src="@drawable/image"
android:gravity="center" />
</item>
我的版本(仍然有 9-patch-png 的可拉伸区域未被覆盖):
<?xml version="1.0" encoding="utf-8"?>
<layer-list
xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:drawable="@drawable/home_btn_bg_blue_hover_without_padding" />
<item>
<bitmap
android:src="@drawable/home_icon_test"
android:gravity="center" />
</item>
<item>
<bitmap android:src="@drawable/layer_black_100"
android:height="100dp"
android:width="100dp"/></item>
</layer-list>
更新 2
这对我有用吗? 在 Android 中使重叠图像在触摸时透明?
I try to implement a hover effect (effect when button is pressed) through putting a semi transparent PNG file on top of the button background and the button icon. Unfortunatly the button background file is a 9-PATCH-PNG which causes some trouble here: It "swallows" everything on top of its layer and doesnt allow to cover the stretchable areas (the fine light line around) of the nine-patch-png. In other words, the black lines the top and left edge of the 9 PATCH PNG cause not only stretching, but also padding behaviour.
Removing the 9-Patch-Information is not a good solution.
Here u can see my Button. The blue background is a 9 PATCH PNG. The thin light line around the button is unwanted.
This layer-list is assigned to the button attribute "background":
<?xml version="1.0" encoding="utf-8"?>
<layer-list
xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:drawable="@drawable/home_btn_bg_blue_without_padding" />
<item>
<bitmap
android:src="@drawable/home_icon_test"
android:gravity="center" />
</item>
<item
android:drawable="@drawable/layer_black_50" />
</layer-list>
Setting the offsets of the layer to "-1" on each border is not valid. Have u guys suggestions?
Update
I tried following, which shall avoid scaling, suggested from here. But didn't work either:
<!-- To avoid scaling, the following example uses a <bitmap> element with centered gravity: -->
<item>
<bitmap android:src="@drawable/image"
android:gravity="center" />
</item>
My version (There are still the stretchable areas of the 9-patch-png uncovered):
<?xml version="1.0" encoding="utf-8"?>
<layer-list
xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:drawable="@drawable/home_btn_bg_blue_hover_without_padding" />
<item>
<bitmap
android:src="@drawable/home_icon_test"
android:gravity="center" />
</item>
<item>
<bitmap android:src="@drawable/layer_black_100"
android:height="100dp"
android:width="100dp"/></item>
</layer-list>
Update 2
Could that work for me? Making Overlaid image transparent on touch in Android?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
[没关系]
LayerDrawable.getPadding 的内部注释声称它从列表中的第一个可绘制对象中获取填充。如果此评论说的是实话,您可以通过在列表中的 9 补丁之前放置任意(可能是空)图像来获得您想要的行为。
然而,快速阅读代码意味着它实际上使用了所有项目填充的总和,这意味着使用默认的 LayerDrawable 无法消除您的问题。该语句暗示了解决方案:实现 LayerDrawable 的子类,它重写“getPadding”以返回 {0, 0, 0, 0}。您可能必须在代码中初始化您的子类,而不是通过加载 XML 布局,但这并不是特别困难。
[/没关系]
更新:
上面的解决方案不起作用,因为问题不是填充本身,而是默认实现将每个图像的边界设置为前面图像的填充之和。换句话说,它强制执行嵌套,这是大多数人想要的。正确的解决方案仍然是覆盖 LayerDrawable,但您可以替换“onBoundsChange”。完整的、经过测试的演示如下:
使用以下布局/main.xml
示例屏幕截图如下:
更新 2:
根据要求,以下是您可以修改它以在代码中初始化选择器的方法。将“mCover1”的初始化替换为以下代码:
这将在窗口获得焦点但未按下按钮的正常情况下显示绿色,按下按钮时显示红色,窗口打开时显示默认的可绘制(灰色)不专心。 (尝试向下拖动“windowshade”通知栏以查看处于未聚焦状态的窗口。)
[NeverMind]
The internal comments for LayerDrawable.getPadding claim that it takes the padding from the first drawable in the list. If this comment is telling the truth, you could get the behavior you want by putting an arbitrary (perhaps empty) image before your 9 patch in the list.
A quick reading of the code, however, implies that it actually uses the sum of all the item's paddings, which means that there's no way to eliminate your problem using the default LayerDrawable. The statement implies the solution: implement a subclass of LayerDrawable which overrides "getPadding" to return {0, 0, 0, 0}. You may have to initialize your subclass in code rather than by loading an XML layout, but this isn't particularly difficult.
[/NeverMind]
Update:
The solution above doesn't work, because the problem isn't the padding itself, it's the fact that the default implementation sets the bounds of each image to be the sum of the paddings of the preceding images. In other words, it enforces nesting, which is what most people will want. The proper solution is still to override LayerDrawable, but you replace "onBoundsChange" instead. A complete, tested demo follows:
using the following layout/main.xml
A sample screenshot follows:
Update 2:
As requested, here's how you can modify it to initialize a Selector within the code. Replace the initialization of "mCover1" with the following code:
This will show green in the normal case where the window is focused but the button isn't pressed, red when the button is pressed, and the default drawable (grey) when the window isn't focused. (Try dragging down the "windowshade" notification bar to see the window in it's unfocused state.)
我让它工作得很好:
res/layout/main.xml
res/drawable/button.xml
frame.9.png 是我的九个补丁-png。番茄是一个基本的 png,周围有透明度。
这是结果:
删除番茄周围的透明部分(用粉红色填充):
编辑 2:
这将使番茄完全覆盖 patch-9-png :
使用 ImageButton 的另一种方法是,您可以使用 patch-9-png 作为背景,使用“内容”作为按钮的 src。在这种情况下,您需要将该 src 的 padding 设置为 0
I got it working just fine :
res/layout/main.xml
res/drawable/button.xml
frame.9.png is my nine-patch-png. Tomato is a basic png with transparency around it.
Here is the result :
Removing the transparent part around the tomato (filling up with pink) :
Edit 2:
This will make the tomato cover completely the patch-9-png :
Another way, with using an ImageButton is that you can use the patch-9-png as the background and the "content" as the src of the button. In that case, you need to set the padding to 0 for that src
我通过操纵九个补丁获得了完整的覆盖。不要将底部和右侧(内容)留空,而是尝试用黑色像素完全填充它们。
I got a full overlay to work by manipulating the nine-patch. Instead of leaving the bottom and right sides (content) empty, try filling them in completely with black pixels.
我认为这个问题有两种解决方案。
解决方案1:
当您说“悬停效果”时,您是指按下按钮时吗?如果是这种情况,那么您想要使用 选择器又名按钮背景的状态列表,其中选定的状态与正常图像不同:
然后将按钮背景设置为该状态列表可绘制 XML。
解决方案2:
虽然您还没有发布原始的九个补丁PNG,但我怀疑您可以删除表示“填充框”的右侧和底部标记,同时保留左侧和顶部标记,表示“填充框” 2D 图形文档。这将保留图像当前的拉伸行为,但删除图像固有的任何填充。然后,您可以根据需要向内部视图添加或删除填充,以获得所需的显示。
I think there are two solutions to this issue.
Solution 1:
When you say "hover effect", do you mean while the button is being pressed down? If that's the case, then what you want to do use use a selector a.k.a. state list for the button background, where the selected state is different than your normal image:
Then set the button background to that state list drawable XML.
Solution 2:
While you haven't posted your raw nine patch PNG, I suspect that you can remove the right and bottom markings denoting the "padding box", while keeping the left and top markings, denoting the "Stretchable area" as documented in the 2D Graphics Doc. This will retain the image's current stretching behavior, but remove any padding that is intrinsic to the image. You can then add or remove padding as desired to the inner views to get the desired display.