Skip to content

Commit

Permalink
Add support for navigation menu item view
Browse files Browse the repository at this point in the history
Use dynamic background view to tint dividers.
  • Loading branch information
pranavpandey committed Apr 24, 2021
1 parent b46ca09 commit cc7cb4f
Show file tree
Hide file tree
Showing 14 changed files with 1,226 additions and 39 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,11 @@ public class Defaults {
*/
public static final int ADS_COLOR_TYPE_ICON = ADS_COLOR_TYPE_SCROLLABLE;

/**
* Default color type for the divider.
*/
public static final int ADS_COLOR_TYPE_DIVIDER = Theme.ColorType.TINT_BACKGROUND;

/**
* Default value to make widgets background aware so that they can change color according
* to the theme background to provide best visibility.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -617,6 +617,50 @@ public static <T> void tintBackground(@Nullable T dynamic) {
tintBackground(dynamic, DynamicTheme.getInstance().getDefaultContrastWith());
}

/**
* Tint foreground according to the supplied contrast with color.
*
* @param dynamic The dynamic object to be tinted.
* @param contrastWithColor The contrast with color to be considered.
* @param borderless {@code true} if the view is borderless.
* @param <T> The type of the dynamic object.
*
* @see DynamicTintUtils#setViewForegroundTint(View, int, boolean)
*/
public static <T> void tintForeground(@Nullable T dynamic,
@ColorInt int contrastWithColor, boolean borderless) {
if (contrastWithColor == Theme.Color.UNKNOWN) {
return;
}

if (dynamic instanceof View && (dynamic instanceof Button
|| ((View) dynamic).isClickable() || ((View) dynamic).isLongClickable())) {
DynamicTintUtils.setViewForegroundTint((View) dynamic,
contrastWithColor, borderless);
}
}

/**
* Tint foreground according to the supplied contrast with color.
*
* @param dynamic The dynamic object to be tinted.
* @param contrastWithColor The contrast with color to be considered.
* @param <T> The type of the dynamic object.
*
* @see DynamicTintUtils#setViewForegroundTint(View, int, boolean)
*/
public static <T> void tintForeground(@Nullable T dynamic, @ColorInt int contrastWithColor) {
if (contrastWithColor == Theme.Color.UNKNOWN) {
return;
}

if (dynamic instanceof View && (dynamic instanceof Button
|| ((View) dynamic).isClickable() || ((View) dynamic).isLongClickable())) {
DynamicTintUtils.setViewForegroundTint((View) dynamic,
contrastWithColor, true);
}
}

/**
* Tint scrollable according to the supplied contrast with color.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import com.pranavpandey.android.dynamic.support.theme.DynamicTheme;
import com.pranavpandey.android.dynamic.support.utils.DynamicResourceUtils;
import com.pranavpandey.android.dynamic.support.widget.DynamicAppBarLayout;
import com.pranavpandey.android.dynamic.support.widget.DynamicBackgroundView;
import com.pranavpandey.android.dynamic.support.widget.DynamicBottomAppBar;
import com.pranavpandey.android.dynamic.support.widget.DynamicBottomNavigationView;
import com.pranavpandey.android.dynamic.support.widget.DynamicButton;
Expand All @@ -39,14 +40,17 @@
import com.pranavpandey.android.dynamic.support.widget.DynamicEditText;
import com.pranavpandey.android.dynamic.support.widget.DynamicExtendedFloatingActionButton;
import com.pranavpandey.android.dynamic.support.widget.DynamicFloatingActionButton;
import com.pranavpandey.android.dynamic.support.widget.DynamicForegroundLinearLayout;
import com.pranavpandey.android.dynamic.support.widget.DynamicFrameLayout;
import com.pranavpandey.android.dynamic.support.widget.DynamicGridView;
import com.pranavpandey.android.dynamic.support.widget.DynamicHorizontalScrollView;
import com.pranavpandey.android.dynamic.support.widget.DynamicImageButton;
import com.pranavpandey.android.dynamic.support.widget.DynamicImageView;
import com.pranavpandey.android.dynamic.support.widget.DynamicLinearLayout;
import com.pranavpandey.android.dynamic.support.widget.DynamicLinearLayoutCompat;
import com.pranavpandey.android.dynamic.support.widget.DynamicListView;
import com.pranavpandey.android.dynamic.support.widget.DynamicMaterialCardView;
import com.pranavpandey.android.dynamic.support.widget.DynamicNavigationMenuItemView;
import com.pranavpandey.android.dynamic.support.widget.DynamicNavigationView;
import com.pranavpandey.android.dynamic.support.widget.DynamicNestedScrollView;
import com.pranavpandey.android.dynamic.support.widget.DynamicProgressBar;
Expand Down Expand Up @@ -88,6 +92,9 @@ public class DynamicLayoutInflater implements LayoutInflater.Factory2 {
View view = null;

switch (name) {
case "View":
view = new DynamicBackgroundView(context, attrs);
break;
case "ListMenuItemView":
case "com.android.internal.view.menu.ListMenuItemView":
case "android.support.v7.view.menu.ListMenuItemView":
Expand Down Expand Up @@ -192,6 +199,16 @@ public class DynamicLayoutInflater implements LayoutInflater.Factory2 {
case "com.pranavpandey.android.dynamic.support.widget.DynamicLinearLayout":
view = new DynamicLinearLayout(context, attrs);
break;
case "android.support.v7.widget.LinearLayoutCompat":
case "androidx.appcompat.widget.LinearLayoutCompat":
case "com.pranavpandey.android.dynamic.support.widget.DynamicLinearLayoutCompat":
view = new DynamicLinearLayoutCompat(context, attrs);
break;
case "android.support.design.internal.ForegroundLinearLayout":
case "com.google.android.material.internal.ForegroundLinearLayout":
case "com.pranavpandey.android.dynamic.support.widget.DynamicForegroundLinearLayout":
view = new DynamicForegroundLinearLayout(context, attrs);
break;
case "RelativeLayout":
case "com.pranavpandey.android.dynamic.support.widget.DynamicRelativeLayout":
view = new DynamicRelativeLayout(context, attrs);
Expand Down Expand Up @@ -257,6 +274,11 @@ public class DynamicLayoutInflater implements LayoutInflater.Factory2 {
case "com.pranavpandey.android.dynamic.support.widget.DynamicNavigationView":
view = new DynamicNavigationView(context, attrs);
break;
case "android.support.design.internal.NavigationMenuItemView":
case "com.google.android.material.internal.NavigationMenuItemView":
case "com.pranavpandey.android.dynamic.support.widget.DynamicNavigationMenuItemView":
view = new DynamicNavigationMenuItemView(context, attrs);
break;
case "android.support.design.widget.BottomNavigationView":
case "com.google.android.material.bottomnavigation.BottomNavigationView":
case "com.pranavpandey.android.dynamic.support.widget.DynamicBottomNavigationView":
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.PorterDuff;
import android.util.AttributeSet;
import android.view.View;

Expand All @@ -31,15 +30,17 @@
import com.pranavpandey.android.dynamic.support.Dynamic;
import com.pranavpandey.android.dynamic.support.R;
import com.pranavpandey.android.dynamic.support.theme.DynamicTheme;
import com.pranavpandey.android.dynamic.support.utils.DynamicResourceUtils;
import com.pranavpandey.android.dynamic.support.widget.base.DynamicTintWidget;
import com.pranavpandey.android.dynamic.support.widget.base.DynamicWidget;
import com.pranavpandey.android.dynamic.theme.Theme;
import com.pranavpandey.android.dynamic.utils.DynamicColorUtils;
import com.pranavpandey.android.dynamic.utils.DynamicDrawableUtils;

/**
* An {@link View} to apply {@link DynamicTheme} according to the supplied parameters.
* A {@link View} to apply {@link DynamicTheme} according to the supplied parameters.
*/
public class DynamicBackgroundView extends View implements DynamicWidget {
public class DynamicBackgroundView extends View implements DynamicWidget, DynamicTintWidget {

/**
* Color type applied to this view.
Expand Down Expand Up @@ -84,6 +85,21 @@ public class DynamicBackgroundView extends View implements DynamicWidget {
*/
private @Theme.BackgroundAware int mBackgroundAware;

/**
* {@code true} to tint background according to the widget color.
*/
private boolean mTintBackground;

/**
* {@code true} if the style applied to this view is borderless.
*/
private boolean mStyleBorderless;

/**
* Original background attribute resource.
*/
private @AttrRes int mBackgroundAttrRes;

public DynamicBackgroundView(@NonNull Context context) {
this(context, null);
}
Expand All @@ -101,15 +117,6 @@ public DynamicBackgroundView(@NonNull Context context,
loadFromAttributes(attrs);
}

/**
* Returns the filter mode to be used to tint this view.
*
* @return The filter mode to be used to tint this view.
*/
public PorterDuff.Mode getFilterMode() {
return PorterDuff.Mode.SRC_IN;
}

@Override
public void loadFromAttributes(@Nullable AttributeSet attrs) {
TypedArray a = getContext().obtainStyledAttributes(attrs,
Expand All @@ -131,11 +138,16 @@ public void loadFromAttributes(@Nullable AttributeSet attrs) {
mBackgroundAware = a.getInteger(
R.styleable.DynamicBackgroundView_ads_backgroundAware,
Defaults.getBackgroundAware());

if (mColorType == Theme.ColorType.NONE && mColor == Theme.Color.UNKNOWN) {
if (getId() == R.id.submenuarrow) {
mColorType = Defaults.ADS_COLOR_TYPE_SYSTEM_SECONDARY;
}
mTintBackground = a.getBoolean(
R.styleable.DynamicBackgroundView_ads_tintBackground,
Defaults.ADS_TINT_BACKGROUND);
mStyleBorderless = a.getBoolean(
R.styleable.DynamicBackgroundView_ads_styleBorderless,
Defaults.ADS_STYLE_BORDERLESS_GROUP);

if (attrs != null) {
mBackgroundAttrRes = DynamicResourceUtils.getResourceIdFromAttributes(
getContext(), attrs, android.R.attr.background);
}
} finally {
a.recycle();
Expand All @@ -146,6 +158,29 @@ public void loadFromAttributes(@Nullable AttributeSet attrs) {

@Override
public void initialize() {
if (mColorType == Theme.ColorType.NONE) {
if (mBackgroundAttrRes == DynamicResourceUtils.getResourceId(
getContext(), android.R.attr.divider)
|| mBackgroundAttrRes == DynamicResourceUtils.getResourceId(
getContext(), androidx.appcompat.R.attr.divider)
|| mBackgroundAttrRes == DynamicResourceUtils.getResourceId(
getContext(), android.R.attr.listDivider)
|| mBackgroundAttrRes == DynamicResourceUtils.getResourceId(
getContext(), android.R.attr.listDividerAlertDialog)
|| mBackgroundAttrRes == DynamicResourceUtils.getResourceId(
getContext(), androidx.appcompat.R.attr.listDividerAlertDialog)
|| mBackgroundAttrRes == DynamicResourceUtils.getResourceId(
getContext(), android.R.attr.dividerHorizontal)
|| mBackgroundAttrRes == DynamicResourceUtils.getResourceId(
getContext(), androidx.appcompat.R.attr.dividerHorizontal)
|| mBackgroundAttrRes == DynamicResourceUtils.getResourceId(
getContext(), android.R.attr.dividerVertical)
|| mBackgroundAttrRes == DynamicResourceUtils.getResourceId(
getContext(), androidx.appcompat.R.attr.dividerVertical)) {
mColorType = Defaults.ADS_COLOR_TYPE_DIVIDER;
}
}

if (mColorType != Theme.ColorType.NONE
&& mColorType != Theme.ColorType.CUSTOM) {
mColor = DynamicTheme.getInstance().resolveColorType(mColorType);
Expand Down Expand Up @@ -236,7 +271,63 @@ public void setBackgroundAware(@Theme.BackgroundAware int backgroundAware) {
public void setEnabled(boolean enabled) {
super.setEnabled(enabled);

setAlpha(enabled ? Defaults.ADS_ALPHA_ENABLED : Defaults.ADS_ALPHA_DISABLED);
if (mColorType != Theme.ColorType.NONE) {
setAlpha(enabled ? Defaults.ADS_ALPHA_ENABLED : Defaults.ADS_ALPHA_DISABLED);
} else {
setAlpha(Defaults.ADS_ALPHA_ENABLED);
}
}

@Override
public void setClickable(boolean clickable) {
super.setClickable(clickable);

setColor();
}

@Override
public void setOnClickListener(@Nullable OnClickListener l) {
super.setOnClickListener(l);

setColor();
}

@Override
public void setLongClickable(boolean longClickable) {
super.setLongClickable(longClickable);

setColor();
}

@Override
public void setOnLongClickListener(@Nullable OnLongClickListener l) {
super.setOnLongClickListener(l);

setColor();
}

@Override
public boolean isTintBackground() {
return mTintBackground;
}

@Override
public void setTintBackground(boolean tintBackground) {
this.mTintBackground = tintBackground;

setColor();
}

@Override
public boolean isStyleBorderless() {
return mStyleBorderless;
}

@Override
public void setStyleBorderless(boolean styleBorderless) {
this.mStyleBorderless = styleBorderless;

setColor();
}

@Override
Expand All @@ -246,12 +337,14 @@ public void setColor() {
if (isBackgroundAware() && mContrastWithColor != Theme.Color.UNKNOWN) {
mAppliedColor = DynamicColorUtils.getContrastColor(mColor, mContrastWithColor);
}

DynamicDrawableUtils.colorizeDrawable(getBackground(), mAppliedColor);
}

if (mColorType == Theme.ColorType.NONE && getBackground() != null) {
if (getBackground() != null) {
getBackground().clearColorFilter();

if (isTintBackground() && mAppliedColor != Theme.Color.UNKNOWN) {
DynamicDrawableUtils.colorizeDrawable(getBackground(), mAppliedColor);
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.pranavpandey.android.dynamic.support.Defaults;
import com.pranavpandey.android.dynamic.support.theme.DynamicTheme;
import com.pranavpandey.android.dynamic.theme.Theme;
import com.pranavpandey.android.dynamic.utils.DynamicDrawableUtils;
Expand Down Expand Up @@ -51,7 +52,7 @@ public void loadFromAttributes(@Nullable AttributeSet attrs) {

if (getColorType() == Theme.ColorType.NONE
&& getColor(false) == Theme.Color.UNKNOWN) {
setColorType(Theme.ColorType.TINT_BACKGROUND);
setColorType(Defaults.ADS_COLOR_TYPE_DIVIDER);
}
}

Expand Down

0 comments on commit cc7cb4f

Please sign in to comment.