getActionBar () zwraca null

176

Mam dziwny problem. Tworzę aplikację z Targetsdk 13.

W metodzie onCreate mojego głównego działania wywołuję, getActionBar()aby skonfigurować mój pasek akcji . Działa to dobrze, gdy działa na emulatorze systemu Android 3.2, ale podczas korzystania z systemu Android 3.0 i 3.1 getActionBar()metoda zwraca wartość null.

Uważam to za wyjątkowo dziwne i nie widzę żadnego powodu, dla którego miałoby to zrobić. Czy jest to błąd w emulatorach, czy też muszę coś zrobić, aby upewnić się, że moja aplikacja ma pasek akcji?

ROZWIĄZANIE: Myślę, że znalazłem rozwiązanie tego problemu. Nie używałem setContentView do ustawienia układu działania. Zamiast tego użyłem, fragmentTransaction.add(android.R.id.content, mFragment, mTag)aby dodać fragment do ćwiczenia. To działało dobrze w 3.2, ale we wcześniejszych wersjach plastra miodu pasek akcji najwyraźniej nie jest ustawiony, jeśli nie używasz setContentView w onCreate()metodzie. Więc naprawiłem to, używając setContentView()metody w mojej onCreate()metodzie i po prostu dostarczając jej układ zawierający pusty FrameLayout. Nadal mogę używać tej fragmentTransaction.add(android.R.id.content, mFragment, mTag)metody w taki sam sposób jak poprzednio.

To nie jest najpiękniejsza poprawka, ale działa.

Christian Skogsberg
źródło
jak wskazałeś w odpowiedzi na inny post, potrzebujesz motywu Holo. Nie przypuszczaj, że podałeś motyw holo tylko w folderze res v13? Przepraszam, jeśli brzmi to zbyt oczywiste.
PJL,
Nie, to też była moja pierwsza myśl, ale tak nie jest. Dziękuję za twoją odpowiedź.
Christian Skogsberg

Odpowiedzi:

226

Można użyć getSupportActionBar()zamiast getActionBar()metody.

Amir
źródło
ze wszystkich stąd, to zrobiło to dla mnie!
msysmilu
16
dzięki, używałem „android.support.v7.app.ActionBarActivity”, więc zrobiłem to za mnie.
velval
1
Po 2 godzinach poszukiwań! Zmiana na getSupportActionBar () i android.support.v7.app.ActionBarActivity w końcu rozwiązuje to za mnie.
FacePalm
To jest rozwiązanie problemu.
zygimantus
46

Jeśli korzystasz z biblioteki wsparcia

import android.support.v7.app.ActionBarActivity;

public class MainActivity extends ActionBarActivity {

użyj getSupportActionBar()zamiastgetActionBar()

* Aktualizacja:

Klasa ActionBarActivity jest teraz przestarzała:

import android.support.v7.app.ActionBarActivity;

Polecam użyć:

import android.support.v7.app.AppCompatActivity
Jorgesys
źródło
wewnątrz android.support.v7.app: ActionBarActivityprzestarzałe Użyj android.support.v7.app.AppCompatActivityzamiast tego.
A. Petrov
35

Musisz zdefiniować typ okna jako pasek akcji, zanim aktywność wyrenderuje widok.

posługiwać się

requestWindowFeature(Window.FEATURE_ACTION_BAR);

przed wywołaniem metody setContentView ().

kaushal trivedi
źródło
Jeśli getSupportActionBar () nie działa, to działa jak urok
Ashwin Balani
35
  1. jeśli używasz android.support.v7.app.AppCompatActivity

    public class HomeActivity rozszerza AppCompatActivity {

Następnie powinieneś używać android.support.v7.app.ActionBar

  ActionBar ab = getSupportActionBar();
  1. Jeśli używasz android.support.v4.app.FragmentActivity

    public class HomeActivity extends FragmentActivity {

wtedy powinieneś używać android.app.ActionBar

    ActionBar ab = getActionBar();
  1. Jeśli używasz android.support.v7.app.ActionBarActivity

    public class HomeActivity rozszerza ActionBarActivity {

powinieneś używać android.support.v7.app.ActionBar

