Last active
August 21, 2019 12:03
-
-
Save tobiasschuerg/9186a955ae8e11366701a24f1a447af9 to your computer and use it in GitHub Desktop.
Activity which let's you easily color toolbar, its back button and overflow menu items
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import android.annotation.SuppressLint; | |
import android.content.res.Resources; | |
import android.content.res.TypedArray; | |
import android.graphics.Color; | |
import android.graphics.PorterDuff; | |
import android.graphics.drawable.Drawable; | |
import android.os.Build; | |
import android.os.Bundle; | |
import android.support.annotation.ColorInt; | |
import android.support.annotation.NonNull; | |
import android.support.annotation.Nullable; | |
import android.support.design.widget.AppBarLayout; | |
import android.support.design.widget.CollapsingToolbarLayout; | |
import android.support.v4.content.ContextCompat; | |
import android.support.v7.app.ActionBar; | |
import android.support.v7.app.AppCompatActivity; | |
import android.support.v7.widget.AppCompatImageView; | |
import android.support.v7.widget.AppCompatTextView; | |
import android.support.v7.widget.Toolbar; | |
import android.text.SpannableString; | |
import android.text.style.ForegroundColorSpan; | |
import android.view.Gravity; | |
import android.view.Menu; | |
import android.view.MenuItem; | |
import android.view.View; | |
import android.view.ViewGroup; | |
import android.view.ViewTreeObserver; | |
import android.view.Window; | |
import android.view.WindowManager; | |
import android.widget.LinearLayout; | |
import java.util.ArrayList; | |
/** | |
* {@link android.app.Activity} which supports quick and easy customizations. | |
* <p> | |
* Needs a {@link Toolbar} and optionally a {@link CollapsingToolbarLayout} | |
* <p> | |
* Created by Tobias Schürg on 14.11.2016. | |
*/ | |
public abstract class EasyColorableActivity extends AppCompatActivity { | |
private Toolbar toolbar; | |
@Nullable private CollapsingToolbarLayout collapsingToolbarLayout; | |
@Nullable private AppBarLayout appbarLayout; | |
private Integer foregroundColor; | |
@Override | |
protected void onPostCreate(@Nullable Bundle savedInstanceState) { | |
super.onPostCreate(savedInstanceState); | |
getTopView(); // make sure view is set up correctly | |
} | |
@NonNull | |
private View getTopView() { | |
if (toolbar != null) { | |
return toolbar; | |
} else if (collapsingToolbarLayout != null) { | |
return collapsingToolbarLayout; | |
} else { | |
throw new NullPointerException( | |
"No toolbar set! Call setToolbar(toolbar) or setToolbar(collapsingToolbarLayout) during onCreate"); | |
} | |
} | |
/** | |
* For the use with just a 'simple' {@link Toolbar} | |
*/ | |
protected void setToolbar(@NonNull Toolbar toolbar) { | |
setToolbar(toolbar, null, null); | |
} | |
/** | |
* For the use with a collapsing toolbar. | |
*/ | |
protected void setToolbar(@NonNull Toolbar toolbar, CollapsingToolbarLayout collapsingToolbarLayout, AppBarLayout appBarLayout) { | |
this.toolbar = toolbar; | |
this.collapsingToolbarLayout = collapsingToolbarLayout; | |
this.appbarLayout = appBarLayout; | |
} | |
protected void setBarBackgroundColor(@ColorInt int color) { | |
// status bar | |
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { | |
Window window = getWindow(); | |
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS); | |
window.setStatusBarColor(ColorHelper.darken(color)); | |
} | |
// actionbar | |
if (appbarLayout != null) { | |
appbarLayout.setBackgroundColor(color); | |
} else { | |
toolbar.setBackgroundColor(color); | |
} | |
setSupportActionBar(toolbar); | |
ActionBar actionbar = getSupportActionBar(); | |
if (actionbar != null) { | |
actionbar.setHomeButtonEnabled(true); | |
actionbar.setDisplayHomeAsUpEnabled(true); | |
} | |
} | |
@SuppressLint("PrivateResource") | |
protected void setBarForegroundColor(@ColorInt int color) { | |
foregroundColor = color; | |
if (collapsingToolbarLayout != null) { | |
collapsingToolbarLayout.setCollapsedTitleTextColor(color); | |
} else if (toolbar != null) { | |
toolbar.setTitleTextColor(color); | |
} | |
ActionBar actionbar = getSupportActionBar(); | |
if (actionbar != null) { | |
Drawable upArrow = ContextCompat.getDrawable(this, android.support.v7.appcompat.R.drawable.abc_ic_ab_back_material); | |
upArrow.setColorFilter(color, PorterDuff.Mode.SRC_ATOP); | |
actionbar.setHomeAsUpIndicator(upArrow); | |
} | |
setOverflowButtonColor(color); | |
} | |
@Override | |
public boolean onCreateOptionsMenu(Menu menu) { | |
for (int i = 0; i < menu.size(); i++) { | |
final MenuItem item = menu.getItem(i); | |
final CharSequence itemTitle = item.getTitle(); | |
SpannableString s = new SpannableString(itemTitle); | |
s.setSpan(new ForegroundColorSpan(Color.DKGRAY), 0, s.length(), 0); | |
item.setTitle(s); | |
AppCompatTextView tv = new AppCompatTextView(getApplicationContext()); | |
LinearLayout.LayoutParams params = new LinearLayout | |
.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, | |
LinearLayout.LayoutParams.MATCH_PARENT, | |
1f); | |
tv.setPadding(dpToPx(8), 0, dpToPx(8), 0); | |
tv.setLayoutParams(params); | |
tv.setGravity(Gravity.CENTER); | |
tv.setText(itemTitle.toString()); | |
tv.setTextAppearance(this, android.R.style.TextAppearance_DeviceDefault_Widget_ActionBar_Menu); | |
tv.setTextColor(foregroundColor); | |
tv.setOnClickListener(new View.OnClickListener() { | |
@Override | |
public void onClick(View v) { | |
onOptionsItemSelected(item); | |
} | |
}); | |
addRippleEffect(tv); | |
item.setActionView(tv); | |
} | |
return super.onCreateOptionsMenu(menu); | |
} | |
private void addRippleEffect(View view) { | |
int[] attrs = new int[]{R.attr.selectableItemBackgroundBorderless}; | |
TypedArray typedArray = obtainStyledAttributes(attrs); | |
Drawable drawable = typedArray.getDrawable(0); | |
view.setBackground(drawable); | |
typedArray.recycle(); | |
view.setClickable(true); | |
view.setFocusable(true); | |
} | |
/** | |
* Changes the color of the overflow dots. | |
* Great cinema ^^ | |
* Based on http://stackoverflow.com/a/36278375/570168 | |
*/ | |
public void setOverflowButtonColor(final int color) { | |
@SuppressLint("PrivateResource") final String overflowDescription = getString(R.string.abc_action_menu_overflow_description); | |
final ViewGroup decorView = (ViewGroup) getWindow().getDecorView(); | |
final ViewTreeObserver viewTreeObserver = decorView.getViewTreeObserver(); | |
viewTreeObserver.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { | |
@Override | |
public void onGlobalLayout() { | |
final ArrayList<View> outViews = new ArrayList<>(); | |
decorView.findViewsWithText(outViews, overflowDescription, View.FIND_VIEWS_WITH_CONTENT_DESCRIPTION); | |
if (outViews.isEmpty()) { | |
return; | |
} | |
for (View outView : outViews) { | |
AppCompatImageView overflow = (AppCompatImageView) outView; | |
overflow.setColorFilter(color); | |
} | |
} | |
}); | |
} | |
public static int dpToPx(int dp) { | |
return (int) (dp * Resources.getSystem().getDisplayMetrics().density); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment