17

如何从 java 代码中删除操作栏的阴影?

如果我从样式中删除它工作正常。

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

但我需要从java代码中动态删除和添加它。

4

7 回答 7

12

windowContentOverlay无法以编程方式设置属性的值。但是您可以定义两种不同的主题,一种用于带有可见 ActionBar 阴影的活动,另一种用于其他主题:

<!-- 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>

现在您可以将它们设置为以下活动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"/>

或者您可以在onCreate()方法中以编程方式设置正确的主题:

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

    //...
}
于 2014-10-08T11:08:18.463 回答
8

如果你不会制作更多主题,那么试试这个。这对我很有效!

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);
    }
}

从 Kitkat(也许)开始,ActionBarOverlayLayout 包含在活动的视图树中。
这显示了动作栏阴影(我认为 XD)

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

Becaraful 我不知道如果使用支持库版本会发生什么。

于 2014-10-09T11:43:10.450 回答
6

我知道这个问题很老,但这个问题对我来说是新问题,所以它也可能对其他人有帮助。

尝试:

  • getSupportActionBar().setElevation(0);

或者,如果您没有使用自定义操作栏:

  • getActionBar().setElevation(0);

我认为这是以编程方式执行此操作的最简单方法。

于 2017-09-04T19:24:39.383 回答
4

像这样定义一个新样式。请注意,没有定义父级:

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

在您的代码上方添加:

// 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
于 2014-10-05T20:02:28.373 回答
3

声明 2 种样式 ne 有阴影,而另一种则没有。然后在您的清单中用各自的主题定义每个活动的主题。例如

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

...

<Activity 
android:theme="@style/ThemeNoShadow" ...>
于 2014-08-31T21:23:43.950 回答
2

我发现这篇文章: Change Theme of Layout Runtime by Button Click in Android

它允许您更改活动的主题,但它确实会调用 finish() 并重新启动活动。所以,我不确定它是否适合你想要的。

import android.app.Activity;
import android.content.Intent;

public class Utils
{
     private static int sTheme;

     public final static int THEME_DEFAULT = 0;
     public final static int THEME_WHITE = 1;
     public final static int THEME_BLUE = 2;

      /**
       * Set the theme of the Activity, and restart it by creating a new Activity of the same type.
       */
      public static void changeToTheme(Activity activity, int theme)
      {
           sTheme = theme;
           activity.finish();

 activity.startActivity(new Intent(activity, activity.getClass()));

      }

      /** Set the theme of the activity, according to the configuration. */
      public static void onActivityCreateSetTheme(Activity activity)
      {
           switch (sTheme)
                {
                default:
           case THEME_DEFAULT:
               activity.setTheme(R.style.FirstTheme);
               break;
           case THEME_WHITE:
               activity.setTheme(R.style.SecondTheme);
               break;
           case THEME_BLUE:
               activity.setTheme(R.style.Thirdheme);
               break;
           }
      }
 }
于 2014-10-08T16:48:37.350 回答
1

如果supportActionBar.elevation=0f对您不起作用,您可以通过设置移除阴影,appBar.targetElevation=0f但此方法已弃用。新方法是使用StateListAnimator

您必须将其设置stateListAnimatorAppBarLayout无海拔,可以通过以下步骤实现

  1. 创建动画师资源appbar_animator.xml

    <item
        android:state_enabled="true"
        app:state_collapsed="false"
        app:state_collapsible="true">
        <objectAnimator
            android:duration="150"
            android:propertyName="elevation"
            android:valueTo="0dp"
            android:valueType="floatType" />
    </item>
    
    <item android:state_enabled="true">
        <objectAnimator
            android:duration="150"
            android:propertyName="elevation"
            android:valueTo="0dp"
            android:valueType="floatType" />
    </item>
    
    <item>
        <objectAnimator
            android:duration="0"
            android:propertyName="elevation"
            android:valueTo="0"
            android:valueType="floatType" />
    </item>
    

    android.valueTo="0dp"定义高程。

  2. 充气并将其设置StateListAnimatorappBar

    val stateAnimator=AnimatorInflater.loadStateListAnimator(this,R.animator.appbar_animator);
    appBar.stateListAnimator=stateAnimator
    

21api Lollipop中添加了 StateListAnimator

于 2018-08-12T12:47:25.310 回答