   ActionBar ab = getSupportActionBar();
Hitesh Sahu
źródło
Świetna odpowiedź, rozwiązuje zamieszanie !!
sud007
31

Napotkałem powyższy problem, w którym getActionBar()metoda zwraca wartość null. Dzwoniłem getActionBar()po ustawieniu setContentView()i nadal zwraca null.

Rozwiązałem problem, ustawiając wersję min-sdk w pliku manifestu Androida, którego początkowo brakowało. <uses-sdk android:minSdkVersion="11" />

Rajendra
źródło
4
To zaoszczędziło mi dużo czasu! Każdy, kto korzysta z przykładowej aplikacji Bluetooth Chat w pakiecie Android SDK, musi skorzystać z tej poprawki. Manifest aplikacji nie zawiera przestrzeni nazw „android:” w tagu minSdkVersion, więc nie jest ona rejestrowana. Dodanie przestrzeni nazw naprawia błąd polegający na tym, że pasek akcji nie został znaleziony. Niechlujnie, Google!
Nick
Właściwie wystarczy określić targetSdkVersion. Możesz uruchomić z niższą minSdkVersion, jeśli używasz biblioteki kompatybilnej, ale targetSdkVersion określa zachowanie.
William
Wspaniały!! to jest to, czego szukałem.
swiftBoy
<uses-sdk android: minSdkVersion = "11" /> rozwiązał mój problem, dziękuję
Majid
27

ActionBar potrzebuje motywu aplikacji lub działania, aby mieć tytuł aplikacji. Upewnij się, że aplikacja lub aktywność nie została nadana jako Theme.NOTITLE.

<application
    android:name="com.xxx.yyy"
    android:debuggable="false"
    android:icon="@drawable/icon"
    android:label="@string/app_name"
    android:theme="@style/Theme.NoTitle"> // remove this line if you have this in your code


<activity
        android:name="com.xxx.yyy.Activity"
        android:configChanges="orientation|keyboardHidden|screenSize"
        android:theme="@style/Theme.NoTitle"  // remove this line if you have in your code
        android:windowSoftInputMode="adjustResize|stateHidden" > 
Himanshu Virmani
źródło
19
import android.support.v7.app.AppCompatActivity;

następnie

extends AppCompatActivity

następnie użyj

getSupportActionBar().setDisplayHomeAsUpEnabled(true);
Abilash Rajasekaran
źródło
rozwiązuje mój problem w przykładzie szuflady nawigacji Google.
Weishi Zeng
Dobre rozwiązanie, ale dla tych, którzy je wdrożyli, najprawdopodobniej otrzymają błędy związane ze zgodnością. Jeśli tak się stanie, upewnij się, że zaimportowałeś pliki android.support.v4.app.FragmentTransaction zamiast tylko android.app.FragmentTransaction i android.support.v7.app.ActionBar zamiast android.app.ActionBar
Serj Ardovic
18

Ta odpowiedź jest spóźniona, ale może być pomocna dla każdego, kto przychodzi z Google: może być konieczne zgłoszenie

<item name="android:windowActionBar">true</item>

w twoim styles.xml. Wydaje się, że falsemoże to być ustawienie domyślne. Musisz także mieć interfejs API 11 lub nowszy.

Więcej szczegółów można znaleźć w dokumentacji tutaj . W szczególności zacytuj:

Porada: Jeśli masz niestandardowy motyw działania, w którym chcesz usunąć pasek akcji, ustaw właściwość stylu android: windowActionBar na false. Jeśli jednak usuniesz pasek akcji za pomocą motywu, okno w ogóle nie zezwoli na pasek akcji, więc nie możesz dodać go później - wywołanie getActionBar () zwróci wartość null.

SK9
źródło
11

Miałem ten sam problem i jednym z rozwiązań było skorzystanie setContentView()przed telefonem getActionBar().

Ale była inna rzecz, która rozwiązała problem. Określiłem motyw dla aplikacji @android:style/Theme.Holo.Light.

<application
    android:allowBackup="true"
    android:icon="@drawable/ic_launcher"
    android:label="@string/app_name"
    android:theme="@android:style/Theme.Holo.Light" >
    ...
</application>

Myślę, <item name="android:windowActionBar">true</item>że można użyć dowolnego tematu, który się w nim znajduje.

ntoskrnl
źródło
Dzięki, u mnie działa. W moim przypadku metoda getActionBar () również zwróciła wartość null i mogłem rozwiązać ten problem zmieniając styl motywu na Theme.Holo.Light. W przypadku innych motywów (np. Theme.AppCompat) wydaje się, że ActionBar nie jest aktywny, więc jego wartość jest zerowa.
harrakiss
10

Głównym tego powodem jest używanie motywów, które nie obsługują ActionBar:

W pliku manifestu dodaj następujące elementy do działania docelowego lub elementu aplikacji (jeśli chcesz ujednolicić motyw w całej aplikacji)

Przykłady motywów obsługujących pasek akcji "Theme.AppCompat.Light"lub "Theme.Holo.Light"...

android:theme="@android:style/Theme.Holo.Light"

Lepiej jest umieścić wszystkie style styles.xmli używać go wszędzie, używając, "@style/themName"aby poprzedni był

android:theme="@style/AppTheme"

a style.xml będą miały następujące elementy:

