在android中为状态栏和工具栏创建从上到下的线性渐变

Create Linear gradient from top to bottom to status bar and toolbar in android

我想为状态栏和工具栏添加线性渐变颜色。 我可以向状态栏和工具栏添加渐变,角度为 0 度,显示从左到右的渐变颜色 (pink on left and purple on right) 但我想要从上到下或从下到上 (eg: top pink and bottom purple) 的 90 度角的渐变流。我试过了,但我最终得到了这个 this.Here 状态栏和工具栏被分开,我想要状态栏和工具栏都具有相同的渐变颜色,渐变角度为 90 度

在 KitKat 和更高版本中,您可以通过将状态栏设置为半透明并使用带有稀松布的全屏布局来控制状态栏和操作栏背景,同时注意将状态栏的渐变混合到操作栏中。

需要注意的是,KitKat 在我们自己的之上使用了自己的渐变稀松布,这似乎无法覆盖,但在 Lollipop+ 上没有这样的问题。

这是在 MarshMallow 模拟器上运行 activity 的示例:

这是我使用的代码:

res/values/styles.xml:

<style name="AppTheme" parent="Theme.AppCompat.NoActionBar">
    <item name="colorPrimary">@color/colorPrimary</item>
    <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
    <item name="colorAccent">@color/colorAccent</item>
    <item name="actionBarStyle">@style/MyActionBar</item>
</style>

<style name="MyActionBar" parent="@style/Widget.AppCompat.ActionBar">
    <item name="background">@drawable/actionbar_bg</item>
</style>

<style name="AppTheme.ActionBar.Popup" parent="ThemeOverlay.AppCompat">
    <item name="android:colorBackground">@color/colorPrimaryDark</item>
    <item name="background">@color/colorPrimaryDark</item>
</style>

res/values/colors.xml:

<resources>
    <color name="colorPrimary">#ff7000e0</color>
    <color name="colorPrimaryDark">#ff400080</color>
    <color name="colorAccent">#ff40aba0</color>
</resources>

res/drawable/statusbar_bg.xml:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    <gradient
        android:angle="270"
        android:endColor="#ff7000e0"
        android:startColor="#ff8000ff" />
</shape>

res/drawable/actionbar_bg.xml:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    <gradient
        android:startColor="#ff7000e0"
        android:endColor="#ff400080"
        android:angle="270" />
</shape>

res/layout/activity_main.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:fitsSystemWindows="false" >

    <View
        android:id="@+id/main_activityStatusBarScrim"
        android:layout_width="match_parent"
        android:layout_height="26dp"
        android:background="@drawable/statusbar_bg"/>

    <android.support.v7.widget.Toolbar
        android:id="@+id/main_activityToolbar"
        android:layout_width="match_parent"
        android:layout_height="?android:attr/actionBarSize"
        android:background="@drawable/actionbar_bg"
        app:popupTheme="@style/AppTheme.ActionBar.Popup"/>

    <FrameLayout
        android:id="@+id/main_activityFragmentContainer"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:fitsSystemWindows="true"
        android:background="#ffffffff">

    </FrameLayout>

</LinearLayout>

MainActivity.java:

public class MainActivity extends AppCompatActivity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // make the main layout fill the screen
        Window window = getWindow();
        final int layoutFlags = View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN;
        window.getDecorView().setSystemUiVisibility(layoutFlags);
        supportRequestWindowFeature(Window.FEATURE_ACTION_BAR_OVERLAY);

        // make the status bar translucent
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
            window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
            window.setStatusBarColor(0x00000000);
        } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            // N.B. on some (most?) KitKat devices the status bar has a pre-defined gradient that
            // cannot be overridden.
            window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
        }

        // inflate main layout and set up action bar
        setContentView(R.layout.activity_main);
        Toolbar toolbar = findViewById(R.id.main_activityToolbar);
        if (toolbar != null) {
            setSupportActionBar(toolbar);
        }

        // set the height of the scrim to standard status bar height for this device (normally 26dp)
        View statusBarScrim = findViewById(R.id.main_activityStatusBarScrim);
        int height;
        int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android");
        if (resourceId > 0) {
            height = getResources().getDimensionPixelSize(resourceId);
        } else {
            // belt and braces 
            height = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 26f, getResources().getDisplayMetrics());
        }
        if (statusBarScrim != null) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
                ViewGroup.LayoutParams lp = statusBarScrim.getLayoutParams();
                lp.height = height;
                statusBarScrim.setLayoutParams(lp);
                statusBarScrim.setVisibility(View.VISIBLE);
            }
        }

    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
    ...