71

のアイテムとして使用されるビューがありますListView。私のカスタム アダプターでView.setBackgroundResource()は、リスト内のアイテムの位置に応じてビューの背景を変更します。(リストの最初と最後のアイテムに別々のアセットを持っています。)

これにより、期待どおりに正しい背景画像が設定されますが、ビューの XML 定義で設定したすべてのパディングが完全に無視されるという厄介な副作用があります。

(XML でバックグラウンド ドローアブルを設定し、アダプターで実行時に変更しない場合、パディングはすべて正常に機能します。)

背景画像を変更し、パディングを保持するにはどうすればよいですか? これはバグですか?

編集他の誰かがここで同じ問題を発見したようです:背景を変更すると、LinearLayout のパディングも変更されますか?

4

5 に答える 5

106

私もこの問題に遭遇しました。おそらく、LayerListリソースドローアブルを使用していますか?それが私が使っていたものです。残念ながら、それを修正する「実際の」方法は見つかりませんでした。コードのバグのようですが、追跡しませんでした。ただし、ビューが適切にレンダリングされた後で「バギー」背景を設定していたという意味で幸運だったので、背景を設定した後でパディング値を保存して復元するだけでした。例:

  if(condition) {
    int bottom = theView.getPaddingBottom();
    int top = theView.getPaddingTop();
    int right = theView.getPaddingRight();
    int left = theView.getPaddingLeft();
    theView.setBackgroundResource(R.drawable.entry_bg_with_image);
    theView.setPadding(left, top, right, bottom);
  }

編集:別の方法として、パディングの以前の値を使用する必要はありません。ディメンション値を使用することもできます。

  int pad = resources.getDimensionPixelSize(R.dimen.linear_layout_padding);
  theView.setBackgroundResource(R.drawable.entry_bg_with_image);
  theView.setPadding(pad, pad, pad, pad);
于 2011-05-04T22:12:12.147 に答える
11

dmon が提案したことに加えて、リソースを更新するたびにフープをジャンプする必要がないように、util クラスにスローできる関数を次に示します。これは実際には関数にラップされた彼のコードです。

public static void updateBackgroundResourceWithRetainedPadding(View view, int resourceID)
{
    int bottom = view.getPaddingBottom();
    int top = view.getPaddingTop();
    int right = view.getPaddingRight();
    int left = view.getPaddingLeft();
    view.setBackgroundResource(resourceID);
    view.setPadding(left, top, right, bottom);
}
于 2013-04-08T18:14:17.427 に答える
7

これは Lollipop では修正されているので、

public static void setBackgroundResource(@NonNull View view, @DrawableRes int resId) {
    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
        int paddingTop = view.getPaddingTop();
        int paddingLeft = view.getPaddingLeft();
        int paddingRight = view.getPaddingRight();
        int paddingBottom = view.getPaddingBottom();
        view.setBackgroundResource(resId);
        view.setPadding(paddingLeft, paddingTop, paddingRight, paddingBottom);
    } else {
        view.setBackgroundResource(resId);
    }
}
于 2015-03-30T14:51:42.827 に答える
6

dmon が提案したコードでパディングを取得して設定する代わりに、私が選択した別の解決策は、パディングを使用せず、代わりに内部要素のマージンを使用することです。

レイアウトによっては、実際には同じ量の XML コードである可能性があり、Java はまったく必要ありません。私には少し汚れているように感じますが、その Java コードをあちこちに追加するほど汚れていません。

于 2011-08-29T22:50:30.423 に答える
-2

Monodroid では、SetBackgroundResource への呼び出しをポストすると、上部パディングと下部パディングは変更されません。

private EditText _etInput

public void Disable()
{
    _etInput.Post(() => {
        _etInput.SetBackgroundResource(Resource.Drawable.input_field_background_disabled);
        _etInput.Clickable = false;
});

ただし、左パディングは 0 にリセットされます!? 投稿されていない場合、すべてのパディングは 0 にリセットされます。

これは投稿する価値のある興味深い発見だと思いました...

于 2013-09-23T18:54:10.633 に答える