2017-05-26 6 views
1

私はこのツールバーを自分のアプリに持っています。ユーザーがログインしているかどうかによって、さまざまなメニュー項目を表示します。ユーザーがログインまたはログアウトすると、自分のレイアウトを更新したいのですが、今は変更を表すツールバーメニューです。しかし、何らかの理由で、私のメニュー項目はまったく削除されず、ログイン状態にかかわらず、すべてが常に表示されます。xmlレイアウトから作成されたツールバーメニューのメニュー項目を変更する

マイメニュー項目:

<menu 
    xmlns:tools="http://schemas.android.com/tools" 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:app="http://schemas.android.com/apk/res-auto"> 

    <item 
     android:id="@+id/action_add" 
     android:icon="@drawable/ic_action_add" 
     android:title="@string/action_add" 
     app:showAsAction="ifRoom"/> 

    <item 
     android:id="@+id/action_login" 
     android:icon="@drawable/ic_action_logged_out" 
     android:title="@string/action_log_in" 
     app:showAsAction="always"/> 

    <item 
     android:id="@+id/action_logout" 
     android:icon="@drawable/ic_action_logged_in" 
     android:title="@string/action_log_out" 
     app:showAsAction="always"/> 
</menu> 

最初のメニュー項目のみがログインしているユーザーに見えることになっている。また、私はそれは自明だと思うが、私は唯一のイン/アウトログのいずれかをしたいですボタンはログイン状態に応じて表示されます。

私のJavaコード:私は2つのメソッドを持っ

protected void initializeToolbar(){ 
    myToolbar = (Toolbar) findViewById(R.id.my_toolbar); 
    menu = myToolbar.getMenu(); 
    resetToolbarMenu(); 
    myToolbar.setOnMenuItemClickListener(this); 
} 

private void resetToolbarMenu(){ 
    menu.clear(); 
    getMenuInflater().inflate(R.menu.menu, menu); 
    if(loginPrefs.getBoolean("login", false)) { //loginPrefs is reference to a SharedPreference object 
     menu.removeItem(1); 
    } else { 
     menu.removeItem(2); 
     menu.removeItem(0); 
    } 
} 

理由は、私は一度だけ、ツールバーとリスナーを設定したいということですが、私は、メニューを毎回変更することができるようにしたいユーザーがログインします/ページを再読み込みせずに。

ログインに成功すると、resetToolbarMenu()メソッドが再び呼び出されます。

私はmenu.remove(0)は、UIを更新しませんが、私が最初にそれを膨張し、ツールバーからそれを得ることなく、私のメニューオブジェクトに到達するための別の方法を見つけることができなかった、と私はインフレが表示されているどのような項目を決定するものであると仮定したとし。基本的には、膨張させる前にUIを膨張または更新する前に、メニュー項目を削除する方法を見つけることができませんでした。私はこのような何かに私のJavaコードを変更し

ソリューション

protected void initializeToolbar(){ 
    myToolbar = (Toolbar) findViewById(R.id.my_toolbar); 
    setSupportActionBar(myToolbar); 
} 

@Override 
public boolean onCreateOptionsMenu(Menu menu) { 
    getMenuInflater().inflate(R.menu.menu, menu); 
    return super.onCreateOptionsMenu(menu); // Don't know if this is necessary or if returning true is prefered. 
} 

@Override 
public boolean onPrepareOptionsMenu(Menu menu) { 
    if(loginPrefs.getBoolean("login", false)) { 
     menu.getItem(0).setVisible(true); 
     menu.getItem(1).setVisible(false); 
     menu.getItem(2).setVisible(true); 
    } else { 
     menu.getItem(0).setVisible(false); 
     menu.getItem(1).setVisible(true); 
     menu.getItem(2).setVisible(false); 
    } 
    return true; 
} 

私はまた、ツールバー/メニューを更新するために、ログアウト/ログイン時にinvalidateOptionsMenu()を呼び出す必要がありました。ただし、onPrepareOptionsMenu()は、ツールバーに表示されない項目のメニューを開くたびに自動的に呼び出されます。

PS:OnCreateOptionsMenuおよびOnPrepareOptionsMenuは、忘れてしまったとしてsetSupportActionBar(myToolbar)を覚えていない限り使用されません。

答えて

1

onCreateOptionsMenuを上書きしてオプションメニューを作成できます。 2 xmlを作成し、ロジックに応じてどちらか1つを膨張させることができます。メニューの再描画を強制するには、invalidateOptionsMenuに電話をかけることができます。

例えば

@Override 
public boolean onCreateOptionsMenu(Menu menu) { 
    MenuInflater inflater = getMenuInflater(); 
    if (login) { 
     inflater.inflate(R.menu.login_menu, menu); 
    } else { 
     inflater.inflate(R.menu.logout_menu, menu); 
    } 
    return true; 
} 

と外側のフラグを変更し、

login = false; // or true 
invalidateOptionsMenu(); 
+0

私は2つのレイアウトを静的に定義するよりもダイナミックなものを探しています。私は既に新しいものを追加するためのアクティビティにいる場合、私は2つの代わりに4つの異なるxmlファイルになる追加項目を表示したくない。このOptionsMenuの事を確かにチェックするつもりだ。 – Chexxor

+0

ダイナミックメニューと同じ方法です。静的レイアウトを拡張するのではなく、menu.addを使用してonCreateOptionsMenuにメニューを作成する必要があります。そしてinvalidateOptionsMenuを使って再描画を強制してください – tompee

+0

Hmm。それはプログラム的にメニュー項目を定義するように私に強制するでしょうか? xmlメニューをオブジェクトとして読み込み、menu.remove(int)を使った後にそのオブジェクトを使って膨らませる方法はありませんか? – Chexxor

1

メニューの項目を変更するアクティビティでonPrepareOptionsMenuを無効にする必要があります。

ドキュメントから:

表示する画面の標準オプションメニューを準備します。これは、メニューが表示される直前に、呼び出されるたびに呼び出されます。この方法を使用すると、アイテムを有効にしたり無効にしたり、コンテンツを動的に変更したりすることができます。

+0

を強制的に再描画だから私はこの方法にアイテムを削除するための私のコードを移動すると、その後の項目が適切に毎回私が準備されますメニューを膨らませてみてください。または、このメソッドを強制的に実行するために、他の回答からinvalidateOptionsMenuメソッドを使用しますか?ドキュメントで混乱している人には例がありません。/ – Chexxor

+0

このメソッドは常に呼び出され、無効化する必要はありません。 invalidateを使用する場合、強制的にonCreateOptionsMenuを再度呼び出す必要があります。完全に異なるxmlのように別のものを膨らませたい場合は、invalidateOptionsMenuを使用して、onPrepareOptionsMenuでいくつかの項目を削除したい場合は、それを実行してください。 – bogdanN

+0

しかし、onPrepareOptionsMenuは、ツールバー/メニューで何かを押すたびに呼び出されました。ログイン時に更新するために、私はinvalidateOptionsMenuを使用しました。たぶん、createメソッドをもう一度呼び出さずにprepareメソッドを強制する方が良いかもしれませんが、今のところinvalidateは私にとってそれを行うようです。 – Chexxor

関連する問題