I am using a NativeActivity with the style #android:style/Theme.DeviceDefault.NoActionBar.FullScreen. However, the Activity expanded behind the system navigation bar, which is not what I want.
(Black region on the left is due to device cutout, which is what I intended)
I tried to search about this topic and couldn't find posts addressing this problem. Any help would be appreciated.
The effect that I intend would be like:
You can try this function. It will remove only status bar. Call this on onCreate().
private fun hideStatusBar() {
WindowCompat.getInsetsController(window,window.decorView).apply {
systemBarsBehavior = WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
hide(WindowInsetsCompat.Type.statusBars())
}
}
To hide only navigation bar,
use hide(WindowInsetsCompat.Type.navigationBars())
To hide both status and navigation bar,
use hide(WindowInsetsCompat.Type.systemBars())
Additional thing, if you need this in multiple activities, you can create a BaseActivity and call this in BaseActivity on create and extend required activities with BaseActivity. So it will work for activities that extend BaseActivity
Here is Java Equivalent.
private void hideSystemBars() {
WindowInsetsControllerCompat windowInsetsController =
WindowCompat.getInsetsController(getWindow(),getWindow().getDecorView());
windowInsetsController.setSystemBarsBehavior(
WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
);
windowInsetsController.hide(WindowInsetsCompat.Type.statusBars());
}
Hope it helps
Read more here
My app is crashing the minute I run it after I changed my AppCompat-v7 to 21.0.0 and Compiled with no problem.
It gives me the error:
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.app.ActionBar.setIcon(int)' on a null object reference
on this line:
getActionBar().setIcon(R.drawable.ic_action_bar);
It works with AppCompat-v7 20.0.0, but not with 21.0.0.
You need to call getSupportActionBar() on an ActionBarActivity. Do not call getActionBar() -- that is not available on older devices, and for the new r21 edition of appcompat-v7, I would expect it to return null all the time, as the new ActionBarActivity disables and replaces the system action bar.
If your activity is AppCompatActivity, you can get the action bar like this:
android.support.v7.app.ActionBar mActionBar = getSupportActionBar();
Object actionBar = getSupportActionBar();
android.support.v7.internal.app.WindowDecorActionBar bar = (android.support.v7.internal.app.WindowDecorActionBar) actionBar;
If you are developing app targeting 21SDK but app is going to be used under older sdk's then this lines above are the solution.
You can't use getActionBar() under 21SDK when your activity extends ActionBarActivity
Replace ActionBar by android.support.v7.app.ActionBar in all you code. and use setSupportActionBar() also Extent your activity from AppCompatActivity. use android support v7 dependency.
I changed from the original ActionBar to the AppCompat Toolbar and setSupportActionBar(toolbar).
When I am using getSupportActionBar() and setDisplayHomeAsUpEnabled(true) for the back arrow, the click never calls onOptionsItemSelected or any other listener method.
Do I have to implement some special listener for it? Befor everything was working just fine.
EDIT:
Initialise the ActionBar:
mToolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(mToolbar);
mActionBar = getSupportActionBar();
mActionBar.setHomeButtonEnabled(true);
and after replacing the content with a Fragment I do this:
mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED);
mDrawerToggle.setDrawerIndicatorEnabled(false);
mActionBar.setDisplayHomeAsUpEnabled(true);
I know this question has been answered but I found the real cause of the problem after 2 days of frustration.
Take a look at the ActionBarDrawerToggle documentation:
https://developer.android.com/reference/android/support/v7/app/ActionBarDrawerToggle.html
Notice the two constructors there. My mistake was that I was using the second constructor that was taking a toolbar as a parameter. It took me so long to notice the last line in the consturctor documentation:
"Please use ActionBarDrawerToggle(Activity, DrawerLayout, int, int) if you are setting the Toolbar as the ActionBar of your activity."
After using the first constructor onOptionsItemSelected() was called with no issues.
Don't forget to call the ActionBarDrawerToggle.onConfigurationChanged() and onOptionsItemSelected() from your activity as described in the last part here: http://developer.android.com/training/implementing-navigation/nav-drawer.html
I had to implement an OnClickListener for the DrawerToggle:
mDrawerToggle.setToolbarNavigationClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
popStackIfNeeded();
mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED);
mActionBar.setDisplayHomeAsUpEnabled(false);
mDrawerToggle.setDrawerIndicatorEnabled(true);
}
});
this fixed my issue.
I had several issues using the setSupportActionBar() method. It also ignores certain color themes, so you can't style the back arrow or overflow icon (don't remember which). I just did away with ActionBar integration and use the Toolbar natively. So, as an alternative, you could do that as follows.
Just include the toolbar like you would normally, in your layout, assume it's using an id of #+id/toolbar.
Then, in code:
_toolbar = (Toolbar) findViewById(R.id.toolbar);
_toolbar.setNavigationOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
handleNavButtonPress();
}
});
_toolbar.setOnMenuItemClickListener(_menuItemClickListener);
_toolbar.inflateMenu(R.menu.message_list_menu);
Menu menu = _toolbar.getMenu();
In this case, _menuItemClickListener can almost literally be your current onOptionsItemSelected() method renamed. You just don't have to check for menu being null anymore.
To remove items from the menu, just call menu->clear(). So in my onPause, I clear the menus and onResume, I inflate them, in my fragments, and each fragment sets the click handler in onResume. You need to always clean up, because Android won't do that for you in this approach, and the toolbar will keep adding menus every time you inflate.
One last note, to make it all work, you have to disable the action bar completely and remove it from the style.
One thing that wasn't mentioned:
If you build the options menu dynamically in onCreateOptionsMenu and return null there, the up button in the action bar will not work.
Works fine if you return the Menu parameter without adding anything into it.
Tested on emulator API 19
If you've tried everything and it just doesn't work, you can implement your own click listener like so:
myNavList.setOnItemClickListener(new android.widget.AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
String item = myNavList.getItemAtPosition(position).toString();
Toast.makeText(this, "You selected " + item, Toast.LENGTH_SHORT).show();
}
});
In my case the setHasOptionsMenu(true); wasn't enabled on onCreateView. Hope this helps someone.
My app uses the android.support.v7.app.ActionBar so that I can use the Action Bar on my Android 2.3.4 phone and my tablet using Android 4.4.2. I've got my minimum and target SDK's set at 10 and 18. When I click the back button on the Action Bar which calls setDisplayHomeAsUpEnabled(true) it works correctly on the 2.3.4 phone and goes back to the Home Activity called Main_Interface. But when I click the back button on the Action Bar on the tablet, it closes the app as if I clicked the back button on the tablet. Nothing comes up in LogCat, so it's acting as though it's supposed to close the app when the Action Bar setDisplayHomeAsUpEnabled() button is clicked. Here's what the Activity looks like in the Manifest:
<activity
android:name=".UILNPPager"
android:configChanges="orientation|screenSize"
android:label="UILNPPager"
android:parentActivityName="com.myapp.ktg.Main_Interface"
android:theme="#style/Theme.Blu_uilpager" >
<intent-filter>
<action android:name="com.myapp.ktg.UILNPPAGER" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="com.myapp.ktg.Main_Interface" />
</activity>
Here's the Activity stripped of everything but the ActionBar calls:
import android.support.v7.app.ActionBar;
import android.support.v7.app.ActionBarActivity;
public class UILNPPager extends ActionBarActivity {
private static final String STATE_POSITION = "STATE_POSITION";
DisplayImageOptions options;
ViewPager pager;
String[] imTitlesStr;
String[] imMediumStr;
String[] imPriceStr;
String[] imageUrls;
int pagerPosition;
PhotoViewAttacher mAttacher;
ActionBar mActionbar;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.actionbar_uilpager);
//--- ViewPager stuff
....
//--- END ViewPager stuff
/** Getting a reference to action bar of this activity */
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_main_actions, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
NavUtils.navigateUpFromSameTask(this);
return true;
}
return super.onOptionsItemSelected(item);
}
}
I tried taking the call android:parentActivityName="com.myapp.ktg.Main_Interface" out of the manifest, but that has no effect. It still works correctly on the 2.3.4 phone and not on the 4.4.2 tablet.
Any idea why it doesn't work right on the tablet?
Please use a AppCompat theme or a theme that inherits one of them. For example:
#style/ThemeAppCompat
#style/ThemeAppCompat.Light
#style/ThemeAppCompat.Light.DarkActionBar
I noticed that you are using your own styled theme, you can inherit the theme from one of the AppCompat theme as follow.
<style name="Theme.Blu_uilpager"
parent="#style/ThemeAppCompat.Light">
....
</style>
Quoted from a official Android tutorial, https://developer.android.com/training/basics/actionbar/styling.html
Note: If you are using the Support Library APIs for the action bar, then you must use (or override) the Theme.AppCompat family of styles (rather than the Theme.Holo family, available in API level 11 and higher). In doing so, each style property that you declare must be declared twice: once using the platform's style properties (the android: properties) and once using the style properties included in the Support Library (the appcompat.R.attr properties—the context for these properties is actually your app). See the examples below for details.
In my app I'm using my own transitions to move from Activity A to Activity B. I've discovered that the call overridePendingTransition(); in the onPause(); call in Activity A breaks the getSupportActionBar().setDisplayHomeAsUpEnabled(true); call in Activity B, which has the ActionBar. So on Activity A, I removed the onPause() method and called overridePendingTransition(); in the Intent that calls Activity B, like this:
Intent miI = new Intent();
miI.setClass(Splash.this, Main_Interface.class);
startActivity(miI);
overridePendingTransition(R.anim.fadein, R.anim.fadeout);
Then in Activity B I removed the onPause(); method and added overridePendingTransition(R.anim.fadein, R.anim.fadeout); to the onCreate(); method like so:
super.onCreate(savedInstanceState);
overridePendingTransition(R.anim.fadein, R.anim.fadeout);
setContentView(R.layout.mainpage);
Then I put the overridePendingTransition(); call in all other Activities' onCreate(); methods just like in Activity B. Doing this makes the transition work correctly. And to make the ActionBar go back to the Main_Interface Activity correctly on my 4.4.2 tablet, I just call getSupportActionBar().setDisplayHomeAsUpEnabled(true);. And everything is working correctly!
I'm having an odd problem.
I am making an app with targetsdk 13.
In my main activity's onCreate method i call getActionBar() to setup my actionbar. This works fine when running on the Android 3.2 emulator, but when using Android 3.0 and 3.1 the getActionBar() method returns null.
I find this extremely odd, and i cannot see any reason why it would do so.
Is this a bug with the emulators or is there something i need to do, in order to ensure that my application has an actionbar?
SOLUTION:
I think I've found a solution for this problem.
I wasn't using the setContentView to set a layout for the activity. Instead I was using fragmentTransaction.add(android.R.id.content, mFragment, mTag) to add a fragment to the activity.
This worked fine in 3.2, but in earlier honeycomb versions the action bar is apparently not set if you don't use the setContentView in the onCreate() method.
So I fixed it by using the setContentView() method in my onCreate() method and just supplying it with a layout that contained an empty FrameLayout.
I can still use the fragmentTransaction.add(android.R.id.content, mFragment, mTag) method the same way as before.
It's not the prettiest fix, but it works.
Can use getSupportActionBar() instead of getActionBar() method.
If you are using the support library
import android.support.v7.app.ActionBarActivity;
public class MainActivity extends ActionBarActivity {
use getSupportActionBar() instead of getActionBar()
* Update:
The class ActionBarActivity now is deprecated:
import android.support.v7.app.ActionBarActivity;
I recommend to use:
import android.support.v7.app.AppCompatActivity
if you are using android.support.v7.app.AppCompatActivity
public class HomeActivity extends AppCompatActivity {
Then you should be using android.support.v7.app.ActionBar
ActionBar ab = getSupportActionBar();
If you are using android.support.v4.app.FragmentActivity
public class HomeActivity extends FragmentActivity {
then you should be using android.app.ActionBar
ActionBar ab = getActionBar();
If you are using android.support.v7.app.ActionBarActivity
public class HomeActivity extends ActionBarActivity {
you should be using android.support.v7.app.ActionBar
ActionBar ab = getSupportActionBar();
You have to define window type as actionbar before activity render its view.
use
requestWindowFeature(Window.FEATURE_ACTION_BAR);
before calling setContentView() method.
I faced the above issue where getActionBar() method returns null. I was calling the getActionBar() after setting the setContentView() and still its returning a null.
I resolved the issue by setting the min-sdk version in Android Manifest file that was missing initially.
<uses-sdk android:minSdkVersion="11" />
ActionBar needs application or activity's Theme to have an app title. Make sure you have not styled your application or activity as 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" >
import android.support.v7.app.AppCompatActivity;
then
extends AppCompatActivity
then use
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
This answer is late but might be helpful to anyone who arrives from Google: You might well need to declare
<item name="android:windowActionBar">true</item>
in your styles.xml. It seems false can be the default. You also need to be on API 11 or higher.
More details can be found in the documentation here. Specifically, quote:
Tip: If you have a custom activity theme in which you'd like to remove
the action bar, set the android:windowActionBar style property to
false. However, if you remove the action bar using a theme, then the
window will not allow the action bar at all, so you cannot add it
later—calling getActionBar() will return null.
I had the same problem and one of the solutions was to use setContentView() before calling getActionBar().
But there was another thing that fixed the problem. I specified theme for the application to be #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>
I think any theme, which has <item name="android:windowActionBar">true</item> in it, can be used.
The main reason for that is using themes that are not supporting ActionBar:
In manifest file add the following either in your target activity or application element (if you want to unify the theme over whole application)
Examples of themes that are supporting action bar "Theme.AppCompat.Light" or "Theme.Holo.Light" ...
android:theme="#android:style/Theme.Holo.Light"
It is better to put all styles in styles.xml and use it everywhere using "#style/themName" so the previous one will be
android:theme="#style/AppTheme"
and styles.xml will have the following:
<style name="AppTheme" parent="Theme.AppCompat.Light">
Hints:
There is some themes that can not be used in old SDKs like "#android:style/Theme.Holo.Light.DarkActionBar" is not supported before SDKs version 14.
To allow your app to support minimum specific version of SDK you could add the following under <app> element:
<uses-sdk android:minSdkVersion="14" />
To specify min SDK version in AndroidStudio, you could by using app's Gradle file.
android{
defaultConfig{
minSdkVersion 14
targetSdkVersion 21
}
}
I ran into this problem . I was checking for version number and enabling the action bar only if it is greater or equal to Honeycomb , but it was returning null. I found the reason
and root cause was that I had disabled the Holo Theme style in style.xml under values-v11 folder.
go to the AndroidManifest.xml and replace
android:theme="#style/AppTheme"
by
android:theme="#android:style/Theme.Holo.Light.DarkActionBar"
Use getSupportActionBar() instead of getActionBar()
In my case, I had this in my code which did not work:
#Override
protected void onCreate(Bundle savedInstanceState) {
context = getApplicationContext();
requestWindowFeature(Window.FEATURE_ACTION_BAR);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
Then I played with the order of the code:
#Override
protected void onCreate(Bundle savedInstanceState) {
requestWindowFeature(Window.FEATURE_ACTION_BAR);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
context = getApplicationContext();
}
And it worked!
Conclusion: requestWindowFeature should be the first thing you call in the onCreate method.
I had the same issue. It solved by chaning App theme in styles.xml
Before
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
After
<!-- Base application theme. -->
<style name="AppTheme" parent="android:Theme.Holo.Light.DarkActionBar">
One thing I wanted to add since I just ran into this, if you are trying to getActionBar() on an Activity that has a parent, it will return null. I am trying to refactor code where my Activity is contained inside an ActivityGroup, and it took a good few minutes for me to go "oh duh" after looking at the source of how an ActionBar gets created in source.
I solve it by this changes:
change in minifest android:theme="#android:style/Theme.Holo.Light" >
add to class extends ActionBarActivity
add import to class import android.support.v7.app.ActionBarActivity
To add to the other answers:
Make sure you call setActionBar() or setSupportActionBar() in your onCreate() method before calling the getActionBar():
Define some Toolbar in your activity.xml, then in the onCreate():
Toolbar toolbar = (Toolbar) findViewById(R.id.my_toolbar);
setSupportActionBar(toolbar);
// Now you can use the get methods:
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
In my case I simply had to extend AppCompatActivity instead of Activity
supportActionBar?.setDisplayHomeAsUpEnabled(true)
Full activity example class:
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)
} }
On Versions
minSdkVersion 22
targetSdkVersion 29
I know I am late to the party (and new to Android) on this question but I found the information here very helpful and thought I should add the findings of my own endeavours with getting ActionBar to work as I wanted in case others like me come looking for help.
I have a widget which is a floating window with no window title. I use a style theme to implement android:windowIsFloating, android:backgroundDimEnabled and android:windowNoTitle. The widget worked fine until I wanted to add a button that called a fragment pager with several list fragment pages and used the ActionBar. It would crash on the pager activity with a null pointer exception. I narrowed it down to the ActionBar being null. Following the findings of previous people who contributed to this thread I removed my theme from the manifest file and the ActionBar worked fine but now my window now longer floated (it was fullscreen) and it had a page title I did not want.
Further research took me to the Styles and Themes API Training Guide which led me to a solution. I discovered I could add my custom theme to individual activities in the manifest file whereas before I was applying it to the application. All my windows now have the desired appearance.
Try extending your Activity class from ActionBarActivity. This solved it for me. Do something like the following:
public class MyActivity extends ActionBarActivity
{
. . .
In my case the class was extending only from Activity.
This may also help some people.
In my case, it was because I had not defined a context in the menu.xml
Try this:
<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">
Instead of this:
<menu xmlns:android="http://schemas.android.com/apk/res/android">
Just check the implementation of source code by command click:
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); Fixed my issue as I saw requestWindowFeature(Window.FEATURE_ACTION_BAR) is failing; code is open source use it !!
android.support.v7.app.ActionBar actionBar = getSupportActionBar();
works pretty quickly
If calling this method from Fragment the make sure to call this in onActivityCreated()