MDXDave.de

IT-Freelancer // Android + Coding

Laden...

Fading ActionBar

veröffentlicht vor 9 Jahren, am 24. November 2014  |  Android    Entwicklung    XML    Java      |  0 Kommentare

Im PlayStore gibt es seit einigen Versionen die FadingActionBar, also das einblenden der ActionBar beim Scrollen:

Genau diese ActionBar möchten wir nachbauen. Im Prinzip geht das ziemlich einfach. Am Ende dieses kleinen Tutorials, soll das ganze so aussehen:

Da unser gesamter Inhalt innerhalb einer ScrollView liegt, können wir später statt dem Foto auch andere Elemente platzieren, zur Demonstration eignet sich das Foto meiner Meinung nach aber am Besten. Aufgrund der Aktualität verwenden wir das MaterialDesign, daher die Support v7-Library und Toolbar.

Los geht's!

Wir erstellen zunächst ein neues Projekt in Android Studio (Leeres Projekt, minSDK: 14).

Als nächstes ändern wir unsere Datei activity_main.xml folgendermaßen ab:

<FrameLayout
 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">
 <de.mdxdave.fadingactionbar.ScrollViewHelper
 android:id="@+id/scrollViewHelper"
 android:layout_width="match_parent"
 android:layout_height="wrap_content">
 <LinearLayout
 android:orientation="vertical" 
 android:layout_width="match_parent" 
 android:layout_height="wrap_content">
 <ImageView
 android:layout_width="match_parent"
 android:layout_height="300dp"
 android:src="@drawable/background"
 android:scaletype="centerCrop" />
 <TextView
 android:layout_width="match_parent"
 android:layout_height="wrap_content"
 android:padding="16dp"
 android:text="@string/lorem_ipsum" />
 </LinearLayout>
 </de.mdxdave.fadingactionbar.ScrollViewHelper>
 <android.support.v7.widget.Toolbar
 android:id="@+id/toolbar" 
 android:layout_width="match_parent" 
 android:layout_height="wrap_content" 
 app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" 
 android:minheight="?attr/actionBarSize" 
 android:background="?attr/colorPrimary">
 </android.support.v7.widget.Toolbar>
</FrameLayout>

Ein FrameLayout benötigen wir, damit unsere Toolbar über dem Foto liegt. Wie ihr vermutlich seht, ist oben keine normale ScrollView eingebunden, sondern eine Benutzerdefinierte. Wieso dies so ist, im nächsten Schritt. Sonst haben wir noch ein Foto und darunter ein TextView, hier könnt ihr aber letztlich platzieren was ihr wollt.

Als nächstes dann die Klasse ScrollViewHelper.java:

package de.mdxdave.fadingactionbar;
import android.content.Context;
import android.util.AttributeSet;
import android.widget.ScrollView;
public class ScrollViewHelper extends ScrollView {
 private OnScrollViewListener mOnScrollViewListener;
 public ScrollViewHelper(Context context) {
 super(context);
 }
 public ScrollViewHelper(Context context, AttributeSet attrs) {
 super(context, attrs);
 }
 public ScrollViewHelper(Context context, AttributeSet attrs, int defStyle) {
 super(context, attrs, defStyle);
 }
 public interface OnScrollViewListener {
 void onScrollChanged(ScrollViewHelper v, int l, int t, int oldl, int oldt );
 }
 public void setOnScrollViewListener(OnScrollViewListener l) {
 this.mOnScrollViewListener = l;
 }
 protected void onScrollChanged(int l, int t, int oldl, int oldt) {
 mOnScrollViewListener.onScrollChanged( this, l, t, oldl, oldt );
 super.onScrollChanged( l, t, oldl, oldt );
 }
}

Diese benötigen wir, um unsere ScrollPosition später abzufangen, damit wir die Toolbar/ActionBar je nach Position der ScrollView ein- oder ausblenden können.

Um den Titel der Toolbar/ActionBar ebenfalls faden zu können, benötigen wir eine weitere Helfer-Klasse, AlphaForeGroundColorSpan.java:

