如何覆盖9补丁PNG完全?补丁、PNG

由网友(有酒就喝有爱就做)分享简介:我试图通过把一个半透明PNG文件上的按钮,背景和按钮图标的上方,以实现悬停效果(效果时,按钮是pressed)。不幸的是按钮的背景文件是9补丁PNG它在这里引起了一些麻烦:它燕子一切都在它的层和犯规的顶部允许覆盖拉伸区九补丁的PNG(细亮线左右) 。的换句话说,黑线的9 PATCH PNG的顶部和左边缘引起不仅拉伸,而...

我试图通过把一个半透明PNG文件上的按钮,背景和按钮图标的上方,以实现悬停效果(效果时,按钮是pressed)。不幸的是按钮的背景文件是9补丁PNG它在这里引起了一些麻烦:它燕子一切都在它的层和犯规的顶部允许覆盖拉伸区九补丁的PNG(细亮线左右) 。的换句话说,黑线的9 PATCH PNG的顶部和左边缘引起不仅拉伸,而且还填充行为

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.

删除9补丁 - 信息并不是一个很好的解决方案。

Removing the 9-Patch-Information is not a good solution.

这里u可以看到我的按钮。蓝色的背景是9 PATCH PNG。周围的按键的超薄线是不必要的。

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>

设置层的偏移量为-1上的每个边界无效。有u人的建议?

Setting the offsets of the layer to "-1" on each border is not valid. Have u guys suggestions?

更新

我试着以下,其中应避免结垢,从的此处。但没有任何工作:

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>

我的版本(还有9补丁PNG发现的拉伸区域):

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>

更新2

能够为我的工作? http://stackoverflow.com/questions/3021401/making-overlaid-image-transparent-on-touch-in-android

推荐答案

[没关系] 对于LayerDrawable.getPadding内部意见权利要求,它需要的填料从该列表中的第一个可拉伸。如果此评论说的是实话,你可以通过把一个任意的(也许是空的)图像的9补丁之前在列表中得到你想要的行为。

[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.

一个快速阅读的code,然而,意味着它实际使用的之的所有项目的补白,这意味着没有办法来消除你的问题的使用默认LayerDrawable 。该声明意味着解决方案:实施LayerDrawable的一个子类覆盖getPadding返回{0,0,0,0}。您可能需要初始化code,而不是通过加载XML布局你的子类,但这不是特别困难。 [/没关系]

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]

更新: 上述解决方案不起作用,因为这个问题不填充本身,这是一个事实,即默认实现设置的界每个图像的的是$ P $的补白总和pceding图像。换句话说,它强制排料,这是大多数人会想。妥善解决仍覆盖LayerDrawable,但你将onBoundsChange代替。一个完整的,经过测试的演示如下:

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:

package com.beekeeper.ninepatchcover;

import android.app.Activity;
import android.graphics.*;
import android.graphics.drawable.*;
import android.os.Bundle;
import android.view.Gravity;
import android.widget.ImageButton;

public class NinePatchCover extends Activity {
  private Drawable mCover0;
  private Drawable mCover1;

  /** Called when the activity is first created. */
  @Override public void onCreate(final Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    final Drawable button =
      getResources().getDrawable(android.R.drawable.btn_default);
    final Bitmap iconBitmap =
      BitmapFactory.decodeResource(getResources(),
                                   android.R.drawable.ic_menu_mylocation);
    final BitmapDrawable icon = new BitmapDrawable(iconBitmap);
    icon.setGravity(Gravity.CENTER);
    mCover0 =
      getResources().getDrawable(android.R.drawable.title_bar);
    mCover1 =
      getResources().getDrawable(android.R.drawable.title_bar);

    final LayerDrawable unsolved =
      new LayerDrawable(new Drawable[]{button, icon, mCover0});
    final LayerDrawable solved =
      new MyLayerDrawable(new Drawable[]{button, icon, mCover1,}, mCover1);

    ((ImageButton)findViewById(R.id.uncovered)).setBackgroundDrawable(unsolved);
    ((ImageButton)findViewById(R.id.covered)).setBackgroundDrawable(solved);
  }

  class MyLayerDrawable extends LayerDrawable {
    Drawable mCover;

    public MyLayerDrawable(final Drawable[] layers, final Drawable cover) {
      super(layers);
      mCover = cover;
    }

    @Override protected void onBoundsChange(final Rect bounds) {
      super.onBoundsChange(bounds);
      mCover.setBounds(bounds);
    }
  }
}

使用下面的布局/ main.xml中

using the following layout/main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 android:orientation="vertical" android:layout_width="fill_parent"
 android:layout_height="fill_parent"
>
 <ImageButton android:id="@+id/uncovered"
  android:layout_width="fill_parent" android:layout_height="wrap_content" />
 <ImageButton android:id="@+id/covered"
  android:layout_width="fill_parent" android:layout_height="wrap_content" />
</LinearLayout>

一个样本截图如下:

更新2:

根据要求,这里是你如何修改它来初始化中的code进行选择。取代mCover1初始化具有以下code:

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:

final StateListDrawable sld = new StateListDrawable();
sld.addState(new int[]{android.R.attr.state_pressed},
                 new ColorDrawable(0xffff0000));
sld.addState(new int[]{android.R.attr.state_window_focused},
                 new ColorDrawable(0xff00ff00));
sld.addState(new int[]{},
                 getResources().getDrawable(android.R.drawable.title_bar));
mCover1 = sld;

此将显示绿色在正常情况下,该窗口被聚焦但按钮不是pressed,红色按钮时pressed,默认抽拉(灰色)当窗口不重点突出。 (尝试拖累windowshade通知栏看到该窗口在它的聚焦状态。)

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.)

阅读全文

相关推荐

最新文章