Add elevation/shadow on toolbar for pre-lollipop devices

前端 未结 8 1129
猫巷女王i
猫巷女王i 2020-11-28 05:39

I updated my android app to the new material design, but I also wanted to add some shadow or elevation to the Toolbar. There seem to be some (hacky) ways of doing it via ima

相关标签:
8条回答
  • 2020-11-28 05:54

    I have a CollapsingToolbarLayout with Toolbar and a Toolbar-like View that moves up and down, but lays above NestedScrollView, like in https://github.com/k0shk0sh/CoordinatorLayoutExample. I tried many variants. Sometimes a shadow scrolled above a screen with NestedScrollView, sometimes the Toolbar drew a solid shadow without transparency, sometimes the shadow was aliased. Anyway, this is my solution.

    Say, you have a layout:

    <android.support.design.widget.CoordinatorLayout>
        <android.support.design.widget.AppBarLayout>
             <android.support.design.widget.CollapsingToolbarLayout>
                 <android.support.v7.widget.Toolbar>
                     <!-- Toolbar views if needed -->
                 </android.support.v7.widget.Toolbar>
            </android.support.design.widget.CollapsingToolbarLayout>
        </android.support.design.widget.AppBarLayout>
    
        <!-- Footer Toolbar views if needed -->
    
        <android.support.v4.widget.NestedScrollView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:layout_behavior="@string/appbar_scrolling_view_behavior">
    
            <LinearLayout>
                <!-- Views -->
            </LinearLayout>
    
        </android.support.v4.widget.NestedScrollView>
    
        <!-- Add this view. It draws a shadow and aligns top of NestedScrollView -->
        <!-- Set visibility to gone or visible -->
        <View
            android:id="@+id/scroll_shadow"
            android:layout_width="match_parent"
            android:layout_height="4dp"
            android:background="@drawable/shadow"
            android:visibility="gone"
            app:layout_behavior="@string/appbar_scrolling_view_behavior" />
    
    </android.support.design.widget.CoordinatorLayout>
    

    Add a shadow (drawable/shadow.xml):

    <?xml version="1.0" encoding="utf-8"?>
    <shape xmlns:android="http://schemas.android.com/apk/res/android">
        <gradient
            android:angle="90"
            android:endColor="#ffcccccc"
            android:startColor="#00cccccc" />
    </shape>
    

    Add this method. Here scrollShadow is a view named "scroll_shadow":

    private void setShadowVisibility(int visibility) {
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
            scrollShadow.setVisibility(visibility);
        }
    }
    

    Manipulate it as you wish. It will show a gradient on pre-Lollipop devices and shows a normal shadow for Android 5.0+.

    0 讨论(0)
  • 2020-11-28 05:54

    A simple solution, when using CoordinatorLayout, is to anchor an ImageView with the "shadow" just below the AppBarLayout, or Toolbar. This even works with CollapsingToolbarLayout, and it's correctly rendered atop the "content":

    <CoordinatorLayout>
      <AppBarLayout android:id="@+id/app_bar">
        <Toolbar/>
      </AppBarLayout>
      <include layout="@layout/app_bar_shadow"/>
      <!-- your content usually goes here -->
    </CoordinatorLayout>
    

    Create a res/layout/app_bar_shadow.xml file, which will only be use on pre-Lollipop devices:

    <ImageView
      android:layout_width="match_parent"
      android:layout_height="wrap_content"
      android:adjustViewBounds="true"
      app:layout_anchor="@+id/app_bar"
      app:layout_anchorGravity="bottom"
      android:layout_gravity="bottom"
      app:srcCompat="@drawable/shadow_app_bar"
      />
    

    Create an "empty" res/layout-v21/app_bar_shadow.xml file, used for Android 5+ devices:

     <merge/>
    

    Finally, an appropriate res/drawable/shadow_app_bar.xml:

    <shape>
      <gradient
        android:angle="90"
        android:startColor="#00000000"
        android:endColor="#30000000"
        />
      <size android:height="@dimen/design_appbar_elevation" />
    </shape>
    
    0 讨论(0)
  • 2020-11-28 05:56

    I think the best solution is to put a gradient shadow view below the toolbar and manipulate with visibility depends on device sdk.

    toolbar.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="wrap_content"
            android:orientation="vertical">
    
            <android.support.v7.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android"
                xmlns:app="http://schemas.android.com/apk/res-auto"
                android:id="@+id/toolbar"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                android:background="@android:color/white"
                android:fitsSystemWindows="true"
                app:popupTheme="@style/AppTheme.PopupOverlay">
    
                <TextView
                    android:id="@+id/centerTitleToolbarTextView"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:gravity="center"
                    android:maxLines="1"
                    android:textColor="@color/color_toolbar"
                    android:textSize="@dimen/titleToolbar" />
    
            </android.support.v7.widget.Toolbar>
    
            <View
                android:id="@+id/shadow_view"
                android:layout_width="match_parent"
                android:visibility="gone"
                android:layout_height="4dp"
                android:background="@drawable/toolbar_shadow" />
    
        </LinearLayout>
    

    toolbar_shadow.xml

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

    MainActivity.class

    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
            findViewById(R.id.shadow_view).setVisibility(View.VISIBLE);
          }
    
    0 讨论(0)
  • 2020-11-28 05:57

    use build file:


    compile 'com.android.support:cardview-v7:23.1.1'
    

    refer this link

    to call in xml add:

    app:cardElevation="8dp"
    app:cardCornerRadius="8dp"
    app:contentPadding="5dp"
    
    0 讨论(0)
  • 2020-11-28 05:57

    Use CardView

       <android.support.v7.widget.CardView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="top"
        app:cardCornerRadius="0dp">
    
        <android.support.design.widget.AppBarLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:theme="@style/AppTheme.AppBarOverlay">
    
    
            <android.support.v7.widget.Toolbar
                android:id="@+id/toolbar"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                app:popupTheme="@style/AppTheme.PopupOverlay" />
        </android.support.design.widget.AppBarLayout>
    </android.support.v7.widget.CardView>
    
    0 讨论(0)
  • 2020-11-28 06:00

    For Android 5.0 and above : AppBarLayout automatically provides/gives shadow in the layout. You can also increase the elevation of the AppBarLayout by app:elevation="4dp".

    For Pre-Lollipop : You can use the following link: https://github.com/vipulasri/Toolbar-Elevation-Pre-Lollipop

    Note: Toolbar also supports elevation to it, using android:elevation="4dp"


    New Update: In Appcompat v24.0.0, you can not set elevation to AppBarLayout using setElevation() and app:elevation as these are deprecated.

    You have to use stateListAnimator property to set elevation now.

    Note: set duration to 1ms in StateListAnimator in order to avoid delay in Elevation Drawing.

    AppBarLayout elevation change is delayed on appCompat v24.0.0

    appbar_always_elevated.xml in animator-v21 folder under res directory.

    <?xml version="1.0" encoding="utf-8"?>
    <selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item>
        <objectAnimator android:propertyName="elevation"
                        android:valueTo="8dp" 
                        android:valueType="floatType"
                        android:duration="1"/>
    </item>
    </selector>
    

    In AppbarLayout :

    <android.support.design.widget.AppBarLayout
            android:layout_width="match_parent"
            android:layout_height="300dp"
            android:fitsSystemWindows="true"
            android:stateListAnimator="@animator/appbar_always_elevated"
            android:theme="@style/AppTheme.AppBarOverlay">
    
    </android.support.design.widget.AppBarLayout>
    
    0 讨论(0)
提交回复
热议问题