'Material3 MaterialToolbar disable coloring at scroll
I am migrating my app to Theme.Material3.* and found that the MaterialToolbar is now being highlighted in some accent color as soon as some content scrolls underneath it. See the animation that I'm referring to below:
However, I don't want this effect to be present within my application. But while reading through the MaterialToolbar documentation, it seems like there is no way to disable or modify it, which irritates me. What am I missing here?
The minimal XML layout to reproduce the behaviour (as well as using a Material3 theme):
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context=".MainActivity">
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:liftOnScroll="true">
<com.google.android.material.appbar.MaterialToolbar
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:titleCentered="true"
app:title="Welcome"
app:layout_scrollFlags="noScroll" />
</com.google.android.material.appbar.AppBarLayout>
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Lorem ipsum dolor sit amet..." />
</androidx.core.widget.NestedScrollView>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
Thanks for your help.
Solution 1:[1]
So, after playing around a while, I'm going to share my findings.
The background color animation takes place at scrolling only when the attribute app:liftOnScroll is set to true in the AppBarLayout.
<com.google.android.material.appbar.AppBarLayout
android:id="@+id/primaryAppbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:liftOnScroll="true">
<com.google.android.material.appbar.MaterialToolbar
android:id="@+id/primaryToolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize" />
</com.google.android.material.appbar.AppBarLayout>
When setting app:liftOnScroll="false", the Toolbar will permanently show the highlight color. This then can be changed by setting the android:background attribute.
In case you have a Layout containing two AppBars, and you want both to show the animation at scrolling, you can synchronize them by calling addLiftOnScrollListener like so:
primaryAppbar.addLiftOnScrollListener(new AppBarLayout.LiftOnScrollListener() {
@Override
public void onUpdate(float elevation, int backgroundColor) {
secondaryAppbar.setElevation(elevation);
secondaryAppbar.setBackgroundColor(backgroundColor);
}
});
In this case, primaryAppbar is the one receiving the scroll events.
Solution 2:[2]
You can add a style for toolbar.
<com.google.android.material.appbar.MaterialToolbar
android:id="@+id/toolbar"
style="@style/Widget.Material3.Toolbar.Surface"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:layout_scrollFlags="noScroll"/>
Solution 3:[3]
words[Math.floor(Math.random() * (words.length - 1))];
I think you need to use like this.
because Math.floor(Math.random() * words.length - 5) can be less than 0
Solution 4:[4]
You may consider : 1) building an array of indexes from 0 to words.length, 2) picking a random index 3) getting a word using the random index (the word will be random) 4) deleting the random index to avoid repetitions. This way, you no dot not need to delete your words and your random index will always be valid.
//----------New code-----------------
var indexes = []
for (let i=0; i<words.length; i++) {
indexes.push(i)
}
//-----------------------------------
playBtn.addEventListener("click", function() {
//get a random index value
let randomIndex = Math.floor((Math.random()*words.length))
//Get your randomword here, using the random index
var randomWord = words[randomIndex];
//Delete the index so it will not repeat
indexes.splice(randomIndex,1)
//This is your code below
audio.src = randomWord.sound;
audio.play();
//var name = words.splice(randomWord,1); // delete this!
words.push(name); // just added >> is this required?
})
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | BenjyTec |
| Solution 2 | Sever |
| Solution 3 | Wang YinXing |
| Solution 4 |

