Remove action bar shadow programmatically

10,026

Solution 1

There is no way to set value for windowContentOverlay attribute programmatically. But you can define two different themes, one for Activities with a visible ActionBar shadow and one for others:

<!-- Your main theme with ActionBar shadow. -->
<style name="MyTheme" parent="Theme.Sherlock">
    ....
</style>

<!-- Theme without ActionBar shadow (inherits main theme) -->
<style name="MyNoActionBarShadowTheme" parent="MyTheme">
    <item name="windowContentOverlay">@null</item>
    <item name="android:windowContentOverlay">@null</item>
</style>

Now you can set them to activities in AndroidManifest.xml:

<!-- Activity with ActionBar shadow -->
<activity
    android:name=".ShadowActivity"
    android:theme="@style/MyTheme"/>

<!-- Activity without ActionBar shadow -->
<activity
    android:name=".NoShadowActivity"
    android:theme="@style/MyNoActionBarShadowTheme"/>

Or you can set the right theme programmatically in onCreate() method:

@Override
protected void onCreate(Bundle savedInstanceState) {
    setTheme(R.style.MyNoActionBarShadowTheme);
    super.onCreate(savedInstanceState);

    //...
}

Solution 2

If you won't make more theme, then try this. This works nicely for me!

public void disableActionbarShadow() {
    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
        View v = getActivity().findViewById(android.R.id.content);
        if (v instanceof FrameLayout) {
            ((FrameLayout) v).setForeground(null);
        }
    }else {
        // kitkat.
        // v is ActionBarOverlayLayout. unfortunately this is internal class.
        // if u want to check v is desired class, try this
        //   if(v.getClass().getSimpleName.equals("ActionBarOverlayLayout")) 
        // (we cant use instanceof caz ActionBarOverlayLayout is internal package)
        View v = ((ViewGroup)getActivity().getWindow().getDecorView()).getChildAt(0);
        v.setWillNotDraw(true);
    }
}

From Kitkat(maybe), ActionBarOverlayLayout is included in activity's view tree.
This shows actionbar shadow (I think XD)

refs: http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/4.4_r1/com/android/internal/widget/ActionBarOverlayLayout.java#79

Becaraful I don't know whats happen if using support library version.

Solution 3

I know this question is old, but this problem was new for me, so it might help somebody else as well.

Try:

  • getSupportActionBar().setElevation(0);

Or, if you are not using a custom action bar:

  • getActionBar().setElevation(0);

I think this is the easiest way to do it programmatically.

Solution 4

Define a new style like this. Notice that there's no parent defined:

<style name="ConOver" >    <<== no parent
    <item name="android:windowContentOverlay">@null</item>
</style>

Add this above your code:

// Add this line before setContentView() call
// Lets you add new attribute values into the current theme
getTheme().applyStyle(R.style.ConOver, true);

// Rest stays the same

Solution 5

Declare 2 styles ne has a shadow and the other one doesn't. THen in your manifest define each activity's theme with respective one. e.g

<Activity 
android:theme="@style/ThemeShadow" ...>

...

<Activity 
android:theme="@style/ThemeNoShadow" ...>
Share:
10,026

Related videos on Youtube

John
Author by

John

Android, React and React-Native enthusiast , And code freak. Love to program and solve problems

Updated on November 02, 2022

Comments

  • John
    John over 1 year

    How can i remove the drop shadow of action bar from java code ?.

    If i remove from the style it is working fine.

    <style name="MyTheme" parent="Theme.Sherlock">
    ....
    <item name="windowContentOverlay">@null</item>
    <item name="android:windowContentOverlay">@null</item>
    ....
    </style>
    

    But i need to remove and add it dynamically from java code.

    • John
      John over 10 years
      i want the shadow, below the actionbar for some activity and not for others.
  • franmontiel
    franmontiel about 9 years
    I don't know why this answer was downvoted, it is the way to remove the actionbar shadow programmatically and it works.
  • Greg Ennis
    Greg Ennis about 9 years
    probably because it only works BEFORE setContentView, which kind of defeats the purpose of doing it programmatically. Better to have different styles on the activity to begin with.
  • Vikram
    Vikram about 9 years
    @GregEnnis Hi Greg, I am not sure why you consider having two activities that only differ in the styles they use 'better'. Moreover, if you notice, we are adding/updating an attribute to/in the style - not using a different one. Can you point to one answer on this page that does not recommend - using two separate activities || recreating an activity || setting the theme before setContentView(...) .
  • Vikram
    Vikram about 9 years
    @GregEnnis By the way, the (second part of) accepted answer has the same restrictions as mine does, was posted much after mine was, and recommends using two separate themes rather than overriding attributes at runtime. At the time of posting, I had pissed someone off on SO, and they were serially downvoting my answers. Within moments of posting, I had acquired a -2. No way anyone wants to even try an answer with that score :)).
  • Greg Ennis
    Greg Ennis about 9 years
    @Vikram well I did not downvote you, actually I just voted you up because getTheme().applyStyle() is a nice tool to have in the bag of tricks. It certainly can be useful in other situations. Point taken about just changing one style should not require a completely different theme definition.
  • Vikram
    Vikram about 9 years
    @GregEnnis Thanks! applyStyle(...) is indeed worth knowing about. An example use-case - last I used applyTheme(..) was to change the overflow menu's background. And you can do this anytime during the activity's life-cycle.