回答:
MenuItem
そのようなアイテムへのポイントを取得し、setVisible
それを呼び出して可視性を調整してから、invalidateOptionsMenu()
、アクティビティをて、それに応じてActionBarメニューを調整します。
更新: A MenuItem
は、レイアウトの一部である通常のビューではありません。その特別な何か、完全に異なる。あなたのコードが戻ってきnull
てitem
、それがクラッシュの原因です。代わりにあなたがする必要があるのは:
MenuItem item = menu.findItem(R.id.addAction);
最初の呼び出しを:ここでは、呼び出す必要があります順序でinvalidateOptionsMenu()
、その後の内部onCreateOptionsMenu(Menu)
(呼び出すことでのMenuItemへの参照を取得menu.findItem()
)と呼んでsetVisible()
、それには、
MenuItem
ことがnull
原因である可能性がgetItem
ありfindItem
ます。私たちはあなたのコードとクラッシュログの両方を見なければ、決して知ることができませんでした。
onCreateOptionsMenu
その時点で項目の可視性を設定してください。または、表示するかどうかを決定するまで参照を維持します。
invalidateOptionsMenu()
、次に内部で(を呼び出すことにより)onCreateOptionsMenu(Menu)
への参照を取得して呼び出すことです。suhas_smとP1r4nh4 による回答は、正しいアプローチを示しています。MenuItem
menu.findItem()
setVisible()
この質問の補遺が見つかりました:
外出先でメニュー項目の可視性を変更する場合は、アクティビティにメンバー変数を設定して、メニューinvalidateOptionsMenu()
を非表示にし、オーバーライドされたonCreateOptionsMenu(...)
メソッドで項目を呼び出して非表示にすることを覚えておく必要があります。
//anywhere in your code
...
mState = HIDE_MENU; // setting state
invalidateOptionsMenu(); // now onCreateOptionsMenu(...) is called again
...
@Override
public boolean onCreateOptionsMenu(Menu menu)
{
// inflate menu from xml
MenuInflater inflater = getSupportMenuInflater();
inflater.inflate(R.menu.settings, menu);
if (mState == HIDE_MENU)
{
for (int i = 0; i < menu.size(); i++)
menu.getItem(i).setVisible(false);
}
}
私の例では、すべてのアイテムを非表示にしています。
if (HIDE_MENU) { return false; } else { getSupportMenuInflater().inflate(R.menu.menu_settings, menu); return true; }
ドキュメントの状態:「メニューを表示するにはtrueを返す必要があります。falseを返すと表示されません」。
onPrepareOptionsMenu()
onCreateOptionsMenu()
一度だけ呼び出されるので、表示/非表示ロジックに使用する必要がある ため、初期化後にメニュー項目を変更する場合は役に立ちません。したがって、onCreateではインフレートしますが、onPrepareでは表示/非表示にします。
はい。
invalidateOptionsMenu()
オプションを非表示にしたいときに呼び出します。これはを呼び出しますonCreateOptionsMenu()
。onCreateOptionsMenu()
フラグ/条件および表示または非表示にするためのチェック次の方法:MenuItem item = menu.findItem(R.id.menu_Done); if (flag/condition)) { item.setVisible(false); } else { }
invalidateOptionsMenu
代わりにすべきではありませんinvalidateOptions
か?
onCreateOptionsMenu
もう少し前後関係のある答えを探していました。私はそれを理解したので、その答えを追加します。
で設定されてandroid:visible="false"
いるように、デフォルトでは共有ボタンは非表示になります。
main_menu.xml
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<!-- hide share button by default -->
<item
android:id="@+id/menu_action_share"
android:icon="@drawable/ic_share_white_24dp"
android:visible="false"
android:title="Share"
app:showAsAction="always"/>
<item
android:id="@+id/menu_action_settings"
android:icon="@drawable/ic_settings_white_24dp"
android:title="Setting"
app:showAsAction="ifRoom"/>
</menu>
ただし、共有ボタンは、状況に応じてオプションで表示できます。
MainActivity.java
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.main_menu, menu);
MenuItem shareItem = menu.findItem(R.id.menu_action_share);
// show the button when some condition is true
if (someCondition) {
shareItem.setVisible(true);
}
return true;
}
invalidateOptionsMenu()
してメニューを更新します。
うまくいきませんでした。onPrepareOptionsMenu
アイテムを非表示にするには、明示的に使用する必要がありました。
したがってonCreateOptionsMenu
、メニューの作成やonPrepareOptionsMenu
可視性の変更などに使用します。
onPrepareOptionsMenu
このタイプの操作を行うのに適切な場所のように思われます。このメソッドを使用すると、アイテムを効率的に有効/無効にしたり、コンテンツを動的に変更したりできます。」
invalidateOptionsMenu()
してメニューを更新します。
以下のように、最初にメニューレイアウトファイルでメニュー項目の可視性をfalseに設定します。
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:visible="false"
android:id="@+id/action_do_something"
android:title="@string/txt_do_something"
app:showAsAction="always|withText"
android:icon="@drawable/ic_done"/>
</menu>
次に、メニューを拡張した後、onCreateOptionsMenu()でメニュー項目の可視性をfalseに設定するだけです。
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
inflater.inflate(menu,R.menu.menu);
MenuItem item = menu.findItem(R.id.menuItemId);
if (item != null){
item.setVisible(false);
}
}
これは、アクティビティとフラグメントの両方から私のために働きました
@Override
public void onPrepareOptionsMenu(Menu menu) {
super.onPrepareOptionsMenu(menu);
if (menu.findItem(R.id.action_messages) != null)
menu.findItem(R.id.action_messages).setVisible(false);
}
P1r4nh4の回答は問題なく機能します。ブールフラグを使用して単純化しました。
public int mState = 0; //at the top of the code
//where you want to trigger the hide action
mState = 1; // to hide or mState = 0; to show
invalidateOptionsMenu(); // now onCreateOptionsMenu(...) is called again
...
@Override
public boolean onCreateOptionsMenu(Menu menu)
{
// inflate menu from xml
MenuInflater inflater = getSupportMenuInflater();
inflater.inflate(R.menu.settings, menu);
if (mState == 1) //1 is true, 0 is false
{
//hide only option 2
menu.getItem(2).setVisible(false);
}
}
0
おり1
、「ブールフラグ」ではなく、疑似ブールです。さらに、実際のブール値をここで使用する理由はありません。
Android Developer Officialのサイトによると、OnCreateOptionMenu(メニューメニュー)は、実行時にメニュー項目やアイコン、visibility..etcを変更することは推奨されていません。
システムがonCreateOptionsMenu()を呼び出した後、システムはユーザーが入力したMenuのインスタンスを保持し、何らかの理由でメニューが無効化されない限り、onCreateOptionsMenu()を再度呼び出しません。ただし、onCreateOptionsMenu()は、メニューの初期状態を作成するためにのみ使用し、アクティビティのライフサイクル中に変更を加えないでください。
アクティビティのライフサイクル中に発生するイベントに基づいてオプションメニューを変更する場合は、onPrepareOptionsMenu()メソッドで変更できます。このメソッドは、現在存在するMenuオブジェクトを渡します。そのため、項目の追加、削除、無効化などの変更が可能です。(フラグメントはonPrepareOptionsMenu()コールバックも提供します。) --AndroidDeveloper公式サイト-
推奨通りこのonOptionsItemSelected(MenuItem item)メソッドを使用して、ユーザー入力を追跡できます。
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.edit) {
Intent intent = new Intent(this, ExampleActivity.class);
intent.putExtra(BUNDLE_KEY, mConnection);
startActivityForResult(intent, PICK_CHANGE_REQUEST);
return true;
} else if (id == R.id.delete) {
showDialog(this);
return true;
}
return super.onOptionsItemSelected(item);
}
実行時にメニュー項目を変更する必要がある場合は、onPrepareOptionsMenu(メニューメニュー)を使用して変更できます。
@Override
public boolean onPrepareOptionsMenu(Menu menu){
if (Utils.checkNetworkStatus(ExampleActivity.this)) {
menu.findItem(R.id.edit).setVisible(true);
menu.findItem(R.id.delete).setVisible(true);
}else {
menu.findItem(R.id.edit).setVisible(false);
menu.findItem(R.id.delete).setVisible(false);
}
return true;
}
setVisible(false)
れているため、常に表示されるアイテムの場合は、3つのドット(メニュー自体)をクリックするまで消えません。アイテムで使用するinvalidateOptionsMenu()
とonPrepareOptionsMenu
すぐに再編成されますが、アクションは失われます(アイテムをクリックしても何も起こりません)。
変数に値を設定し、invalidateOptionsMenu();を呼び出します。
例えば
selectedid=arg2;
invalidateOptionsMenu();
public boolean onPrepareOptionsMenu(Menu menu) {
if(selectedid==1){
menu.findItem(R.id.action_setting).setVisible(false);
menu.findItem(R.id.action_s2).setVisible(false);
menu.findItem(R.id.action_s3).setVisible(false);
}
else{
if(selectedid==2){
menu.findItem(R.id.action_search).setVisible(false);
menu.findItem(R.id.action_s4).setVisible(false);
menu.findItem(R.id.action_s5).setVisible(false);
}
}
return super.onPrepareOptionsMenu(menu);
}
setVisible(false)
れているため、常に表示されるアイテムの場合は、3つのドット(メニュー自体)をクリックするまで消えません。アイテムで使用するinvalidateOptionsMenu()
とonPrepareOptionsMenu
すぐに再編成されますが、アクションは失われます(アイテムをクリックしても何も起こりません)。
メニューのすべてのアイテムの表示を設定すると、アプリバーメニューまたはオーバーフローメニューが自動的に非表示になります
例
private Menu menu_change_language;
...
...
@Override
public boolean onCreateOptionsMenu(Menu menu) {
...
...
menu_change_language = menu;
menu_change_language.findItem(R.id.menu_change_language)
.setVisible(true);
return super.onCreateOptionsMenu(menu);
}
他のフラグメントに進む前に、次のコードを使用します。
if(menu_change_language != null){
menu_change_language.findItem(R.id.menu_change_language)
.setVisible(false);
}
https://stackoverflow.com/a/21215280/466363-Look AlternoおよびSufianによる回答
。
private Menu mMenu;
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.track_fragment, menu);
mMenu = menu;
}
...
private void someMethod() {
...
if (mMenu != null) {
MenuItem item = mMenu.findItem(R.id.new_track);
if (item != null) {
item.setVisible(false);
ActivityCompat.invalidateOptionsMenu(this.getActivity());
}
}
...
}
ActivityCompat.invalidateOptionsMenu()はonPrepareOptionsMenu();をコールバックしません。メニューを直接更新するだけです。
私のsomeMethod()は、onCreateOptionsMenu()の前でも、いくつかの場所から呼び出されるため、mMenu!= nullを確認する必要があります。
上記の回答のようにすべてを実行してもメニュー項目が表示されている場合は、一意のリソースを参照していることを確認してください。たとえば、onCreateOptionsMenuまたはonPrepareOptionsMenu
@Override
public void onPrepareOptionsMenu(Menu menu) {
super.onPrepareOptionsMenu(menu);
MenuItem menuOpen = menu.findItem(R.id.menu_open);
menuOpen.setVisible(false);
}
Ctrlキーを押しながらR.id.menu_openをクリックし、1つのメニューファイルにのみ存在することを確認します。このリソースがすでにどこかで使用されており、アクティビティに読み込まれている場合、そのリソースを非表示にしようとします。
1つのコマンドだけでメニューのすべての項目を非表示にする最良の方法は、メニューxmlで「グループ」を使用することです。同じグループ内のオーバーフローメニューに含まれるすべてのメニュー項目を追加するだけです。
この例では、常に表示される2つのメニュー項目(通常の項目と検索)と3つのオーバーフロー項目があります。
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/someItemNotToHide1"
android:title="ITEM"
app:showAsAction="always" />
<item
android:id="@+id/someItemNotToHide2"
android:icon="@android:drawable/ic_menu_search"
app:showAsAction="collapseActionView|ifRoom"
app:actionViewClass="android.support.v7.widget.SearchView"
android:title="Search"/>
<group android:id="@+id/overFlowItemsToHide">
<item android:id="@+id/someID"
android:orderInCategory="1" app:showAsAction="never" />
<item android:id="@+id/someID2"
android:orderInCategory="1" app:showAsAction="never" />
<item android:id="@+id/someID3"
android:orderInCategory="1" app:showAsAction="never" />
</group>
</menu>
次に、アクティビティ(onCreateOptionsMenuで推奨)で、コマンドsetGroupVisibleを使用して、すべてのメニュー項目の可視性をfalseまたはtrueに設定します。
public boolean onCreateOptionsMenu(Menu menu) {
menu.setGroupVisible(R.id.overFlowItems, false); // Or true to be visible
}
アクティビティの他の場所でこのコマンドを使用する場合は、必ずメニュークラスをローカルに保存し、createOptionsMenuの前に実行できるため、常にメニューがnullかどうかを確認してください。
Menu menu;
public boolean onCreateOptionsMenu(Menu menu) {
this.menu = menu;
}
public void hideMenus() {
if (menu != null) menu.setGroupVisible(R.id.overFlowItems, false); // Or true to be visible
}
Appcompatライブラリを使用する場合:ActivityがActionBarActivityをサブクラス化する場合、supportInvalidateOptionsMenu()を呼び出すことができます。
ここに見られる:https : //stackoverflow.com/a/19649877/1562524
メニューのメンバー変数を使用し、onCreateOptionsMenu()で初期化し、後でオプションメニューを無効にせずにsetVisible()を使用するのが、より良いアプローチだと思います。
このコードは私のために働きました
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main_menu,menu);
if (Application.sharedPreferences.getInt("type",1) == 2)
{
menuItem = menu.findItem(R.id.menu_travel_orders);
menuItem.setVisible(false);
}
return super.onCreateOptionsMenu(menu);
}
このアプローチは私にとってうまくいきました:
private Menu thismenu;
if (condition)
{
if(thismenu != null)
{
thismenu.findItem(R.id.menu_save).setVisible(true);
Toast.makeText(ProfileActivity.this,
""+thismenu.findItem(R.id.menu_save).getTitle(),
Toast.LENGTH_SHORT).show();
}else
{
thismenu.findItem(R.id.menu_save).setVisible(false);
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.profile_menu, menu);
thismenu = menu;
return true;
}
スコープにアクセスできないアクティビティからメニュー項目にアクセスしようとしています。メニュー項目を検索する呼び出しはnullを返します。これは、ビューが、呼び出し元のアクティビティまたはレイアウトのどちらにもバインドされていないためです。
メニュー項目は、「ナビゲーションバー」などの項目にバインドされ、次に対応するアクティビティにバインドされます。
したがって、アクティビティ()でこれらのビューを初期化し、そのビューを使用してメニュー項目にアクセスします。
Navigation navView;
navView = findViewById(R.id.navigationView);
MenuItem item = navView.getMenu().findItem(R.id.item_hosting);
item.setVisible(false);
使用する invalidateOptionsMenu()
呼び出すために onPrepareOptionsMenu(menu: Menu?)
onCreateOptionsMenu()は、初期メニュー状態を作成するためにのみ使用し、アクティビティのライフサイクル中に変更を加えないでください...
イベントが発生してメニューの更新を実行したい場合は、invalidateOptionsMenu()を呼び出して、システムがonPrepareOptionsMenu()を呼び出すように要求する必要があります。
Android kotlin、アクションバーのメニュー項目の可視性をプログラムで非表示または設定。
override fun onCreateOptionsMenu(menu: Menu): Boolean {
val inflater = menuInflater
inflater.inflate(R.menu.main_menu, menu)
val method = menu.findItem(R.id.menu_method)
method.isVisible = false //if want to show set true
return super.onCreateOptionsMenu(menu)
}