web-dev-qa-db-ja.com

MenuItem ActionViewに使用するレイアウトを拡張するとき、ルートに何を渡す必要がありますか?

ImageViewとしてMenuItemにアタッチするActionViewがあります(アイテムはActionBarに表示されます)。このビューのレイアウトはXMLから取得されます。私はそれを次のように膨らませています:

_ImageView actionView = (ImageView) layoutInflater.inflate(
   R.layout.action_view_layout, null);
_

これはうまくいくようです。しかしながら; inflate()への呼び出しでrootにnullを渡すと、Lintが私を怒らせます:

ビュールートとしてnullを渡さないようにします(膨張したレイアウトのルート要素のレイアウトパラメーターを解決する必要があります)

私は特定のケースでルートなしで管理できるように見えますが、できるだけコードを正確にしたいです。問題は、ここでどのViewをルートとして使用すべきかわからないことです。 この回答 は、「膨張させたいビューオブジェクトを囲むウィジェット」であるべきだと言っています。しかし、それはここでどういう意味ですか?アクションバー用のもの?アクティビティ?完全に何か他のもの?


更新:回答を読んで、私が正しいことをしているのではないかと疑っています:

  1. ActionBarに対応するViewMenuItemを取得します
  2. そのルートを取得
  3. ルートをViewGroupにキャストします
  4. 結果をインフレータに渡す

これはうまくいくようです。これを行うべきかどうかを誰でも確認または拒否できますか?

37
dlf

私は次のように単純にそれをします:

menuItem.setActionView(R.layout.action_view_layout);

Androidビューを膨張させてください。

このImageView呼び出しで追加の変更を行う必要がある場合

ImageView imageView = (ImageView) menuItem.getActionView();

更新

あなたの好奇心に応えるために。これは、Googleの人々が内部で行うことです。

public MenuItem setActionView(int resId) {
    final Context context = mMenu.getContext();
    final LayoutInflater inflater = LayoutInflater.from(context);
    setActionView(inflater.inflate(resId, new LinearLayout(context), false));
    return this;
}
24
Damian Petla

これを見てください。レイアウトインフレータについてもうまく説明しています。

標準アプリケーションで使用できるinflate()メソッドには、次の2つのバージョンがあります。

inflate(int resource, ViewGroup root)
inflate(int resource, ViewGroup root, boolean attachToRoot)

最初のパラメーターは、インフレートするレイアウトリソースを指します。 2番目のパラメーターは、アタッチするリソースを拡張する階層のルートビューです。 3番目のパラメーターが存在する場合、膨張後にビューが供給されたルートにアタッチされるかどうかを制御します。

少し混乱を招く可能性があるのは、これら最後の2つのパラメーターです。このメソッドの2つのパラメーターバージョンを使用すると、LayoutInflaterは、指定されたルートに膨張ビューを自動的にアタッチしようとします。ただし、フレームワークには、ルートにnullを渡すと、アプリケーションのクラッシュを回避するためにこの試行をバイパスするチェックがあります。

多くの開発者はこの振る舞いを利用して、インフレーション時に添付ファイルを無効にする適切な方法は、ルートとしてnullを渡すことです。多くの場合、inflate()の3つのパラメーターバージョンが存在することさえ認識していません。

レイアウトインフレの詳細

12
Top Cat

通常、actionViewをinに追加するもの(ViewGroupサブクラス)を渡して膨らませます。親ではなくinflate呼び出しからactionViewを取得するには、3番目のパラメーターfalseを追加して、膨張したビューが親に追加されないようにします。

ImageView actionView = 
    (ImageView)layoutInflater.inflate(R.layout.action_view_layout, parent, false);
// .. do whatever you like with actionView and then add it to it's parent
menuItem.addActionView(actionView)

かなり良いチュートリアルがあります here 物事については少し異なります。次のようなaction_view_layoutの一部としてmenu.xmlを指定しています。

Android:actionLayout="@layout/action_view_layout"

常に同じレイアウトを使用していれば、これも機能する可能性があります。そのルートに行けば、次のようにしてActionViewを取得できます

ImageView actionView = menu.findItem(R.id.whatever).getActionView();
3
user2399268