public class

MenuHostHelper

extends java.lang.Object

 java.lang.Object

↳androidx.core.view.MenuHostHelper

Gradle dependencies

compile group: 'androidx.core', name: 'core', version: '1.9.0-alpha04'

  • groupId: androidx.core
  • artifactId: core
  • version: 1.9.0-alpha04

Artifact androidx.core:core:1.9.0-alpha04 it located at Google repository (https://maven.google.com/)

Androidx artifact mapping:

androidx.core:core com.android.support:support-compat

Overview

Helper class for implementing MenuHost.

Summary

Constructors
publicMenuHostHelper(java.lang.Runnable onInvalidateMenuCallback)

Construct a new MenuHostHelper.

Methods
public voidaddMenuProvider(MenuProvider provider)

Adds the given MenuProvider to the helper.

public voidaddMenuProvider(MenuProvider provider, LifecycleOwner owner)

Adds the given MenuProvider to the helper.

public voidaddMenuProvider(MenuProvider provider, LifecycleOwner owner, Lifecycle.State state)

Adds the given MenuProvider to the helper once the given LifecycleOwner reaches the given .

public voidonCreateMenu(Menu menu, MenuInflater menuInflater)

Inflates the entire , which will include all MenuItems provided by all current MenuProviders.

public voidonMenuClosed(Menu menu)

Called when the given , which was provided by one of the current MenuProviders, is closed.

public booleanonMenuItemSelected(MenuItem item)

Called whenever one of the menu items from any of the current MenuProviders is selected.

public voidonPrepareMenu(Menu menu)

Called right before the given , which was provided by one of the current MenuProviders, is to be shown.

public voidremoveMenuProvider(MenuProvider provider)

Removes the given MenuProvider from the helper.

from java.lang.Objectclone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait

Constructors

public MenuHostHelper(java.lang.Runnable onInvalidateMenuCallback)

Construct a new MenuHostHelper.

Parameters:

onInvalidateMenuCallback: callback to invalidate the menu whenever there may be a change to it

Methods

public void onPrepareMenu(Menu menu)

Called right before the given , which was provided by one of the current MenuProviders, is to be shown. This happens when the menu has been dynamically modified.

Parameters:

menu: the menu that is to be prepared

See also: MenuHostHelper.onCreateMenu(Menu, MenuInflater)

public void onCreateMenu(Menu menu, MenuInflater menuInflater)

Inflates the entire , which will include all MenuItems provided by all current MenuProviders.

Parameters:

menu: the menu to inflate all the menu items into
menuInflater: the inflater to be used to inflate the menu

public boolean onMenuItemSelected(MenuItem item)

Called whenever one of the menu items from any of the current MenuProviders is selected.

Parameters:

item: the menu item that was selected

Returns:

true to indicate the menu processing was consumed by one of the MenuProviders, false otherwise.

public void onMenuClosed(Menu menu)

Called when the given , which was provided by one of the current MenuProviders, is closed.

Parameters:

menu: the menu that has been closed

public void addMenuProvider(MenuProvider provider)

Adds the given MenuProvider to the helper.

Parameters:

provider: the MenuProvider to be added

public void addMenuProvider(MenuProvider provider, LifecycleOwner owner)

Adds the given MenuProvider to the helper. This MenuProvider will be removed once the given LifecycleOwner receives an event.

Parameters:

provider: the MenuProvider to be added
owner: the Lifecycle owner whose state will determine the removal of the provider

public void addMenuProvider(MenuProvider provider, LifecycleOwner owner, Lifecycle.State state)

Adds the given MenuProvider to the helper once the given LifecycleOwner reaches the given . This MenuProvider will be removed once the given LifecycleOwner goes down from the given or receives an event.

Parameters:

provider: the MenuProvider to be added
state: the Lifecycle.State to check for automated addition/removal
owner: the Lifecycle owner whose state will determine the removal of the provider

public void removeMenuProvider(MenuProvider provider)

Removes the given MenuProvider from the helper.

Parameters:

provider: the MenuProvider to be removed

Source

/*
 * Copyright 2021 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package androidx.core.view;

import android.annotation.SuppressLint;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;

import androidx.annotation.NonNull;
import androidx.lifecycle.Lifecycle;
import androidx.lifecycle.LifecycleEventObserver;
import androidx.lifecycle.LifecycleOwner;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArrayList;

/**
 * Helper class for implementing {@link MenuHost}.
 */
public class MenuHostHelper {

    private final Runnable mOnInvalidateMenuCallback;
    private final CopyOnWriteArrayList<MenuProvider> mMenuProviders = new CopyOnWriteArrayList<>();
    private final Map<MenuProvider, LifecycleContainer> mProviderToLifecycleContainers =
            new HashMap<>();

    /**
     * Construct a new MenuHostHelper.
     *
     * @param onInvalidateMenuCallback callback to invalidate the menu
     *                                 whenever there may be a change to it
     */
    public MenuHostHelper(@NonNull Runnable onInvalidateMenuCallback) {
        mOnInvalidateMenuCallback = onInvalidateMenuCallback;
    }

    /**
     * Called right before the given {@link Menu}, which was provided by one of the
     * current {@link MenuProvider}s, is to be shown. This happens when the menu has
     * been dynamically modified.
     *
     * @param menu the menu that is to be prepared
     * @see #onCreateMenu(Menu, MenuInflater)
     */
    public void onPrepareMenu(@NonNull Menu menu) {
        for (MenuProvider menuProvider : mMenuProviders) {
            menuProvider.onPrepareMenu(menu);
        }
    }

    /**
     * Inflates the entire {@link Menu}, which will include all
     * {@link MenuItem}s provided by all current {@link MenuProvider}s.
     *
     * @param menu         the menu to inflate all the menu items into
     * @param menuInflater the inflater to be used to inflate the menu
     */
    public void onCreateMenu(@NonNull Menu menu, @NonNull MenuInflater menuInflater) {
        for (MenuProvider menuProvider : mMenuProviders) {
            menuProvider.onCreateMenu(menu, menuInflater);
        }
    }

    /**
     * Called whenever one of the menu items from any of the current
     * {@link MenuProvider}s is selected.
     *
     * @param item the menu item that was selected
     * @return {@code true} to indicate the menu processing was consumed
     * by one of the {@link MenuProvider}s, {@code false} otherwise.
     */
    public boolean onMenuItemSelected(@NonNull MenuItem item) {
        for (MenuProvider menuProvider : mMenuProviders) {
            if (menuProvider.onMenuItemSelected(item)) {
                return true;
            }
        }
        return false;
    }

    /**
     * Called when the given {@link Menu}, which was provided by one of the
     * current {@link MenuProvider}s, is closed.
     *
     * @param menu the menu that has been closed
     */
    public void onMenuClosed(@NonNull Menu menu) {
        for (MenuProvider menuProvider : mMenuProviders) {
            menuProvider.onMenuClosed(menu);
        }
    }

    /**
     * Adds the given {@link MenuProvider} to the helper.
     *
     * @param provider the MenuProvider to be added
     */
    public void addMenuProvider(@NonNull MenuProvider provider) {
        mMenuProviders.add(provider);
        mOnInvalidateMenuCallback.run();
    }

    /**
     * Adds the given {@link MenuProvider} to the helper.
     *
     * This {@link MenuProvider} will be removed once the given {@link LifecycleOwner}
     * receives an {@link Lifecycle.Event.ON_DESTROY} event.
     *
     * @param provider the MenuProvider to be added
     * @param owner    the Lifecycle owner whose state will determine the removal of the provider
     */
    public void addMenuProvider(@NonNull MenuProvider provider, @NonNull LifecycleOwner owner) {
        addMenuProvider(provider);
        Lifecycle lifecycle = owner.getLifecycle();
        LifecycleContainer lifecycleContainer = mProviderToLifecycleContainers.remove(provider);
        if (lifecycleContainer != null) {
            lifecycleContainer.clearObservers();
        }
        LifecycleEventObserver observer = (source, event) -> {
            if (event == Lifecycle.Event.ON_DESTROY) {
                removeMenuProvider(provider);
            }
        };
        mProviderToLifecycleContainers.put(provider, new LifecycleContainer(lifecycle, observer));
    }

    /**
     * Adds the given {@link MenuProvider} to the helper once the given
     * {@link LifecycleOwner} reaches the given {@link Lifecycle.State}.
     *
     * This {@link MenuProvider} will be removed once the given {@link LifecycleOwner}
     * goes down from the given {@link Lifecycle.State} or receives an
     * {@link Lifecycle.Event.ON_DESTROY} event.
     *
     * @param provider the MenuProvider to be added
     * @param state    the Lifecycle.State to check for automated addition/removal
     * @param owner    the Lifecycle owner whose state will determine the removal of the provider
     */
    @SuppressLint("LambdaLast")
    public void addMenuProvider(@NonNull MenuProvider provider, @NonNull LifecycleOwner owner,
            @NonNull Lifecycle.State state) {
        Lifecycle lifecycle = owner.getLifecycle();
        LifecycleContainer lifecycleContainer = mProviderToLifecycleContainers.remove(provider);
        if (lifecycleContainer != null) {
            lifecycleContainer.clearObservers();
        }
        LifecycleEventObserver observer = (source, event) -> {
            if (event == Lifecycle.Event.upTo(state)) {
                addMenuProvider(provider);
            } else if (event == Lifecycle.Event.ON_DESTROY) {
                removeMenuProvider(provider);
            } else if (event == Lifecycle.Event.downFrom(state)) {
                mMenuProviders.remove(provider);
                mOnInvalidateMenuCallback.run();
            }
        };
        mProviderToLifecycleContainers.put(provider, new LifecycleContainer(lifecycle, observer));
    }

    /**
     * Removes the given {@link MenuProvider} from the helper.
     *
     * @param provider the MenuProvider to be removed
     */
    public void removeMenuProvider(@NonNull MenuProvider provider) {
        mMenuProviders.remove(provider);
        LifecycleContainer lifecycleContainer = mProviderToLifecycleContainers.remove(provider);
        if (lifecycleContainer != null) {
            lifecycleContainer.clearObservers();
        }
        mOnInvalidateMenuCallback.run();
    }

    private static class LifecycleContainer {
        final Lifecycle mLifecycle;
        private LifecycleEventObserver mObserver;

        LifecycleContainer(@NonNull Lifecycle lifecycle, @NonNull LifecycleEventObserver observer) {
            mLifecycle = lifecycle;
            mObserver = observer;
            mLifecycle.addObserver(observer);
        }

        void clearObservers() {
            mLifecycle.removeObserver(mObserver);
            mObserver = null;
        }
    }
}