 <style name="AppTheme" parent="Theme.AppCompat.Light">

Poradnik:

  • Istnieje kilka motywów, których nie można używać w starych pakietach SDK, na przykład "@android:style/Theme.Holo.Light.DarkActionBar"nie są one obsługiwane przed wersjami SDK 14.
  • Aby umożliwić aplikacji obsługę określonej minimalnej wersji pakietu SDK, możesz dodać następujący <app>element w sekcji :

    <uses-sdk android:minSdkVersion="14" />
  • Aby określić minimalną wersję zestawu SDK w AndroidStudio, możesz użyć pliku Gradle aplikacji.

    android{
      defaultConfig{
        minSdkVersion 14
        targetSdkVersion 21
      }
    }
Muhammad Soliman
źródło
ale co mam zrobić, aby obsługiwać poziom API 9-13, jeśli używam Theme.Holo.Light.DarkActionBar
Sid
8

Natknąłem się na ten problem. Sprawdzałem numer wersji i włączałem pasek akcji tylko wtedy, gdy jest większy lub równy Honeycomb, ale zwracał null. Znalazłem przyczynę i główną przyczynę, że wyłączyłem styl Holo Theme w style.xml w folderze values-v11.

Pratap Singh
źródło
Mój problem został rozwiązany przez użycie Holo Theme jako motywu nadrzędnego mojego AppTheme.
Bharat Dodeja
7

przejdź do AndroidManifest.xml i zamień

android: theme = "@ style / AppTheme"

by 

android: theme = "@ android: style / Theme.Holo.Light.DarkActionBar"

NEERAJ GUPTA
źródło
6

Użyj getSupportActionBar () zamiast getActionBar ()

sonal balekai
źródło
4

W moim przypadku miałem to w swoim kodzie, który nie działał:

@Override
protected void onCreate(Bundle savedInstanceState) {
    context = getApplicationContext();

    requestWindowFeature(Window.FEATURE_ACTION_BAR);

    super.onCreate(savedInstanceState);

    setContentView(R.layout.activity_main);
}

Potem bawiłem się kolejnością kodu:

@Override
protected void onCreate(Bundle savedInstanceState) {
    requestWindowFeature(Window.FEATURE_ACTION_BAR);

    super.onCreate(savedInstanceState);

    setContentView(R.layout.activity_main);

    context = getApplicationContext();
}

I zadziałało!

Wniosek: requestWindowFeature powinno być pierwszą rzeczą, którą wywołujesz w metodzie onCreate.

Szymon
źródło
3

Miałem ten sam problem. Rozwiązano go, zmieniając motyw aplikacji w styles.xml

Przed

<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">

Po

<!-- Base application theme. -->
<style name="AppTheme" parent="android:Theme.Holo.Light.DarkActionBar">
jafarmlp
źródło
2

Jedną rzeczą, którą chciałem dodać, ponieważ właśnie natknąłem się na to, jeśli próbujesz getActionBar () na działaniu, które ma rodzica, zwróci wartość null. Próbuję refaktoryzować kod, w którym moja aktywność jest zawarta w grupie ActivityGroup, i zajęło mi dobre kilka minut, aby przejść do „oh duh” po sprawdzeniu źródła tworzenia ActionBar w kodzie źródłowym.

C Nick
źródło
czy możesz opublikować swoje rozwiązanie dla grup aktywności?
Anthea
Moje rozwiązanie z tego, co pamiętam, to refaktoryzacja kodu, aby nie używać żadnych ActivityGroups. Przepraszam, nie mam fragmentów kodu :(
C Nick,
W rzeczywistości nie jest to rozwiązanie; więcej komentarza. Ale bardzo przydatne!
Kato
1

Rozwiązuję to przez te zmiany:

  1. zmiana w minifest android:theme="@android:style/Theme.Holo.Light" >
  2. dodaj do klasy extends ActionBarActivity
  3. dodaj import do klasy import android.support.v7.app.ActionBarActivity
Sharon lub Weissberg
źródło
1

Aby dodać do innych odpowiedzi:

Upewnij się, że wywołujesz setActionBar()lub setSupportActionBar()w swojej onCreate()metodzie przed wywołaniem getActionBar():

Zdefiniuj pasek narzędzi w swoim pliku activity.xml, a następnie w onCreate ():

Toolbar toolbar = (Toolbar) findViewById(R.id.my_toolbar);
setSupportActionBar(toolbar);
// Now you can use the get methods:
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
A-Sharabiani
źródło
0

Wiem, że spóźniłem się na imprezę (i nowy na Androida) w tej kwestii, ale znalazłem informacje tutaj bardzo pomocne i pomyślałem, że powinienem dodać wyniki moich własnych starań, aby ActionBar działał tak, jak chciałem, na wypadek, gdyby inni tacy jak ja przyszli szukam pomocy.

Mam widżet, który jest ruchomym oknem bez tytułu okna. Używam motywu styl do wdrożenia android:windowIsFloating, android:backgroundDimEnableda android:windowNoTitle. Widżet działał dobrze, dopóki nie chciałem dodać przycisku, który wywoływał fragment pagera z kilkoma stronami z fragmentami listy i używał ActionBar. To spowodowałoby awarię podczas działania pagera z wyjątkiem wskaźnika zerowego. Zawęziłem to do wartości zerowej ActionBar. Zgodnie z ustaleniami poprzednich osób, które brały udział w tym wątku, usunąłem mój motyw z pliku manifestu i ActionBar działał dobrze, ale teraz moje okno było teraz dłuższe (było pełnoekranowe) i miało tytuł strony, którego nie chciałem.

Dalsze badania doprowadziły mnie do Przewodnika szkoleniowego interfejsu API stylów i motywów, który doprowadził mnie do rozwiązania. Odkryłem, że mogę dodać mój motyw niestandardowy do poszczególnych działań w pliku manifestu, podczas gdy przed zastosowaniem go w aplikacji. Wszystkie moje okna mają teraz pożądany wygląd.

DocM
źródło
0

Spróbuj rozszerzyć swoją klasę Activity z ActionBarActivity. To rozwiązało to dla mnie. Zrób coś takiego:

public class MyActivity extends ActionBarActivity
{
  . . .

W moim przypadku klasa rozszerzała się tylko z Activity.

Alyoshak
źródło
0

Może to również pomóc niektórym osobom.

W moim przypadku było tak, ponieważ nie zdefiniowałem kontekstu w menu.xml

Spróbuj tego:

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

Zamiast tego:

<menu xmlns:android="http://schemas.android.com/apk/res/android">
ElaGorilaki
źródło
0

Wystarczy sprawdzić implementację kodu źródłowego, klikając polecenie:

    private void initWindowDecorActionBar() {
    Window window = getWindow();

    // Initializing the window decor can change window feature flags.
    // Make sure that we have the correct set before performing the test below.
    window.getDecorView();

    if (isChild() || !window.hasFeature(Window.FEATURE_ACTION_BAR) || mActionBar != null) {
        return;
    }

    mActionBar = new WindowDecorActionBar(this);
    mActionBar.setDefaultDisplayHomeAsUpEnabled(mEnableDefaultActionBarUp);

    mWindow.setDefaultIcon(mActivityInfo.getIconResource());
    mWindow.setDefaultLogo(mActivityInfo.getLogoResource());
}

requestWindowFeature (Window.FEATURE_ACTION_BAR); Naprawiono mój problem, ponieważ zobaczyłem, że requestWindowFeature (Window.FEATURE_ACTION_BAR) nie działa; kod jest open source użyj go !!

Ankish Jain
źródło
0

android.support.v7.app.ActionBar actionBar = getSupportActionBar();

działa dość szybko

Akhila Madari
źródło
3
Chociaż ten kod może odpowiedzieć na pytanie, dostarczenie dodatkowego kontekstu dotyczącego tego, jak i / lub dlaczego rozwiązuje problem, poprawiłoby długoterminową wartość odpowiedzi.
Nic3500,
0

W moim przypadku po prostu musiałem AppCompatActivityzamiast tego przedłużyćActivity

    supportActionBar?.setDisplayHomeAsUpEnabled(true)

Przykładowa klasa pełnej aktywności:

import android.os.Bundle import androidx.appcompat.app.AppCompatActivity

//class LocationFound : Activity() { <-----Does not seem to work with ActionBar in recent versions
class LocationFound : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_location_found)

        supportActionBar?.setDisplayHomeAsUpEnabled(true)
    } }

W wersjach

    minSdkVersion 22
    targetSdkVersion 29
DaddyMoe
źródło