package de.mdxdave.fadingactionbar;
import android.graphics.Color;
import android.text.TextPaint;
import android.text.style.ForegroundColorSpan;
public class AlphaForeGroundColorSpan extends ForegroundColorSpan {
private float mAlpha;
 public AlphaForeGroundColorSpan(int color) {
 super(color);
 }
 @Override
 public void updateDrawState(TextPaint textPaint) {
 textPaint.setColor(getAlphaColor());
 }
 public void setAlpha(float alpha) {
 mAlpha = alpha;
 }
 private int getAlphaColor() {
 int foregroundColor = getForegroundColor();
 return Color.argb((int) (mAlpha * 255), Color.red(foregroundColor), Color.green(foregroundColor), Color.blue(foregroundColor));
 }
}

So, als nächstes geht's an unsere MainActivity.java:

Und hier passiert letztlich die ganze Magie. Als erstes suchen wir unsere Toolbar und legen diese als ActionBar fest:

Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);

Anschließend erstellen wir ein ColorDrawable-Objekt aus unsere primären Farbe und machen dieses unsichtbar (Alpha 0):

final ColorDrawable cd = new ColorDrawable(getResources().getColor(R.color.colorPrimary));
cd.setAlpha(0);

Als nächstes modifizieren wir unsere ActionBar mit unserer ColorDrawable-Objekt und leeren den Titel:

ActionBar actionBar = getSupportActionBar();
actionBar.setDisplayHomeAsUpEnabled(true);
actionBar.setTitle("");
actionBar.setBackgroundDrawable(cd);

Nun benötigen wir unseren ScrollViewHelper, welchen wir oben angelegt haben:

ScrollViewHelper scrollViewHelper = (ScrollViewHelper)findViewById(R.id.scrollViewHelper);
scrollViewHelper.setOnScrollViewListener(new ScrollViewHelper.OnScrollViewListener() {
 @Override
 public void onScrollChanged(ScrollViewHelper v, int l, int t, int oldl, int oldt) {
 setTitleAlpha(255 - getAlphaforActionBar(v.getScrollY()));
 cd.setAlpha(getAlphaforActionBar(v.getScrollY()));
 }
 private int getAlphaforActionBar(int scrollY) {
 int minDist = 0, maxDist = 550;
 if(scrollY>maxDist){
 return 255; 
 } else {
 if (scrollY < minDist) {
 return 0;
 } else {
 return (int) ((255.0 / maxDist) * scrollY);
 }
 }
 }
});

Was macht unser Code? Zunächst einmal wird die Methode setTitleAlpha aufgerufen (die wir gleich definieren), des weiteren wird der Alpha-Wert (Transparenz) für unsere ActionBar berechnet und gesetzt (0 = unsichtbar, 255 = sichtbar), Mithilfe der Variable int maxDist können wir festlegen, wie viele Pixel gescrollt werden soll, bis die ActionBar einen Alpha-Wert von 255 hat, sprich 100% sichtbar und solide ist.

Um den Titel der ActionBar (folgendes funktioniert auch mit dem SubTitle-Attribut) ebenfalls zu faden, müssen wir zunächst zwei globale Variablen festlegen:

private AlphaForeGroundColorSpan mAlphaForegroundColorSpan;
private SpannableString mSpannableString;

und diese in der onCreate()-Methode deklarieren:

mSpannableString = new SpannableString("Dies ist ein Test");
mAlphaForegroundColorSpan = new AlphaForeGroundColorSpan(0xFFFFFF);

Wobei 0xFFFFFF hier für die Schriftfarbe Weiß steht (Hex: #FFFFFF).

Als letztes benötigen wir noch unsere Methode setTitleAlpha():

private void setTitleAlpha(float alpha) {
 if(alpha<1){ alpha = 1; }
 mAlphaForegroundColorSpan.setAlpha(alpha);
 mSpannableString.setSpan(mAlphaForegroundColorSpan, 0, mSpannableString.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
 getSupportActionBar().setTitle(mSpannableString);
}

Nun solltet ihr das Projekt erzeugen - und die App auf eurem Smartphone oder Emulator starten können.

Bei Fragen und/oder Problemen, könnt ihr gerne einen Kommentar hinterlassen.

Den gesamten Quellcode gibts auf GitHub.com.

Demnächst veröffentliche ich noch ein Tutorial in welchem ihr statt der ScrollView einen ParallaxScroll-Effekt nutzen könnt und ab Android KitKat (4.4.4) auch die StatusBar gefärbt werden kann.

Links: Kompletter Code auf Github | Material Design für Pre-Lollipop-Geräte (Informationen) | Material Design Richtlinien