java.lang.Object

↳Activity

androidx.core.app.ComponentActivity

androidx.activity.ComponentActivity

androidx.fragment.app.FragmentActivity

↳androidx.appcompat.app.AppCompatActivity

Subclasses:

SlicePermissionActivity, DeviceCredentialHandlerActivity

Gradle dependencies

compile group: 'androidx.appcompat', name: 'appcompat', version: '1.7.0'

  • groupId: androidx.appcompat
  • artifactId: appcompat
  • version: 1.7.0

Artifact androidx.appcompat:appcompat:1.7.0 it located at Google repository (https://maven.google.com/)

Androidx artifact mapping:

androidx.appcompat:appcompat com.android.support:appcompat-v7

Androidx class mapping:

androidx.appcompat.app.AppCompatActivity android.support.v7.app.AppCompatActivity

Overview

Base class for activities that wish to use some of the newer platform features on older Android devices. Some of these backported features include:

Note that every activity that extends this class has to be themed with or a theme that extends that theme.

Developer Guides

For information about how to use the action bar, including how to add action items, navigation modes and more, read the Action Bar API guide.

Summary

Constructors
publicAppCompatActivity()

Default constructor for AppCompatActivity.

publicAppCompatActivity(int contentLayoutId)

Alternate constructor that can be used to provide a default layout that will be inflated as part of super.onCreate(savedInstanceState).

Methods
public voidaddContentView(View view, ViewGroup.LayoutParams params)

protected voidattachBaseContext(Context newBase)

public voidcloseOptionsMenu()

public booleandispatchKeyEvent(KeyEvent event)

public ViewfindViewById(int id)

public AppCompatDelegategetDelegate()

public ActionBarDrawerToggle.DelegategetDrawerToggleDelegate()

public MenuInflatergetMenuInflater()

public ResourcesgetResources()

public ActionBargetSupportActionBar()

Support library version of .

public IntentgetSupportParentActivityIntent()

Obtain an that will launch an explicit target activity specified by sourceActivity's NavUtils.PARENT_ACTIVITY <meta-data> element in the application's manifest.

public voidinvalidateOptionsMenu()

public voidonConfigurationChanged(Configuration newConfig)

Dispatches this call to all listeners added via ComponentActivity.addOnConfigurationChangedListener(Consumer).

public voidonContentChanged()

public voidonCreateSupportNavigateUpTaskStack(TaskStackBuilder builder)

Support version of AppCompatActivity.

protected voidonDestroy()

Destroy all fragments.

public booleanonKeyDown(int keyCode, KeyEvent event)

protected voidonLocalesChanged(LocaleListCompat locales)

Called when the locales have been changed.

public final booleanonMenuItemSelected(int featureId, android.view.MenuItem item)

public booleanonMenuOpened(int featureId, Menu menu)

protected voidonNightModeChanged(int mode)

Called when the night mode has changed.

public voidonPanelClosed(int featureId, Menu menu)

protected voidonPostCreate(Bundle savedInstanceState)

protected voidonPostResume()

Dispatch onResume() to fragments.

public voidonPrepareSupportNavigateUpTaskStack(TaskStackBuilder builder)

Support version of AppCompatActivity.

protected voidonStart()

Dispatch onStart() to all fragments.

protected voidonStop()

Dispatch onStop() to all fragments.

public voidonSupportActionModeFinished(ActionMode mode)

Notifies the activity that a support action mode has finished.

public voidonSupportActionModeStarted(ActionMode mode)

Notifies the Activity that a support action mode has been started.

public voidonSupportContentChanged()

public booleanonSupportNavigateUp()

This method is called whenever the user chooses to navigate Up within your application's activity hierarchy from the action bar.

protected voidonTitleChanged(java.lang.CharSequence title, int color)

public ActionModeonWindowStartingSupportActionMode(ActionMode.Callback callback)

Called when a support action mode is being started for this window.

public voidopenOptionsMenu()

public voidsetContentView(int layoutResID)

public voidsetContentView(View view)

public voidsetContentView(View view, ViewGroup.LayoutParams params)

public voidsetSupportActionBar(Toolbar toolbar)

Set a to act as the ActionBar for this Activity window.

public voidsetSupportProgress(int progress)

public voidsetSupportProgressBarIndeterminate(boolean indeterminate)

public voidsetSupportProgressBarIndeterminateVisibility(boolean visible)

public voidsetSupportProgressBarVisibility(boolean visible)

public voidsetTheme(int resId)

public ActionModestartSupportActionMode(ActionMode.Callback callback)

Start an action mode.

public voidsupportInvalidateOptionsMenu()

Support library version of .

public voidsupportNavigateUpTo(Intent upIntent)

Navigate from sourceActivity to the activity specified by upIntent, finishing sourceActivity in the process.

public booleansupportRequestWindowFeature(int featureId)

Enable extended support library window features.

public booleansupportShouldUpRecreateTask(Intent targetIntent)

Returns true if sourceActivity should recreate the task when navigating 'up' by using targetIntent.

from FragmentActivitydump, getSupportFragmentManager, getSupportLoaderManager, onActivityResult, onAttachFragment, onCreate, onCreateView, onCreateView, onMenuItemSelected, onPause, onRequestPermissionsResult, onResume, onResumeFragments, onStateNotSaved, setEnterSharedElementCallback, setExitSharedElementCallback, startActivityFromFragment, startActivityFromFragment, startIntentSenderFromFragment, supportFinishAfterTransition, supportPostponeEnterTransition, supportStartPostponedEnterTransition, validateRequestPermissionsRequestCode
from ComponentActivityaddMenuProvider, addMenuProvider, addMenuProvider, addOnConfigurationChangedListener, addOnContextAvailableListener, addOnMultiWindowModeChangedListener, addOnNewIntentListener, addOnPictureInPictureModeChangedListener, addOnTrimMemoryListener, getActivityResultRegistry, getDefaultViewModelCreationExtras, getDefaultViewModelProviderFactory, getLastCustomNonConfigurationInstance, getLifecycle, getOnBackPressedDispatcher, getSavedStateRegistry, getViewModelStore, invalidateMenu, onBackPressed, onCreateOptionsMenu, onMultiWindowModeChanged, onMultiWindowModeChanged, onNewIntent, onOptionsItemSelected, onPictureInPictureModeChanged, onPictureInPictureModeChanged, onPrepareOptionsMenu, onRetainCustomNonConfigurationInstance, onRetainNonConfigurationInstance, onSaveInstanceState, onTrimMemory, peekAvailableContext, registerForActivityResult, registerForActivityResult, removeMenuProvider, removeOnConfigurationChangedListener, removeOnContextAvailableListener, removeOnMultiWindowModeChangedListener, removeOnNewIntentListener, removeOnPictureInPictureModeChangedListener, removeOnTrimMemoryListener, reportFullyDrawn, startActivityForResult, startActivityForResult, startIntentSenderForResult, startIntentSenderForResult
from ComponentActivitydispatchKeyShortcutEvent, getExtraData, putExtraData, shouldDumpInternalState, superDispatchKeyEvent
from java.lang.Objectclone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait

Constructors

public AppCompatActivity()

Default constructor for AppCompatActivity. All Activities must have a default constructor for API 27 and lower devices or when using the default .

public AppCompatActivity(int contentLayoutId)

Alternate constructor that can be used to provide a default layout that will be inflated as part of super.onCreate(savedInstanceState).

This should generally be called from your constructor that takes no parameters, as is required for API 27 and lower or when using the default .

See also: AppCompatActivity.AppCompatActivity()

Methods

protected void attachBaseContext(Context newBase)

public void setTheme(int resId)

protected void onPostCreate(Bundle savedInstanceState)

public ActionBar getSupportActionBar()

Support library version of .

Retrieve a reference to this activity's ActionBar.

Returns:

The Activity's ActionBar, or null if it does not have one.

public void setSupportActionBar(Toolbar toolbar)

Set a to act as the ActionBar for this Activity window.

When set to a non-null value the AppCompatActivity method will return an ActionBar object that can be used to control the given toolbar as if it were a traditional window decor action bar. The toolbar's menu will be populated with the Activity's options menu and the navigation button will be wired through the standard menu select action.

In order to use a Toolbar within the Activity's window content the application must not request the window feature .

Parameters:

toolbar: Toolbar to set as the Activity's action bar, or null to clear it

public MenuInflater getMenuInflater()

public void setContentView(int layoutResID)

public void setContentView(View view)

public void setContentView(View view, ViewGroup.LayoutParams params)

public void addContentView(View view, ViewGroup.LayoutParams params)

public void onConfigurationChanged(Configuration newConfig)

Dispatches this call to all listeners added via ComponentActivity.addOnConfigurationChangedListener(Consumer).

protected void onPostResume()

Dispatch onResume() to fragments.

protected void onStart()

Dispatch onStart() to all fragments.

protected void onStop()

Dispatch onStop() to all fragments.

public View findViewById(int id)

public final boolean onMenuItemSelected(int featureId, android.view.MenuItem item)

protected void onDestroy()

Destroy all fragments.

protected void onTitleChanged(java.lang.CharSequence title, int color)

public boolean supportRequestWindowFeature(int featureId)

Enable extended support library window features.

This is a convenience for calling .

Parameters:

featureId: The desired feature as defined in or WindowCompat.

Returns:

Returns true if the requested feature is supported and now enabled.

See also:

public void supportInvalidateOptionsMenu()

Deprecated: Call directly.

Support library version of .

Invalidate the activity's options menu. This will cause relevant presentations of the menu to fully update via calls to onCreateOptionsMenu and onPrepareOptionsMenu the next time the menu is requested.

public void invalidateOptionsMenu()

public void onSupportActionModeStarted(ActionMode mode)

Notifies the Activity that a support action mode has been started. Activity subclasses overriding this method should call the superclass implementation.

Parameters:

mode: The new action mode.

public void onSupportActionModeFinished(ActionMode mode)

Notifies the activity that a support action mode has finished. Activity subclasses overriding this method should call the superclass implementation.

Parameters:

mode: The action mode that just finished.

public ActionMode onWindowStartingSupportActionMode(ActionMode.Callback callback)

Called when a support action mode is being started for this window. Gives the callback an opportunity to handle the action mode in its own unique and beautiful way. If this method returns null the system can choose a way to present the mode or choose not to start the mode at all.

Parameters:

callback: Callback to control the lifecycle of this action mode

Returns:

The ActionMode that was started, or null if the system should present it

public ActionMode startSupportActionMode(ActionMode.Callback callback)

Start an action mode.

Parameters:

callback: Callback that will manage lifecycle events for this context mode

Returns:

The ContextMode that was started, or null if it was canceled

public void setSupportProgressBarVisibility(boolean visible)

Deprecated: Progress bars are no longer provided in AppCompat.

public void setSupportProgressBarIndeterminateVisibility(boolean visible)

Deprecated: Progress bars are no longer provided in AppCompat.

public void setSupportProgressBarIndeterminate(boolean indeterminate)

Deprecated: Progress bars are no longer provided in AppCompat.

public void setSupportProgress(int progress)

Deprecated: Progress bars are no longer provided in AppCompat.

public void onCreateSupportNavigateUpTaskStack(TaskStackBuilder builder)

Support version of AppCompatActivity. This method will be called on all platform versions. Define the synthetic task stack that will be generated during Up navigation from a different task.

The default implementation of this method adds the parent chain of this activity as specified in the manifest to the supplied TaskStackBuilder. Applications may choose to override this method to construct the desired task stack in a different way.

This method will be invoked by the default implementation of AppCompatActivity if AppCompatActivity returns true when supplied with the intent returned by AppCompatActivity.

Applications that wish to supply extra Intent parameters to the parent stack defined by the manifest should override AppCompatActivity.onPrepareSupportNavigateUpTaskStack(TaskStackBuilder).

Parameters:

builder: An empty TaskStackBuilder - the application should add intents representing the desired task stack

public void onPrepareSupportNavigateUpTaskStack(TaskStackBuilder builder)

Support version of AppCompatActivity. This method will be called on all platform versions. Prepare the synthetic task stack that will be generated during Up navigation from a different task.

This method receives the TaskStackBuilder with the constructed series of Intents as generated by AppCompatActivity.onCreateSupportNavigateUpTaskStack(TaskStackBuilder). If any extra data should be added to these intents before launching the new task, the application should override this method and add that data here.

Parameters:

builder: A TaskStackBuilder that has been populated with Intents by onCreateNavigateUpTaskStack.

public boolean onSupportNavigateUp()

This method is called whenever the user chooses to navigate Up within your application's activity hierarchy from the action bar.

If a parent was specified in the manifest for this activity or an activity-alias to it, default Up navigation will be handled automatically. See AppCompatActivity.getSupportParentActivityIntent() for how to specify the parent. If any activity along the parent chain requires extra Intent arguments, the Activity subclass should override the method AppCompatActivity.onPrepareSupportNavigateUpTaskStack(TaskStackBuilder) to supply those arguments.

See Tasks and Back Stack from the developer guide and Navigation from the design guide for more information about navigating within your app.

See the TaskStackBuilder class and the Activity methods AppCompatActivity.getSupportParentActivityIntent(), AppCompatActivity, and AppCompatActivity for help implementing custom Up navigation.

Returns:

true if Up navigation completed successfully and this Activity was finished, false otherwise.

public Intent getSupportParentActivityIntent()

Obtain an that will launch an explicit target activity specified by sourceActivity's NavUtils.PARENT_ACTIVITY <meta-data> element in the application's manifest. If the device is running Jellybean or newer, the android:parentActivityName attribute will be preferred if it is present.

Returns:

a new Intent targeting the defined parent activity of sourceActivity

public boolean supportShouldUpRecreateTask(Intent targetIntent)

Returns true if sourceActivity should recreate the task when navigating 'up' by using targetIntent.

If this method returns false the app can trivially call AppCompatActivity using the same parameters to correctly perform up navigation. If this method returns false, the app should synthesize a new task stack by using TaskStackBuilder or another similar mechanism to perform up navigation.

Parameters:

targetIntent: An intent representing the target destination for up navigation

Returns:

true if navigating up should recreate a new task stack, false if the same task should be used for the destination

public void supportNavigateUpTo(Intent upIntent)

Navigate from sourceActivity to the activity specified by upIntent, finishing sourceActivity in the process. upIntent will have the flag set by this method, along with any others required for proper up navigation as outlined in the Android Design Guide.

This method should be used when performing up navigation from within the same task as the destination. If up navigation should cross tasks in some cases, see AppCompatActivity.

Parameters:

upIntent: An intent representing the target destination for up navigation

public void onContentChanged()

public void onSupportContentChanged()

Deprecated: Use AppCompatActivity.onContentChanged() instead.

public ActionBarDrawerToggle.Delegate getDrawerToggleDelegate()

public boolean onMenuOpened(int featureId, Menu menu)

Please note: AppCompat uses its own feature id for the action bar: FEATURE_SUPPORT_ACTION_BAR.

public void onPanelClosed(int featureId, Menu menu)

Please note: AppCompat uses its own feature id for the action bar: FEATURE_SUPPORT_ACTION_BAR.

public AppCompatDelegate getDelegate()

Returns:

The AppCompatDelegate being used by this Activity.

public boolean dispatchKeyEvent(KeyEvent event)

public Resources getResources()

public boolean onKeyDown(int keyCode, KeyEvent event)

public void openOptionsMenu()

public void closeOptionsMenu()

protected void onNightModeChanged(int mode)

Called when the night mode has changed. See AppCompatDelegate.applyDayNight() for more information.

Parameters:

mode: the night mode which has been applied

protected void onLocalesChanged(LocaleListCompat locales)

Called when the locales have been changed. See AppCompatDelegate.applyAppLocales() for more information.

Parameters:

locales: the localeListCompat which has been applied

Source

/*
 * Copyright (C) 2015 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.appcompat.app;

import android.content.Context;
import android.content.Intent;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.os.Build;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;

import androidx.activity.ViewTreeOnBackPressedDispatcherOwner;
import androidx.activity.contextaware.OnContextAvailableListener;
import androidx.annotation.CallSuper;
import androidx.annotation.ContentView;
import androidx.annotation.IdRes;
import androidx.annotation.LayoutRes;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.StyleRes;
import androidx.appcompat.app.AppCompatDelegate.NightMode;
import androidx.appcompat.view.ActionMode;
import androidx.appcompat.widget.Toolbar;
import androidx.appcompat.widget.VectorEnabledTintResources;
import androidx.core.app.ActivityCompat;
import androidx.core.app.NavUtils;
import androidx.core.app.TaskStackBuilder;
import androidx.core.os.LocaleListCompat;
import androidx.fragment.app.FragmentActivity;
import androidx.lifecycle.ViewTreeLifecycleOwner;
import androidx.lifecycle.ViewTreeViewModelStoreOwner;
import androidx.savedstate.SavedStateRegistry;
import androidx.savedstate.ViewTreeSavedStateRegistryOwner;

/**
 * Base class for activities that wish to use some of the newer platform features on older
 * Android devices. Some of these backported features include:
 *
 * <ul>
 *     <li>Using the action bar, including action items, navigation modes and more with
 *     the {@link #setSupportActionBar(Toolbar)} API.</li>
 *     <li>Built-in switching between light and dark themes by using the
 *     {@link androidx.appcompat.R.style#Theme_AppCompat_DayNight Theme.AppCompat.DayNight} theme
 *     and {@link AppCompatDelegate#setDefaultNightMode(int)} API.</li>
 *     <li>Integration with <code>DrawerLayout</code> by using the
 *     {@link #getDrawerToggleDelegate()} API.</li>
 * </ul>
 *
 * <p>Note that every activity that extends this class has to be themed with
 * {@link androidx.appcompat.R.style#Theme_AppCompat Theme.AppCompat} or a theme that extends
 * that theme.</p>
 *
 * <div class="special reference">
 * <h3>Developer Guides</h3>
 *
 * <p>For information about how to use the action bar, including how to add action items, navigation
 * modes and more, read the <a href="{@docRoot}guide/topics/ui/actionbar.html">Action
 * Bar</a> API guide.</p>
 * </div>
 */
public class AppCompatActivity extends FragmentActivity implements AppCompatCallback,
        TaskStackBuilder.SupportParentable, ActionBarDrawerToggle.DelegateProvider {

    private static final String DELEGATE_TAG = "androidx:appcompat";

    private AppCompatDelegate mDelegate;
    private Resources mResources;

    /**
     * Default constructor for AppCompatActivity. All Activities must have a default constructor
     * for API 27 and lower devices or when using the default
     * {@link android.app.AppComponentFactory}.
     */
    public AppCompatActivity() {
        super();
        initDelegate();
    }

    /**
     * Alternate constructor that can be used to provide a default layout
     * that will be inflated as part of <code>super.onCreate(savedInstanceState)</code>.
     *
     * <p>This should generally be called from your constructor that takes no parameters,
     * as is required for API 27 and lower or when using the default
     * {@link android.app.AppComponentFactory}.
     *
     * @see #AppCompatActivity()
     */
    @ContentView
    public AppCompatActivity(@LayoutRes int contentLayoutId) {
        super(contentLayoutId);
        initDelegate();
    }

    private void initDelegate() {
        // TODO: Directly connect AppCompatDelegate to SavedStateRegistry
        getSavedStateRegistry().registerSavedStateProvider(DELEGATE_TAG,
                new SavedStateRegistry.SavedStateProvider() {
                    @NonNull
                    @Override
                    public Bundle saveState() {
                        Bundle outState = new Bundle();
                        getDelegate().onSaveInstanceState(outState);
                        return outState;
                    }
                });
        addOnContextAvailableListener(new OnContextAvailableListener() {
            @Override
            public void onContextAvailable(@NonNull Context context) {
                final AppCompatDelegate delegate = getDelegate();
                delegate.installViewFactory();
                delegate.onCreate(getSavedStateRegistry()
                        .consumeRestoredStateForKey(DELEGATE_TAG));
            }
        });
    }

    @Override
    protected void attachBaseContext(Context newBase) {
        super.attachBaseContext(getDelegate().attachBaseContext2(newBase));
    }

    @Override
    public void setTheme(@StyleRes final int resId) {
        super.setTheme(resId);
        getDelegate().setTheme(resId);
    }

    @Override
    protected void onPostCreate(@Nullable Bundle savedInstanceState) {
        super.onPostCreate(savedInstanceState);
        getDelegate().onPostCreate(savedInstanceState);
    }

    /**
     * Support library version of {@link android.app.Activity#getActionBar}.
     *
     * <p>Retrieve a reference to this activity's ActionBar.
     *
     * @return The Activity's ActionBar, or null if it does not have one.
     */
    @Nullable
    public ActionBar getSupportActionBar() {
        return getDelegate().getSupportActionBar();
    }

    /**
     * Set a {@link android.widget.Toolbar Toolbar} to act as the
     * {@link androidx.appcompat.app.ActionBar} for this Activity window.
     *
     * <p>When set to a non-null value the {@link #getActionBar()} method will return
     * an {@link androidx.appcompat.app.ActionBar} object that can be used to control the given
     * toolbar as if it were a traditional window decor action bar. The toolbar's menu will be
     * populated with the Activity's options menu and the navigation button will be wired through
     * the standard {@link android.R.id#home home} menu select action.</p>
     *
     * <p>In order to use a Toolbar within the Activity's window content the application
     * must not request the window feature
     * {@link android.view.Window#FEATURE_ACTION_BAR FEATURE_SUPPORT_ACTION_BAR}.</p>
     *
     * @param toolbar Toolbar to set as the Activity's action bar, or {@code null} to clear it
     */
    public void setSupportActionBar(@Nullable Toolbar toolbar) {
        getDelegate().setSupportActionBar(toolbar);
    }

    @NonNull
    @Override
    public MenuInflater getMenuInflater() {
        return getDelegate().getMenuInflater();
    }

    @Override
    public void setContentView(@LayoutRes int layoutResID) {
        initViewTreeOwners();
        getDelegate().setContentView(layoutResID);
    }

    @Override
    public void setContentView(View view) {
        initViewTreeOwners();
        getDelegate().setContentView(view);
    }

    @Override
    public void setContentView(View view, ViewGroup.LayoutParams params) {
        initViewTreeOwners();
        getDelegate().setContentView(view, params);
    }

    @Override
    public void addContentView(View view, ViewGroup.LayoutParams params) {
        initViewTreeOwners();
        getDelegate().addContentView(view, params);
    }

    private void initViewTreeOwners() {
        // Set the view tree owners before setting the content view so that the inflation process
        // and attach listeners will see them already present
        ViewTreeLifecycleOwner.set(getWindow().getDecorView(), this);
        ViewTreeViewModelStoreOwner.set(getWindow().getDecorView(), this);
        ViewTreeSavedStateRegistryOwner.set(getWindow().getDecorView(), this);
        ViewTreeOnBackPressedDispatcherOwner.set(getWindow().getDecorView(), this);
    }

    @Override
    public void onConfigurationChanged(@NonNull Configuration newConfig) {
        super.onConfigurationChanged(newConfig);

        // The delegate may modify the real resources object or the config param to implement its
        // desired configuration overrides. Let it do it's thing and then use the resulting state.
        getDelegate().onConfigurationChanged(newConfig);

        // Manually propagate configuration changes to our unmanaged resources object.
        if (mResources != null) {
            final Configuration currConfig = super.getResources().getConfiguration();
            final DisplayMetrics currMetrics = super.getResources().getDisplayMetrics();
            mResources.updateConfiguration(currConfig, currMetrics);
        }
    }

    @Override
    protected void onPostResume() {
        super.onPostResume();
        getDelegate().onPostResume();
    }

    @Override
    protected void onStart() {
        super.onStart();
        getDelegate().onStart();
    }

    @Override
    protected void onStop() {
        super.onStop();
        getDelegate().onStop();
    }

    @SuppressWarnings("TypeParameterUnusedInFormals")
    @Override
    public <T extends View> T findViewById(@IdRes int id) {
        return getDelegate().findViewById(id);
    }

    @Override
    public final boolean onMenuItemSelected(int featureId, @NonNull android.view.MenuItem item) {
        if (super.onMenuItemSelected(featureId, item)) {
            return true;
        }

        final ActionBar ab = getSupportActionBar();
        if (item.getItemId() == android.R.id.home && ab != null &&
                (ab.getDisplayOptions() & ActionBar.DISPLAY_HOME_AS_UP) != 0) {
            return onSupportNavigateUp();
        }
        return false;
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        getDelegate().onDestroy();
    }

    @Override
    protected void onTitleChanged(CharSequence title, int color) {
        super.onTitleChanged(title, color);
        getDelegate().setTitle(title);
    }

    /**
     * Enable extended support library window features.
     * <p>
     * This is a convenience for calling
     * {@link android.view.Window#requestFeature getWindow().requestFeature()}.
     * </p>
     *
     * @param featureId The desired feature as defined in
     * {@link android.view.Window} or {@link androidx.core.view.WindowCompat}.
     * @return Returns true if the requested feature is supported and now enabled.
     *
     * @see android.app.Activity#requestWindowFeature
     * @see android.view.Window#requestFeature
     */
    public boolean supportRequestWindowFeature(int featureId) {
        return getDelegate().requestWindowFeature(featureId);
    }

    @SuppressWarnings("deprecation")
    @Override
    public void supportInvalidateOptionsMenu() {
        getDelegate().invalidateOptionsMenu();
    }

    @Override
    public void invalidateOptionsMenu() {
        getDelegate().invalidateOptionsMenu();
    }

    /**
     * Notifies the Activity that a support action mode has been started.
     * Activity subclasses overriding this method should call the superclass implementation.
     *
     * @param mode The new action mode.
     */
    @Override
    @CallSuper
    public void onSupportActionModeStarted(@NonNull ActionMode mode) {
    }

    /**
     * Notifies the activity that a support action mode has finished.
     * Activity subclasses overriding this method should call the superclass implementation.
     *
     * @param mode The action mode that just finished.
     */
    @Override
    @CallSuper
    public void onSupportActionModeFinished(@NonNull ActionMode mode) {
    }

    /**
     * Called when a support action mode is being started for this window. Gives the
     * callback an opportunity to handle the action mode in its own unique and
     * beautiful way. If this method returns null the system can choose a way
     * to present the mode or choose not to start the mode at all.
     *
     * @param callback Callback to control the lifecycle of this action mode
     * @return The ActionMode that was started, or null if the system should present it
     */
    @Nullable
    @Override
    public ActionMode onWindowStartingSupportActionMode(@NonNull ActionMode.Callback callback) {
        return null;
    }

    /**
     * Start an action mode.
     *
     * @param callback Callback that will manage lifecycle events for this context mode
     * @return The ContextMode that was started, or null if it was canceled
     */
    @Nullable
    public ActionMode startSupportActionMode(@NonNull ActionMode.Callback callback) {
        return getDelegate().startSupportActionMode(callback);
    }

    /**
     * @deprecated Progress bars are no longer provided in AppCompat.
     */
    @Deprecated
    public void setSupportProgressBarVisibility(boolean visible) {
    }

    /**
     * @deprecated Progress bars are no longer provided in AppCompat.
     */
    @Deprecated
    public void setSupportProgressBarIndeterminateVisibility(boolean visible) {
    }

    /**
     * @deprecated Progress bars are no longer provided in AppCompat.
     */
    @Deprecated
    public void setSupportProgressBarIndeterminate(boolean indeterminate) {
    }

    /**
     * @deprecated Progress bars are no longer provided in AppCompat.
     */
    @Deprecated
    public void setSupportProgress(int progress) {
    }

    /**
     * Support version of {@link #onCreateNavigateUpTaskStack(android.app.TaskStackBuilder)}.
     * This method will be called on all platform versions.
     *
     * Define the synthetic task stack that will be generated during Up navigation from
     * a different task.
     *
     * <p>The default implementation of this method adds the parent chain of this activity
     * as specified in the manifest to the supplied {@link androidx.core.app.TaskStackBuilder}. Applications
     * may choose to override this method to construct the desired task stack in a different
     * way.</p>
     *
     * <p>This method will be invoked by the default implementation of {@link #onNavigateUp()}
     * if {@link #shouldUpRecreateTask(android.content.Intent)} returns true when supplied with the intent
     * returned by {@link #getParentActivityIntent()}.</p>
     *
     * <p>Applications that wish to supply extra Intent parameters to the parent stack defined
     * by the manifest should override
     * {@link #onPrepareSupportNavigateUpTaskStack(androidx.core.app.TaskStackBuilder)}.</p>
     *
     * @param builder An empty TaskStackBuilder - the application should add intents representing
     *                the desired task stack
     */
    public void onCreateSupportNavigateUpTaskStack(@NonNull TaskStackBuilder builder) {
        builder.addParentStack(this);
    }

    /**
     * Support version of {@link #onPrepareNavigateUpTaskStack(android.app.TaskStackBuilder)}.
     * This method will be called on all platform versions.
     *
     * Prepare the synthetic task stack that will be generated during Up navigation
     * from a different task.
     *
     * <p>This method receives the {@link androidx.core.app.TaskStackBuilder} with the constructed series of
     * Intents as generated by {@link #onCreateSupportNavigateUpTaskStack(androidx.core.app.TaskStackBuilder)}.
     * If any extra data should be added to these intents before launching the new task,
     * the application should override this method and add that data here.</p>
     *
     * @param builder A TaskStackBuilder that has been populated with Intents by
     *                onCreateNavigateUpTaskStack.
     */
    public void onPrepareSupportNavigateUpTaskStack(@NonNull TaskStackBuilder builder) {
    }

    /**
     * This method is called whenever the user chooses to navigate Up within your application's
     * activity hierarchy from the action bar.
     *
     * <p>If a parent was specified in the manifest for this activity or an activity-alias to it,
     * default Up navigation will be handled automatically. See
     * {@link #getSupportParentActivityIntent()} for how to specify the parent. If any activity
     * along the parent chain requires extra Intent arguments, the Activity subclass
     * should override the method {@link #onPrepareSupportNavigateUpTaskStack(androidx.core.app.TaskStackBuilder)}
     * to supply those arguments.</p>
     *
     * <p>See <a href="{@docRoot}guide/topics/fundamentals/tasks-and-back-stack.html">Tasks and
     * Back Stack</a> from the developer guide and
     * <a href="{@docRoot}design/patterns/navigation.html">Navigation</a> from the design guide
     * for more information about navigating within your app.</p>
     *
     * <p>See the {@link androidx.core.app.TaskStackBuilder} class and the Activity methods
     * {@link #getSupportParentActivityIntent()}, {@link #supportShouldUpRecreateTask(android.content.Intent)}, and
     * {@link #supportNavigateUpTo(android.content.Intent)} for help implementing custom Up navigation.</p>
     *
     * @return true if Up navigation completed successfully and this Activity was finished,
     *         false otherwise.
     */
    public boolean onSupportNavigateUp() {
        Intent upIntent = getSupportParentActivityIntent();

        if (upIntent != null) {
            if (supportShouldUpRecreateTask(upIntent)) {
                TaskStackBuilder b = TaskStackBuilder.create(this);
                onCreateSupportNavigateUpTaskStack(b);
                onPrepareSupportNavigateUpTaskStack(b);
                b.startActivities();

                try {
                    ActivityCompat.finishAffinity(this);
                } catch (IllegalStateException e) {
                    // This can only happen on 4.1+, when we don't have a parent or a result set.
                    // In that case we should just finish().
                    finish();
                }
            } else {
                // This activity is part of the application's task, so simply
                // navigate up to the hierarchical parent activity.
                supportNavigateUpTo(upIntent);
            }
            return true;
        }
        return false;
    }

    /**
     * Obtain an {@link android.content.Intent} that will launch an explicit target activity
     * specified by sourceActivity's {@link androidx.core.app.NavUtils#PARENT_ACTIVITY} &lt;meta-data&gt;
     * element in the application's manifest. If the device is running
     * Jellybean or newer, the android:parentActivityName attribute will be preferred
     * if it is present.
     *
     * @return a new Intent targeting the defined parent activity of sourceActivity
     */
    @Nullable
    @Override
    public Intent getSupportParentActivityIntent() {
        return NavUtils.getParentActivityIntent(this);
    }

    /**
     * Returns true if sourceActivity should recreate the task when navigating 'up'
     * by using targetIntent.
     *
     * <p>If this method returns false the app can trivially call
     * {@link #supportNavigateUpTo(android.content.Intent)} using the same parameters to correctly perform
     * up navigation. If this method returns false, the app should synthesize a new task stack
     * by using {@link androidx.core.app.TaskStackBuilder} or another similar mechanism to perform up navigation.</p>
     *
     * @param targetIntent An intent representing the target destination for up navigation
     * @return true if navigating up should recreate a new task stack, false if the same task
     *         should be used for the destination
     */
    public boolean supportShouldUpRecreateTask(@NonNull Intent targetIntent) {
        return NavUtils.shouldUpRecreateTask(this, targetIntent);
    }

    /**
     * Navigate from sourceActivity to the activity specified by upIntent, finishing sourceActivity
     * in the process. upIntent will have the flag {@link android.content.Intent#FLAG_ACTIVITY_CLEAR_TOP} set
     * by this method, along with any others required for proper up navigation as outlined
     * in the Android Design Guide.
     *
     * <p>This method should be used when performing up navigation from within the same task
     * as the destination. If up navigation should cross tasks in some cases, see
     * {@link #supportShouldUpRecreateTask(android.content.Intent)}.</p>
     *
     * @param upIntent An intent representing the target destination for up navigation
     */
    public void supportNavigateUpTo(@NonNull Intent upIntent) {
        NavUtils.navigateUpTo(this, upIntent);
    }

    @SuppressWarnings("deprecation")
    @Override
    public void onContentChanged() {
        // Call onSupportContentChanged() for legacy reasons
        onSupportContentChanged();
    }

    /**
     * @deprecated Use {@link #onContentChanged()} instead.
     */
    @Deprecated
    public void onSupportContentChanged() {
    }

    @Nullable
    @Override
    public ActionBarDrawerToggle.Delegate getDrawerToggleDelegate() {
        return getDelegate().getDrawerToggleDelegate();
    }

    /**
     * {@inheritDoc}
     *
     * <p>Please note: AppCompat uses its own feature id for the action bar:
     * {@link AppCompatDelegate#FEATURE_SUPPORT_ACTION_BAR FEATURE_SUPPORT_ACTION_BAR}.</p>
     */
    @Override
    public boolean onMenuOpened(int featureId, Menu menu) {
        return super.onMenuOpened(featureId, menu);
    }

    /**
     * {@inheritDoc}
     *
     * <p>Please note: AppCompat uses its own feature id for the action bar:
     * {@link AppCompatDelegate#FEATURE_SUPPORT_ACTION_BAR FEATURE_SUPPORT_ACTION_BAR}.</p>
     */
    @Override
    public void onPanelClosed(int featureId, @NonNull Menu menu) {
        super.onPanelClosed(featureId, menu);
    }

    /**
     * @return The {@link AppCompatDelegate} being used by this Activity.
     */
    @NonNull
    public AppCompatDelegate getDelegate() {
        if (mDelegate == null) {
            mDelegate = AppCompatDelegate.create(this, this);
        }
        return mDelegate;
    }

    @Override
    public boolean dispatchKeyEvent(KeyEvent event) {
        // Let support action bars open menus in response to the menu key prioritized over
        // the window handling it
        final int keyCode = event.getKeyCode();
        final ActionBar actionBar = getSupportActionBar();
        if (keyCode == KeyEvent.KEYCODE_MENU
                && actionBar != null && actionBar.onMenuKeyEvent(event)) {
            return true;
        }
        return super.dispatchKeyEvent(event);
    }

    @Override
    public Resources getResources() {
        if (mResources == null && VectorEnabledTintResources.shouldBeUsed()) {
            mResources = new VectorEnabledTintResources(this, super.getResources());
        }
        return mResources == null ? super.getResources() : mResources;
    }

    /**
     * KeyEvents with non-default modifiers are not dispatched to menu's performShortcut in API 25
     * or lower. Here, we check if the keypress corresponds to a menuitem's shortcut combination
     * and perform the corresponding action.
     */
    private boolean performMenuItemShortcut(KeyEvent event) {
        if (!(Build.VERSION.SDK_INT >= 26) && !event.isCtrlPressed()
                && !KeyEvent.metaStateHasNoModifiers(event.getMetaState())
                && event.getRepeatCount() == 0
                && !KeyEvent.isModifierKey(event.getKeyCode())) {
            final Window currentWindow = getWindow();
            if (currentWindow != null && currentWindow.getDecorView() != null) {
                final View decorView = currentWindow.getDecorView();
                if (decorView.dispatchKeyShortcutEvent(event)) {
                    return true;
                }
            }
        }
        return false;
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (performMenuItemShortcut(event)) {
            return true;
        }
        return super.onKeyDown(keyCode, event);
    }

    @Override
    public void openOptionsMenu() {
        ActionBar actionBar = getSupportActionBar();
        if (getWindow().hasFeature(Window.FEATURE_OPTIONS_PANEL)
                && (actionBar == null || !actionBar.openOptionsMenu())) {
            super.openOptionsMenu();
        }
    }

    @Override
    public void closeOptionsMenu() {
        ActionBar actionBar = getSupportActionBar();
        if (getWindow().hasFeature(Window.FEATURE_OPTIONS_PANEL)
                && (actionBar == null || !actionBar.closeOptionsMenu())) {
            super.closeOptionsMenu();
        }
    }

    /**
     * Called when the night mode has changed. See {@link AppCompatDelegate#applyDayNight()} for
     * more information.
     *
     * @param mode the night mode which has been applied
     */
    protected void onNightModeChanged(@NightMode int mode) {
    }

    /**
     * Called when the locales have been changed. See {@link AppCompatDelegate#applyAppLocales()}
     * for more information.
     *
     * @param locales the localeListCompat which has been applied
     */
    protected void onLocalesChanged(@NonNull LocaleListCompat locales) {
    }
}