Created
March 9, 2019 02:49
-
-
Save bmc08gt/40a151e93969f2633b9b92bca4b31e83 to your computer and use it in GitHub Desktop.
Toolbar subclass to allow custom gravity and coloring for various elements
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
/** | |
* Created by bmcansh on 3/3/17. | |
*/ | |
public class Toolbar extends android.support.v7.widget.Toolbar { | |
private String mGraphikRegular; | |
private String mGraphikLight; | |
private ActionMenuView mActionMenuView; | |
private ImageButton mNavigationIcon; | |
private TextView mTitle; | |
private TextView mSubtitle; | |
private HashMap<Element, Integer> gravityMap; | |
private HashMap<Element, Integer> colorMap; | |
private List<ActionMenuItemView> mMenuItems; | |
public enum Element { | |
Title, | |
Subtitle, | |
Overflow | |
} | |
public Toolbar(Context context) { | |
this(context, null); | |
} | |
public Toolbar(Context context, @Nullable AttributeSet attrs) { | |
this(context, attrs, android.support.v7.appcompat.R.attr.toolbarStyle); | |
} | |
public Toolbar(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { | |
super(context, attrs, defStyleAttr); | |
init(); | |
} | |
private void init() { | |
mGraphikRegular = TypefaceAdapter.GRAPHIK_MEDIUM; | |
mGraphikLight = TypefaceAdapter.GRAPHIK_REGULAR; | |
gravityMap = new HashMap<>(); | |
colorMap = new HashMap<>(); | |
colorMap.put(Element.Title, ContextCompat.getColor(getContext(), android.R.color.white)); | |
colorMap.put(Element.Subtitle, ContextCompat.getColor(getContext(), android.R.color.white)); | |
colorMap.put(Element.Overflow, ContextCompat.getColor(getContext(), android.R.color.white)); | |
} | |
private void locateTitle(CharSequence title) { | |
mTitle = null; | |
for (int i = 0; i < getChildCount(); ++i) { | |
View child = getChildAt(i); | |
// assuming that the title is the first instance of TextView | |
// you can also check if the title string matches | |
if (child instanceof TextView) { | |
if (((TextView) child).getText().equals(title)) { | |
mTitle = (TextView) child; | |
gravityMap.put(Element.Title, mTitle.getGravity()); | |
break; | |
} | |
} | |
} | |
} | |
private void locateSubtitle(CharSequence title) { | |
mSubtitle = null; | |
for (int i = 0; i < getChildCount(); ++i) { | |
View child = getChildAt(i); | |
// assuming that the title is the first instance of TextView | |
// you can also check if the title string matches | |
if (child instanceof TextView) { | |
if (((TextView) child).getText().equals(title)) { | |
mSubtitle = (TextView) child; | |
gravityMap.put(Element.Subtitle, mSubtitle.getGravity()); | |
break; | |
} | |
} | |
} | |
} | |
public void locateMenu() { | |
mMenuItems = new ArrayList<>(); | |
for (int i = 0; i < getChildCount(); ++i) { | |
View child = getChildAt(i); | |
if (child instanceof ActionMenuView) { | |
mActionMenuView = (ActionMenuView) child; | |
// All menu items | |
for (int j = 0; j < mActionMenuView.getChildCount(); j++) { | |
View c = mActionMenuView.getChildAt(j); | |
if (c instanceof ActionMenuItemView) { | |
ActionMenuItemView itemView = (ActionMenuItemView) c; | |
mMenuItems.add(itemView); | |
} | |
} | |
} | |
} | |
} | |
private void locateNavigationIcon() { | |
mNavigationIcon = null; | |
for (int i = 0; i < getChildCount(); ++i) { | |
View child = getChildAt(i); | |
// assuming that the title is the first instance of TextView | |
// you can also check if the title string matches | |
if (child instanceof ImageButton) { | |
mNavigationIcon = (ImageButton) child; | |
} | |
} | |
} | |
private TextView getElement(Element element) { | |
switch (element) { | |
case Title: | |
return mTitle; | |
case Subtitle: | |
return mSubtitle; | |
default: | |
return null; | |
} | |
} | |
public void setGravityForElement(Element element, int gravity) { | |
TextView tv = getElement(element); | |
if (tv != null) { | |
setGravity(tv, gravity); | |
gravityMap.put(element, gravity); | |
} else { | |
if (element == Element.Overflow) { | |
if (mMenuItems != null) { | |
StreamSupport.stream(mMenuItems) | |
.forEach(t -> setGravity(t, gravity)); | |
} | |
} | |
} | |
} | |
@Override | |
protected void onLayout(boolean changed, int l, int t, int r, int b) { | |
super.onLayout(changed, l, t, r, b); | |
if (android.os.Build.VERSION.SDK_INT == Build.VERSION_CODES.KITKAT){ | |
this.setLayoutParams(new AppBarLayout.LayoutParams( | |
AppBarLayout.LayoutParams.MATCH_PARENT, | |
AppBarLayout.LayoutParams.WRAP_CONTENT)); | |
int dp = (int) (8 * (getResources().getDisplayMetrics().density) + 0.5f); | |
this.setPadding(0,0,0,dp); | |
} | |
TextView title = getElement(Element.Title); | |
if (title != null && gravityMap.get(Element.Title) == Gravity.CENTER_HORIZONTAL) { | |
title.setX((getWidth() - title.getWidth()) / 2); | |
} | |
TextView subtitle = getElement(Element.Subtitle); | |
if (subtitle != null && gravityMap.get(Element.Subtitle) == Gravity.CENTER_HORIZONTAL) { | |
subtitle.setX((getWidth() - subtitle.getWidth()) / 2); | |
} | |
} | |
private void setGravity(TextView tv, int gravity) { | |
tv.setGravity(gravity); | |
requestLayout(); | |
} | |
public void setTextSizeForElement(Element element, int sp) { | |
TextView tv = getElement(element); | |
if (tv != null) { | |
setTextSize(tv, sp); | |
} else { | |
if (element == Element.Overflow) { | |
if (mMenuItems != null) { | |
StreamSupport.stream(mMenuItems) | |
.forEach(t -> setTextSize(t, sp)); | |
} | |
} | |
} | |
} | |
private void setTextSize(TextView tv, int sp) { | |
tv.setTextSize(sp); | |
} | |
public void setTypefaceForElement(Element element, String fontName) { | |
TextView tv = getElement(element); | |
if (tv != null) { | |
setTypeface(tv, fontName); | |
} else { | |
if (element == Element.Overflow) { | |
if (mMenuItems != null) { | |
StreamSupport.stream(mMenuItems) | |
.forEach(t -> setTypeface(t, fontName)); | |
} | |
} | |
} | |
} | |
private void setTypeface(TextView tv, String typeface) { | |
TypefaceAdapter.setFont(tv, typeface); | |
} | |
public void setTextColorForElement(Element element, int color) { | |
TextView tv = getElement(element); | |
colorMap.put(element, color); | |
if (tv != null) { | |
setTextColor(tv, color); | |
} else { | |
if (element == Element.Overflow) { | |
if (mMenuItems != null) { | |
StreamSupport.stream(mMenuItems) | |
.forEach(t -> setTextColor(t, color)); | |
} | |
} | |
} | |
} | |
private void setTextColor(TextView textView, int color) { | |
textView.setTextColor(color); | |
} | |
public void setEllipsizeForElement(Element element, TextUtils.TruncateAt where) { | |
TextView tv = getElement(element); | |
if (tv != null) { | |
tv.setEllipsize(where); | |
} | |
} | |
public void setMaxLinesForElement(Element element, int maxLines) { | |
TextView tv = getElement(element); | |
if (tv != null) { | |
tv.setMaxLines(maxLines); | |
tv.setSingleLine(maxLines == 1); | |
} | |
} | |
public void setPaddingOnElement(Element element, Integer left, Integer top, | |
Integer right, Integer bottom) { | |
TextView tv = getElement(element); | |
if (tv != null) { | |
tv.setPadding(left == null ? tv.getPaddingLeft() : left, | |
top == null ? tv.getPaddingTop() : top, | |
right == null ? tv.getPaddingRight() : right, | |
bottom == null ? tv.getPaddingBottom() : bottom); | |
} | |
} | |
@Override | |
public void setTitle(@StringRes int resId) { | |
super.setTitle(resId); | |
locateNavigationIcon(); | |
locateTitle(getContext().getString(resId)); | |
setTypefaceForElement(Element.Title, mGraphikLight); | |
setTextColorForElement(Element.Title, colorMap.get(Element.Title)); | |
super.setTitle(resId); | |
} | |
@Override | |
public void setTitle(CharSequence title) { | |
super.setTitle(title); | |
locateNavigationIcon(); | |
locateTitle(title); | |
setTypefaceForElement(Element.Title, mGraphikLight); | |
setTextColorForElement(Element.Title, colorMap.get(Element.Title)); | |
super.setTitle(title); | |
} | |
@Override | |
public void setSubtitle(@StringRes int resId) { | |
super.setSubtitle(resId); | |
locateNavigationIcon(); | |
locateSubtitle(getContext().getString(resId)); | |
setTypefaceForElement(Element.Subtitle, mGraphikLight); | |
setTextSizeForElement(Element.Subtitle, 14); | |
setTextColorForElement(Element.Subtitle, colorMap.get(Element.Subtitle)); | |
super.setSubtitle(resId); | |
} | |
@Override | |
public void setSubtitle(CharSequence subtitle) { | |
super.setSubtitle(subtitle); | |
locateNavigationIcon(); | |
locateSubtitle(subtitle); | |
setTypefaceForElement(Element.Subtitle, mGraphikLight); | |
setTextSizeForElement(Element.Subtitle, 14); | |
setTextColorForElement(Element.Subtitle, colorMap.get(Element.Subtitle)); | |
super.setSubtitle(subtitle); | |
} | |
@Override | |
public void inflateMenu(@MenuRes int resId) { | |
super.inflateMenu(resId); | |
locateMenu(); | |
setTypefaceForElement(Element.Overflow, mGraphikLight); | |
setTextColorForElement(Element.Overflow, colorMap.get(Element.Overflow)); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment