Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Fading action bar effect using the new Toolbar class from the support library
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@null"
tools:context=".MainActivity">
<com.github.manuelpeinado.toolbartest.ObservableScrollView
android:id="@+id/scrollview"
android:text="@string/hello_world"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true">
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/header"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:adjustViewBounds="true"
android:src="@drawable/nyc" />
<TextView
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:background="?android:colorBackground"
android:padding="16dp"
android:text="@string/loren_ipsum" />
</LinearLayout>
</com.github.manuelpeinado.toolbartest.ObservableScrollView>
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:layout_gravity="top"
android:minHeight="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />
</FrameLayout>
package com.github.manuelpeinado.toolbartest;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.support.v7.widget.Toolbar;
import android.view.Menu;
import android.view.View;
import com.readystatesoftware.systembartint.SystemBarTintManager;
public class MainActivity extends ActionBarActivity implements OnScrollChangedCallback {
private Toolbar mToolbar;
private Drawable mActionBarBackgroundDrawable;
private View mHeader;
private int mLastDampedScroll;
private int mInitialStatusBarColor;
private int mFinalStatusBarColor;
private SystemBarTintManager mStatusBarManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mToolbar = (Toolbar) findViewById(R.id.toolbar);
mActionBarBackgroundDrawable = mToolbar.getBackground();
setSupportActionBar(mToolbar);
mStatusBarManager = new SystemBarTintManager(this);
mStatusBarManager.setStatusBarTintEnabled(true);
mInitialStatusBarColor = Color.BLACK;
mFinalStatusBarColor = getResources().getColor(R.color.primary_color_dark);
mHeader = findViewById(R.id.header);
ObservableScrollable scrollView = (ObservableScrollable) findViewById(R.id.scrollview);
scrollView.setOnScrollChangedCallback(this);
onScroll(-1, 0);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
@Override
public void onScroll(int l, int scrollPosition) {
int headerHeight = mHeader.getHeight() - mToolbar.getHeight();
float ratio = 0;
if (scrollPosition > 0 && headerHeight > 0)
ratio = (float) Math.min(Math.max(scrollPosition, 0), headerHeight) / headerHeight;
updateActionBarTransparency(ratio);
updateStatusBarColor(ratio);
updateParallaxEffect(scrollPosition);
}
private void updateActionBarTransparency(float scrollRatio) {
int newAlpha = (int) (scrollRatio * 255);
mActionBarBackgroundDrawable.setAlpha(newAlpha);
mToolbar.setBackground(mActionBarBackgroundDrawable);
}
private void updateStatusBarColor(float scrollRatio) {
int r = interpolate(Color.red(mInitialStatusBarColor), Color.red(mFinalStatusBarColor), 1 - scrollRatio);
int g = interpolate(Color.green(mInitialStatusBarColor), Color.green(mFinalStatusBarColor), 1 - scrollRatio);
int b = interpolate(Color.blue(mInitialStatusBarColor), Color.blue(mFinalStatusBarColor), 1 - scrollRatio);
mStatusBarManager.setTintColor(Color.rgb(r, g, b));
}
private void updateParallaxEffect(int scrollPosition) {
float damping = 0.5f;
int dampedScroll = (int) (scrollPosition * damping);
int offset = mLastDampedScroll - dampedScroll;
mHeader.offsetTopAndBottom(-offset);
mLastDampedScroll = dampedScroll;
}
private int interpolate(int from, int to, float param) {
return (int) (from * param + to * (1 - param));
}
}
<resources>
<style name="AppTheme" parent="Theme.AppCompat.Light">
<item name="windowActionBar">false</item>
<item name="android:windowTranslucentStatus">true</item>
<item name="android:fitsSystemWindows">true</item>
<item name="colorPrimary">@color/primary_color</item>
<item name="colorPrimaryDark">@color/primary_color_dark</item>
<item name="colorAccent">#f77</item>
</style>
</resources>
@charlires
Copy link

Thanks for the sample I am searching for this com.github.manuelpeinado.toolbartest.ObservableScrollView but I cant find it.

@deakjahn
Copy link

deakjahn commented Dec 7, 2014

Charly, it's part of Manuel's pre-Lollipop FadingActionBar library at https://github.com/ManuelPeinado/FadingActionBar .

Copy link

ghost commented Dec 13, 2014

Does this work around go well with ObservableWebViewWithHeader as well? Any other change that I need to do to make it work?
Will give it a try and post back.

@beraldofilippo
Copy link

Hi, I've noticed that mToolbar.setBackground(mActionBarBackgroundDrawable); is supported only in API 16+. Any suggestion about mantaining compatibility with older versions as well (e.g. API 11+)?

@dshen6
Copy link

dshen6 commented Dec 23, 2014

If you are only changing the alpha of the background, rather than changing the entire background asset, you could call toolbar.invalidate() after the setAlpha().

@chipcerio
Copy link

this is great just as the play store toolbar behaves but one thing it can't do, it doesn't fades the text in it

@rampatra
Copy link

It works great but i faced an absurd issue with nexus 5 running lollipop. The toolbar opacity doesn't return back to normal when i exit the activity and return to my previous activity.

I tried calling updateActionBarTransparency(1) on onStop() but still this issue persists. Can anyone help me out?

