This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 4 years ago.
I am getting a NullPointerException warning below at setDisplayHomeAsUpEnabled method.
if((getActivity()) != null) {
if(((AppCompatActivity) getActivity()).getSupportActionBar() != null) {
((AppCompatActivity) getActivity()).getSupportActionBar().setDisplayHomeAsUpEnabled(false);
}
}
How do I fix this?
Because you don't put checks for NullPointerException
((AppCompatActivity) getActivity()).getSupportActionBar() gives actionbar object
but you are calling directly by
((AppCompatActivity) getActivity()).getSupportActionBar().setDisplayHomeAsUpEnabled(false)
that is why system gives warning for NullPointerException.
if((getActivity()) != null) {
ActionBar actionBar = ((AppCompatActivity) getActivity()).getSupportActionBar();
if(actionBar != null) {
actionBar.setDisplayHomeAsUpEnabled(false);
}
}
Put above code. Your warning will remove.
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(false);
Using toolbar is a preferred choice. If you use Toolbar and set the Actionbar, you don't need to chekc for NullPointerException.
Probable cause is if you are trying to do this out of the Activity Context you will get NullpointerException. It must set within the Activity Context.
Check your Manifest File, if you have set the theme as NoActionBar and trying to access Actionbar, change it to Apptheme.
Related
I have a generic
MyActivity extends AppCompatActivity
I don't override the toolbar with a custom xml defined toolbar, just use the generated one Android provides.
I can set the title via your normal
getSupportActionBar().setTitle("foo");
but setting the subtitle via
getSupportActionBar().setSubtitle("bar");
doesn't set it. It remains blank. I'm doing this onCreate()
(I feel I've done this many times before with no fail)
Although I've noticed if I visit another activity, then return, the subtitle would then show... not on orientation change, not on recreate() but only when I'm returning from an activity.
I'm experiencing this on 5.0 and 7.0
For the time being I'll likely define my own Toolbar and move forward since that seems where most people have solutions for this same problem.
Relevant code:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_replenishment_list);
ButterKnife.bind(this);
MyApplication.getInstance().getComponent().inject(this);
setupUI();
}
private void setupUI() {
setupActionBar();
}
private void setupActionBar() {
ActionBar actionBar = getSupportActionBar();
if (actionBar != null) {
//TODO: not working unless activity is recreated...
// explore custom xml defined toolbar
//actionBar.setTitle("different title than what is defined in manifest"); <-- this does work, but not this
actionBar.setSubtitle(UserUtil.getFormattedFirstNameLastName(userService.getUserFromJWT(), this));
}
}
I have put the below code in my onCreate() method.
ActionBar actionBar = getActionBar();
if (actionBar==null) {
System.out.println("TEST NULL");
} else {
System.out.println("TEST NOT NULL");
}
The result is null. When I add the toolbar first it works fine.
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
ActionBar actionBar = getActionBar();
actionBar.setSubtitle("TESTING");
Your getSupportActionBar or getActionBar will return null if you didn't set toolbar to it. You need to set the toolbar to your action bar before using getSupportActionBar or getActionBar.
I've got problem with my actionBar. Tryin' to set an icon but still getting null :/ Here's code :
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
getActionBar().setIcon(R.drawable.logo);
getActionBar().setBackgroundDrawable(new ColorDrawable(Color.parseColor("#51717e")));
}
Ofc I've got logo in my drawable folder. Both lines are incorrect - Icon and Background color. Help :/
You are getting Actionbar null because the Theme don't have ActionBar.
Try to set the background and icon in your styles.xml
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.and surround these two line in try catch like:
try{
getSupportActionBar().setIcon(R.drawable.logo);
getSupportActionBar() .setBackgroundDrawable(new ColorDrawable(Color.parseColor("#51717e")));
}catch(NullPointerException e)
{
e.printstacktrace();
}
Try this:
getWindow().requestFeature(Window.FEATURE_ACTION_BAR);
setContentView(R.layout.activity_main);
ActionBar actionBar = getActionBar();
I have this code in my Activity:
protected void onCreate(Bundle savedInstanceState) {
...
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
ActionBar actionBar = getSupportActionBar();
if (actionBar != null) {
actionBar.setDisplayHomeAsUpEnabled(true);
}
...
}
I'm updating the ActionBar title from various fragments like this in onResume():
ActionBar actionBar = ((AppCompatActivity) getActivity()).getSupportActionBar();
if (actionBar != null) {
actionBar.setTitle(title);
}
This is working fine, but after orientation change, the title changes to the app name again. How I can overcome this?
EDIT:
After investigating more, I tried this and found this weird behaviour:
Added this code where I was setting title in Fragments:
final ActionBar actionBar = ((AppCompatActivity)getActivity()).getSupportActionBar();
if (actionBar != null) {
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
Log.d("SWAPNIL", "IN RUN BEFORE: " + actionBar.getTitle());
actionBar.setTitle(title);
Log.d("SWAPNIL", "IN RUN AFTER : " + actionBar.getTitle());
}
}, 3000);
}
And here's the log:
10-13 10:27:04.526 3719-3719/com.example.xxxx D/SWAPNIL: onResumeHelp
10-13 10:27:07.528 3719-3719/com.example.xxxx D/SWAPNIL: IN RUN BEFORE: MY APP NAME
10-13 10:27:07.528 3719-3719/com.example.xxxx D/SWAPNIL: IN RUN AFTER : title
10-13 10:27:21.012 3719-3719/com.example.xxxx D/SWAPNIL: onResumeHelp
10-13 10:27:24.013 3719-3719/com.example.xxxx D/SWAPNIL: IN RUN BEFORE: title
10-13 10:27:24.013 3719-3719/com.example.xxxx D/SWAPNIL: IN RUN AFTER : title
It was getting changed as per logs but wasn't reflected in UI.
Please help me!
Okay, finally, after spending 2 days on this silly thing, I got the solution (I would say workaround).
This is probably a nested Fragment bug.
I have nested Fragment structure. As we know Fragment.getActivity() returns parent Activity. After lot of debugging I observed that if you call getActivity() after orientation change (even inside Fragment.onActivityCreated()) it returns reference of the old Activity except in top most parent fragment where it correctly returns the newly created Activity.
So I've written this method to get current Activity from any Fragment:
/**
* When inside a nested fragment and Activity gets recreated due to reasons like orientation
* change, {#link android.support.v4.app.Fragment#getActivity()} returns old Activity but the top
* level parent fragment's {#link android.support.v4.app.Fragment#getActivity()} returns current,
* recreated Activity. Hence use this method in nested fragments instead of
* android.support.v4.app.Fragment#getActivity()
*
* #param fragment
* The current nested Fragment
*
* #return current Activity that fragment is hosted in
*/
public Activity getActivity(Fragment fragment) {
if (fragment == null) {
return null;
}
while (fragment.getParentFragment() != null) {
fragment = fragment.getParentFragment();
}
return fragment.getActivity();
}
You need to see the answer written by sorianiv here:
In android app Toolbar.setTitle method has no effect – application name is shown as title
Adding the additional toolbar.setTitle("") resolved this issue for me.
Toolbar toolbar = (Toolbar) root.findViewById(R.id.toolbar);
toolbar.setTitle("");
((AppCompatActivity)getActivity()).setSupportActionBar(toolbar);
toolbar.setTitle("Profiles");
I just ran into the same issue, and I solved it by using getSupportActionBar instead of toolbar.
getSupportActionBar().setTitle("...");
You're activity is getting recreated when you rotate the screen. So onCreate is getting called again, and you have not set a title there.
Add the following to your onCreate:
actionBar.setTile("Enter title here")
maybe you can change your Action Bar / ToolBar, in onPostCreate() method in your Activity..
The code is just simple. I try to change my emulator / device orientation for many times and it works like charm..
#Override
protected void onPostCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onPostCreate(savedInstanceState);
toolbar.setTitle(mTitle);
}
Add in Manifest file
<activity
android:name=".Activity"
android:configChanges="orientation|screenSize|keyboardHidden"/>
or
code in onConfigChange()
if(newConfig.orientation==Configuration.ORIENTATION_LANDSCAPE){
// Set Title for Landscape
}else{
// Set Title for Portrait
In my activity I've created a method for the fragments to update the title :
public void setTitle(String title) {
ActionBar ab = getSupportActionBar();
if (ab != null) {
if (title == null) {
title = getString(R.string.string_title);
}
ab.setTitle(title);
}
}
The toolbar is part of a CollapsingToolbarLayout.
It looks like the title is set correctly for the first fragment, however, when the second one tries to update it, it doesn't get updated.
I'm running with v 23 so this is not the known bug.
I am using a toolbar as my actionbar in an activity. I am trying to add the method getActionBar().setDisplayHomeAsUpEnabled(true); to the Activity.java file for Up navigation for older devices.
The method produces the following error message in Android Studio:
Method invocation may produce java.lang.NullPointerException
The Up navigation on the toolbar works fine on newer devices...now I'm trying to figure out how to make sure it will work for older devices.
Please advise.
From build.gradle:
dependencies {
compile "com.android.support:appcompat-v7:22.1.0"
}
From AndroidManifest.xml:
android:theme="#style/Theme.AppCompat.NoActionBar.FullScreen"
From styles.xml
<style name="Theme.AppCompat.NoActionBar.FullScreen" parent="AppTheme">
<item name="android:windowNoTitle">true</item>
<item name="windowActionBar">false</item>
<item name="android:windowFullscreen">true</item>
from Activity.java
public class CardViewActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.cardviewinput);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
if (toolbar != null) {
// Up navigation to the parent activity for 4.0 and earlier
getActionBar().setDisplayHomeAsUpEnabled(true);
toolbar.setNavigationIcon(R.drawable.ic_action_previous_item);
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
onBackPressed();
}
});
}
}
Actually Android Studio isn't showing you an "error message", it's just a warning.
Some answers propose the use of an assertion, Dalvik runtime has assertion turned off by default, so you have to actually turn it on for it to actually do something. In this case (assertion is turned off), what you're essentially doing is just tricking Android Studio to not show you the warning. Also, I prefer not to use "assert" in production code.
In my opinion, what you should do is very simple.
if(getActionBar() != null){
getActionBar().setDisplayHomeAsUpEnabled(true);
}
Update:
In case you're using the support library version of the Action Bar, you should replace getActionBar() with getSupportActionBar().
if(getSupportActionBar() != null){
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
}
First off, you need to set the toolbar as the support ActionBar.
Then if you're certain it's going to be there all the time, just assert it as != null. This will tell the compiler it won't be null, so the null check passes.
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.cardviewinput);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
assert getSupportActionBar() != null;
getSupportActionBar().setDisplayHomeAsUpEnabled(true); // it's getSupportActionBar() if you're using AppCompatActivity, not getActionBar()
}
Thank You Andrew for your answer.
If you have a Nav Drawer or something else that uses getSupportActionBar() you need to add assert getSupportActionBar() != null;
Peace,
Example:
#Override
public void setTitle(CharSequence title) {
mTitle = title;
assert getSupportActionBar() != null;
getSupportActionBar().setTitle(mTitle);
}
Try this :
private ActionBar getActionBar() {
return ((AppCompatActivity) getActivity()).getSupportActionBar();
}
What I have done is override the getSupportActionBar() method in my base Activity and add a #NonNull annotation. This way, I only get one lint warning in the base activity about how I use #NonNull annotation for something that has a #Nullable annotation.
#NonNull
#Override
public ActionBar getSupportActionBar() {
// Small hack here so that Lint does not warn me in every single activity about null
// action bar
return super.getSupportActionBar();
}
I created a generic class such as:
public final class Cast
{
private Cast() {}
/**
* Helps to eliminate annoying NullPointerException lint warning.
*/
#android.support.annotation.NonNull
public static <T> T neverNull(T value)
{
return value;
}
}
then I can use it for any call with NullPointerException warning for which I am sure that it will never happen, e.g.
final ActionBar actionBar = Cast.neverNull(getSupportActionBar());
actionBar.setDisplayHomeAsUpEnabled(true);
actionBar.setHomeButtonEnabled(true);
P.S. don't forget to add "com.android.support:support-annotations" to your gradle file.
add assert getSupportActionBar() != null; before getSupportActionBar().setDisplayHomeAsUpEnabled(true);
if(actionBar != null) {
actionBar.setHomeButtonEnabled(true);
actionBar.setBackgroundDrawable(ContextCompat.getDrawable(mContext,
R.drawable.action_bar_gradient));
}
use this theme: android:theme="#style/Theme.AppCompat.Light.NoActionBar"
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
toolbar.setTitle("Title");
setSupportActionBar(toolbar);
ActionBar actionBar = getSupportActionBar();
actionBar.setHomeButtonEnabled(true);
actionBar.setHomeAsUpIndicator(R.drawable.ic_action_previous_item);
actionBar.setDisplayHomeAsUpEnabled(true);
Alternatively you could assert actionbar to not null.Add the assertion before calling your actionbar as follows
assert getSupportActionBar() != null;
Final snippet would therefore look as follows:
setSupportActionBar((Toolbar) findViewById(R.id.toolbar));
assert getSupportActionBar() != null;
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
Try this :
setSupportActionBar (toolbar);
if(getSupportActionBar () != null) {
assert getSupportActionBar () != null;
getSupportActionBar ().setDisplayHomeUpEnabled(true);
}
Note that setSupportActionBar(toolbar) should be before getSupportActionBar().
if(getSupportActionBar() != null){
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
}
OR
Replace the MainActivity extends AppCompatActivity to public class MainActivity extends AppCompatActivity
just check getSupportActionBar not equal to null
setSupportActionBar(toolbar);
if(getSupportActionBar() != null) {
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setTitle("Daily Shopping List");
}
If you are importing
android.app.ActionBar
you have to use getActionBar()
and if you are importing
android.support.v7.app.ActionBar
use getSupportActionBar()