android – 如何完全覆盖9-PATCH-PNG?

我尝试通过在按钮背景和按钮图标上放置一个半透明的PNG文件来实现悬停效果(按下按钮时的效果).不幸的是,按钮背景文件是一个9-PATCH-PNG,它在这里引起了一些麻烦:它“吞下”其层顶部的所有东西,并且不允许覆盖九个补丁-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”无效.你有什么建议吗?

更新

我试过跟随,这将避免缩放,建议从here.但也没有工作:

<!-- 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

这对我有用吗? Making Overlaid image transparent on touch in Android?

解决方法

[没关系]
LayerDrawable.getPadding的内部注释声称它从列表中的第一个drawable获取填充.如果这个评论说实话,你可以通过在列表中的9补丁之前放置一个任意(可能是空的)图像来获得你想要的行为.

但是,快速阅读代码意味着它实际上使用了所有项目填充的总和,这意味着使用默认的LayerDrawable无法消除您的问题.该语句暗示了解决方案:实现LayerDrawable的子类,它覆盖“getPadding”以返回{0,0}.您可能必须在代码中初始化子类,而不是通过加载XML布局,但这并不是特别困难.
[/没关系]

更新:
上面的解决方案不起作用,因为问题不在于填充本身,而是默认实现将每个图像的边界设置为前面图像的填充之和.换句话说,它强制执行嵌套,这是大多数人想要的.正确的解决方案仍然是覆盖LayerDrawable,但你改为替换“onBoundsChange”.完整的,经过测试的演示如下:

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,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);
    }
  }
}

使用以下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:

根据要求,以下是如何修改它以在代码中初始化选择器.用以下代码替换“mCover1”的初始化:

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;

这将在正常情况下显示绿色,其中窗口聚焦但未按下按钮,按下按钮时为红色,窗口未聚焦时为默认可绘制(灰色). (尝试向下拖动“windowshade”通知栏以查看窗口处于未聚焦状态.)

以上是来客网为你收集整理的android – 如何完全覆盖9-PATCH-PNG?全部内容,希望文章能够帮你解决android – 如何完全覆盖9-PATCH-PNG?所遇到的程序开发问题。

如果觉得来客网网站内容还不错,欢迎将来客网网站推荐给程序员好友。