@FatihPolat
Copy link

It works with textview but when i try to replace textview with listview it is not working , is there anyway to implement the same effect for listview ?

@Shajeel-Afzal
Copy link

It is not working for me because text is going on top of the Picture on scrolling. Can anyone please help?

@Shajeel-Afzal
Copy link

I was facing this problem because i was not setting the background color of the TextView.

@nathaliepl
Copy link

@ramswaroop You could solve the problem calling this code on activity's onResume method:
toolbarBackgroundDrawable.setAlpha(255); // 0% of transparency
toolbar.setBackground(toolbarBackgroundDrawable);

@omartosca
Copy link

So Android Studio keep saying me:

java.lang.RuntimeException: Unable to start activity ComponentInfo{com.vorticelabs.miveo/com.vorticelabs.miveo.activities.VideoViewActivity}: android.view.InflateException: Binary XML file line #9: Error inflating class com.vorticelabs.miveo.activities.ObservableScrollView
Caused by: java.lang.ClassNotFoundException: Didn't find class "com.github.manuelpeinado.toolbartest.ObservableScrollView" on path: DexPathList[[zip file "/data/app/com.vorticelabs.miveo-2/base.apk"],nativeLibraryDirectories=[/vendor/lib, /system/lib]]

Even with the library imported :(

@mariciv
Copy link

mariciv commented Feb 9, 2015

@otozk In xml change com.github.manuelpeinado.toolbartest.ObservableScrollView to com.manuelpeinado.fadingactionbar.view.ObservableScrollView and it should work.

@SultanPro
Copy link

9515-9515/com..apps.material E/AndroidRuntime﹕ FATAL EXCEPTION: main
java.lang.NoSuchMethodError: android.support.v7.widget.Toolbar.setBackground
at fragments.Desc2.updateActionBarTransparency(Desc2.java:75)
at fragments.Desc2.onScroll(Desc2.java:66)
at fragments.Desc2.onCreate(Desc2.java:50)
at android.app.Activity.performCreate(Activity.java:4538)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1071)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2161)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2240)
at android.app.ActivityThread.access$600(ActivityThread.java:139)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1262)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:156)
at android.app.ActivityThread.main(ActivityThread.java:4987)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
at dalvik.system.NativeStart.main(Native Method)

@SultanPro
Copy link

how to use in fragment

@Pirat4e
Copy link

Pirat4e commented Feb 19, 2015

@ramswaroop did you solve it? and how ?

@tibigeorgescu90
Copy link

How can this be used with a stickey view. i.e. Layout format -> toolbar -> picture holder -> Textview -> rest of listview? When the toolbar is fully opaque, continue to scroll textview on top of it, and make it sticky., while the rest of the listview scrolls under the tool bar.

@MichaelEvans
Copy link

@ramswaroop @nathaliepl : is there any way to do it without those kinds of hacks? Seems messy to have to do that.

@jemshit
Copy link

jemshit commented Mar 8, 2015

What is min API supported, 11?

@danielwilson1702
Copy link

Hmm I have quite a complicated list view and can't get this to work (instead of a scroll view), is there any example anywhere?

@AdarshYadav
Copy link

As per my requirement I have to fix a button at the bottom of the screen,which is visible for all the time so I putted it out of scroll-view. But after doing this I found that there is no fading effect only content inside scroll-view is scroll able even header image-view also stops scrolling. Anyone have any idea why it's not working?

@aniruddhasm
Copy link

Thanks @ManuelPeinado with this example.
Here is solution to all your problems.

parallax effect on RecyclerView == https://github.com/kanytu/android-parallax-recyclerview

parallax listview, scrollview and gridview with zoom support == https://github.com/kanytu/android-parallax-listview

@Adnan9011
Copy link

finally i solve this
do this things 😄

  1. Copy Java Code
  2. Copy Xml Layout
  3. replace com.github.manuelpeinado.toolbartest.ObservableScrollView to com.manuelpeinado.fadingactionbar.view.ObservableScrollView
  4. add FadingActionBar library at https://g"ithub.com/ManuelPeinado/
  5. add https://github.com/jgilfelt/SystemBarTint library
  6. copy Style recource
  7. add this for appcompat 22.2 :
    http://stackoverflow.com/questions/29784124/java-lang-illegalargumentexception-appcompat-does-not-support-the-current-theme
  8. enjoy it 😊

@sumitsharmadesi
Copy link

When redirected to next activity and come back header layout becomes invisible. How to solve this ?

@rciovati
Copy link

FYI: It's also possible to use the android.support.v4.widget.NestedScrollView bundled in the support library instead of com.github.manuelpeinado.toolbartest.ObservableScrollView.

@gosuka
Copy link

gosuka commented Dec 2, 2015

I'm having the same issue with @ramswaroop, when I go back, the action opacity doesn't return to normal

@anubhav17
Copy link

@nathaliepl thanks for your help it solved my issue.In parent activity just needed to ad this code

public void onResume(){
    super.onResume();
    updateColor();

}

@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
private void updateColor() {
    toolbarBackgroundDrawable.setAlpha(255); // 0% of transparency
    toolbar.setBackground(toolbarBackgroundDrawable);
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment