6

ボタンの背景とボタンのアイコンの上に半透明のPNGファイルを置くことで、ホバー効果(ボタンが押されたときの効果)を実装しようとしています。残念ながら、ボタンの背景ファイルは 9-PATCH-PNG であり、ここでいくつかの問題を引き起こします: そのレイヤーの上にあるすべてのものを「飲み込み」、9-patch-png の伸縮可能な領域 (周りの細い光線) を覆うことができません。 . つまり、9 PATCH PNG の上端と左端の黒い線は、引き延ばしだけでなく、パディング動作も引き起こします。

9-Patch-Information を削除することは適切な解決策ではありません。

ここに私のボタンが表示されます。青色の背景は 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_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

それは私のために働くことができますか?Androidでタッチするとオーバーレイ画像を透明にしますか?

4

4 に答える 4

4

[NeverMind] LayerDrawable.getPadding の内部コメントは、リストの最初のドローアブルからパディングを取得すると主張しています。このコメントが真実を語っている場合、リスト内の 9 パッチの前に任意の (おそらく空の) イメージを配置することで、必要な動作を得ることができます。

ただし、コードをすばやく読むと、実際にはすべての項目のパディングの合計が使用されていることがわかります。つまり、デフォルトの LayerDrawable を使用して問題を解決する方法がないことを意味します。このステートメントは解決策を暗示しています。「getPadding」をオーバーライドして {0, 0, 0, 0} を返す LayerDrawable のサブクラスを実装します。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, 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);
    }
  }
}

次の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」通知バーを下にドラッグして、ウィンドウがフォーカスされていない状態であることを確認してください。)

于 2010-10-08T18:35:55.017 に答える
2

私はそれがうまくいきました:

res/レイアウト/main.xml

...
<ImageButton
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:src="@drawable/button"
    />
...

res/drawable/button.xml

<layer-list
    xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@drawable/frame" /> 
    <item>
        <bitmap
            android:src="@drawable/tomato"
            android:gravity="center"
            />
    </item>
</layer-list>

frame.9.png は私の nine-patch-png です。Tomato は基本的な png で、周囲に透明度があります。

結果は次のとおりです。代替テキスト

トマトの周りの透明部分を取り除く(ピンクで塗りつぶす):代替テキスト

編集 2: これにより、トマトが patch-9-png を完全に覆うようになります。

<layer-list
    xmlns:android="http://schemas.android.com/apk/res/android">
    <item>
    <bitmap
        android:src="@drawable/frame"
        />
    </item>
    <item>
    <bitmap
        android:src="@drawable/tomato"
        />
    </item>
</layer-list>

ImageButton を使用する別の方法は、patch-9-png を背景として使用し、「コンテンツ」をボタンの src として使用することです。その場合、その src のパディングを 0 に設定する必要があります

于 2010-09-28T06:27:09.993 に答える
2

9 パッチを操作することで、完全なオーバーレイが機能するようになりました。下部と右側 (コンテンツ) を空のままにする代わりに、それらを完全に黒のピクセルで埋めてみてください。

于 2011-02-18T18:47:39.867 に答える
1

この問題には2つの解決策があると思います。

解決策 1:

「ホバーエフェクト」とは、ボタンを押している間という意味ですか?その場合、使用したいことは、選択された状態が通常の画像とは異なる、ボタンの背景にセレクター別名状態リストを使用することです。

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_pressed="true"
          android:drawable="@android:color/black" /> <!-- pressed -->
    <item android:drawable="@drawable/home_btn_bg_blue_hover_without_padding" /> <!-- default -->
</selector>

次に、ボタンの背景をそのステート リスト ドローアブル XML に設定します。

解決策 2:

生の 9 パッチ PNG を投稿していませんが、2D グラフィックスドク。これにより、画像の現在の伸縮動作が保持されますが、画像固有のパディングが削除されます。次に、必要に応じて内部ビューにパディングを追加または削除して、目的の表示を取得できます。

于 2010-10-07T18:26:25.663 に答える