add CompoundButton hook
This commit is contained in:
Binary file not shown.
@@ -0,0 +1,66 @@
|
||||
package com.vk.core.ui;
|
||||
import android.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import androidx.annotation.Nullable;
|
||||
import org.xmlpull.v1.XmlPullParser;
|
||||
import ru.vtosters.lite.themes.ViewInjector;
|
||||
|
||||
public class VKLayoutInflater extends LayoutInflater {
|
||||
|
||||
private final static String[] DEFAULT_PACKAGES = {
|
||||
"android.widget.", "android.webkit.", "android.app."
|
||||
};
|
||||
|
||||
public VKLayoutInflater(LayoutInflater original, Context context) {
|
||||
super(original, context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public LayoutInflater cloneInContext(Context newContext) {
|
||||
return new VKLayoutInflater(this, newContext);
|
||||
}
|
||||
|
||||
public final View createView(View parent, String name, Context context, AttributeSet attrs) {
|
||||
if (!name.startsWith("android.")) {
|
||||
try {
|
||||
return onCreateView(parent, name, attrs);
|
||||
} catch (ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
try {
|
||||
return createView(name, null, attrs);
|
||||
} catch (ClassNotFoundException ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected View onCreateView(String name, AttributeSet attrs) throws ClassNotFoundException {
|
||||
for (var defPackage : DEFAULT_PACKAGES) {
|
||||
try {
|
||||
View view = createView(name, defPackage, attrs);
|
||||
if (view != null) return view;
|
||||
} catch (ClassCastException | ClassNotFoundException ignored) {
|
||||
}
|
||||
}
|
||||
|
||||
return super.onCreateView(name, attrs);
|
||||
}
|
||||
|
||||
@Override
|
||||
public View inflate(int resource, @Nullable ViewGroup root, boolean attachToRoot) {
|
||||
var view = super.inflate(resource, root, attachToRoot);
|
||||
return ViewInjector.inject(view, -1, attachToRoot);
|
||||
}
|
||||
|
||||
@Override
|
||||
public View inflate(XmlPullParser parser, @Nullable ViewGroup root, boolean attachToRoot) {
|
||||
var view = super.inflate(parser, root, attachToRoot);
|
||||
return ViewInjector.inject(view, -1, attachToRoot);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,117 @@
|
||||
package com.vk.core.ui;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.TypedArray;
|
||||
import android.os.Build;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.InflateException;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.webkit.WebView;
|
||||
import android.widget.CheckBox;
|
||||
import android.widget.RadioButton;
|
||||
import android.widget.Switch;
|
||||
import android.widget.TextView;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.app.AppCompatDelegate;
|
||||
import androidx.appcompat.widget.SwitchCompat;
|
||||
import com.vk.core.ui.themes.VKThemeHelper;
|
||||
import com.vk.core.util.OsUtil;
|
||||
import com.vk.core.view.NavigationSpinner;
|
||||
import com.vk.core.view.TextViewColorStateListAndAlphaSupportPreV23;
|
||||
import com.vk.core.view.VKAppBarLayout;
|
||||
|
||||
public class VKUILayoutFactory implements LayoutInflater.Factory2 {
|
||||
|
||||
private final static int[] FONT_ATTR = { android.R.attr.font };
|
||||
private AppCompatDelegate mDelegate;
|
||||
private VKLayoutInflater mInflater;
|
||||
|
||||
public VKUILayoutFactory(AppCompatDelegate delegate, VKLayoutInflater inflater) {
|
||||
mDelegate = delegate;
|
||||
mInflater = inflater;
|
||||
}
|
||||
|
||||
private void setTypeface(TextView textView, Context context, AttributeSet attrs) {
|
||||
TypedArray ta = context.obtainStyledAttributes(attrs, FONT_ATTR, android.R.attr.textViewStyle, 0);
|
||||
if (ta == null) return;
|
||||
Font font = Font.Companion.a(ta.getString(0));
|
||||
if (font != null && Build.VERSION.SDK_INT < font.a())
|
||||
textView.setTypeface(font.c());
|
||||
ta.recycle();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(@Nullable View parent, @NonNull String name, @NonNull Context context, @NonNull AttributeSet attrs) {
|
||||
View view = null;
|
||||
try {
|
||||
if (!(parent instanceof NavigationSpinner) && !OsUtil.b())
|
||||
view = new TextViewColorStateListAndAlphaSupportPreV23(context, attrs, 0);
|
||||
else if (mDelegate != null)
|
||||
view = mDelegate.createView(parent, name, context, attrs);
|
||||
else if (mInflater != null)
|
||||
view = mInflater.createView(parent, name, context, attrs);
|
||||
} catch (Throwable unused) {
|
||||
throw new InflateException(
|
||||
"parent=" + parent.getClass().getName()
|
||||
+ ":" + getResourceIdName(view)
|
||||
+ ", view=" + name
|
||||
+ ":" + getResourceIdName(context, attrs));
|
||||
}
|
||||
if (view == null &&
|
||||
("com.google.android.material.appbar.AppBarLayout".equals(name)
|
||||
|| "android.support.design.widget.AppBarLayout".equals(name)))
|
||||
view = new VKAppBarLayout(context, attrs);
|
||||
|
||||
if (view != null) {
|
||||
if (!(view.getTag() instanceof String)) {
|
||||
if (view instanceof TextView) {
|
||||
setTypeface((TextView) view, context, attrs);
|
||||
if (view instanceof CheckBox)
|
||||
VKThemeHelper.k.a((CheckBox) view);
|
||||
else if (view instanceof RadioButton)
|
||||
VKThemeHelper.k.a((RadioButton) view);
|
||||
else if (view instanceof SwitchCompat)
|
||||
VKThemeHelper.k.a((SwitchCompat) view);
|
||||
else if (view instanceof Switch)
|
||||
VKThemeHelper.k.a((Switch) view);
|
||||
} else if (view instanceof WebView) {
|
||||
VKThemeHelper.a((WebView) view);
|
||||
}
|
||||
VKThemeHelper.k.a(view, attrs);
|
||||
}
|
||||
}
|
||||
|
||||
return view;
|
||||
}
|
||||
|
||||
private String getResourceIdName(View view) {
|
||||
try {
|
||||
if (view != null) {
|
||||
if (view.getId() != -1)
|
||||
return view.getResources().getResourceName(view.getId());
|
||||
return "NO_ID";
|
||||
}
|
||||
return "null";
|
||||
} catch (Throwable unused) {
|
||||
return "FAILED_TO_GET_ID";
|
||||
}
|
||||
}
|
||||
|
||||
private String getResourceIdName(Context context, AttributeSet attrs) {
|
||||
TypedArray ta = context.obtainStyledAttributes(attrs, new int[] { android.R.attr.id });
|
||||
int resId = ta.getResourceId(0, -1);
|
||||
ta.recycle();
|
||||
return resId != -1
|
||||
? context.getResources().getResourceName(resId)
|
||||
: "NO_ID";
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(@NonNull String name, @NonNull Context context, @NonNull AttributeSet attrs) {
|
||||
return onCreateView(null, name, context, attrs);
|
||||
}
|
||||
}
|
||||
@@ -2,18 +2,10 @@ package ru.vtosters.lite.themes;
|
||||
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import ru.vtosters.lite.themes.hooks.*;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import ru.vtosters.lite.themes.hooks.BaseHook;
|
||||
import ru.vtosters.lite.themes.hooks.ButtonHook;
|
||||
import ru.vtosters.lite.themes.hooks.ImageViewHook;
|
||||
import ru.vtosters.lite.themes.hooks.ProgressWheelHook;
|
||||
import ru.vtosters.lite.themes.hooks.TabLayoutHook;
|
||||
import ru.vtosters.lite.themes.hooks.TextViewHook;
|
||||
import ru.vtosters.lite.themes.hooks.ToolbarHook;
|
||||
import ru.vtosters.lite.themes.hooks.VKImageViewHook;
|
||||
|
||||
public class ViewInjector {
|
||||
public static ArrayList<BaseHook> hooks = new ArrayList<>();
|
||||
|
||||
@@ -25,6 +17,7 @@ public class ViewInjector {
|
||||
hooks.add(new ToolbarHook());
|
||||
hooks.add(new VKImageViewHook());
|
||||
hooks.add(new ProgressWheelHook());
|
||||
hooks.add(new CompoundButtonHook());
|
||||
}
|
||||
|
||||
public static View inject(View view, int i, boolean z) {
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
package ru.vtosters.lite.themes.hooks;
|
||||
|
||||
import android.content.res.ColorStateList;
|
||||
import android.view.View;
|
||||
import android.widget.CheckBox;
|
||||
import android.widget.CompoundButton;
|
||||
import android.widget.RadioButton;
|
||||
import android.widget.Switch;
|
||||
import androidx.appcompat.widget.SwitchCompat;
|
||||
import androidx.core.graphics.drawable.DrawableCompat;
|
||||
import androidx.core.widget.CompoundButtonCompat;
|
||||
import com.vk.core.ui.themes.VKThemeHelper;
|
||||
import com.vk.core.util.ColorUtils;
|
||||
import com.vtosters.lite.R;
|
||||
import ru.vtosters.lite.utils.AndroidUtils;
|
||||
import ru.vtosters.lite.utils.ThemesUtils;
|
||||
|
||||
public class CompoundButtonHook implements BaseHook {
|
||||
|
||||
private static final int[][] STATES = new int[][]{
|
||||
{ android.R.attr.state_enabled, -android.R.attr.state_checked },
|
||||
{ -android.R.attr.state_enabled, android.R.attr.state_checked },
|
||||
{ -android.R.attr.state_checked },
|
||||
{ android.R.attr.state_checked }
|
||||
};
|
||||
|
||||
@Override
|
||||
public void inject(View view, int i, boolean z) {
|
||||
if (view instanceof CheckBox || view instanceof RadioButton)
|
||||
recolorCompoundButton((CompoundButton) view);
|
||||
else if (view instanceof Switch)
|
||||
recolorSwitch((Switch) view);
|
||||
else if (view instanceof SwitchCompat)
|
||||
recolorSwitchCompat((SwitchCompat) view);
|
||||
}
|
||||
|
||||
private void recolorCompoundButton(CompoundButton cb) {
|
||||
var colors = new int[] {
|
||||
ColorUtils.b(VKThemeHelper.d(R.attr.selection_off_icon), 0.4F),
|
||||
ColorUtils.b(ThemesUtils.getAccentColor(), 0.4F),
|
||||
VKThemeHelper.d(R.attr.selection_off_icon),
|
||||
ThemesUtils.getAccentColor()
|
||||
};
|
||||
CompoundButtonCompat.setButtonTintList(cb,
|
||||
new ColorStateList(STATES, colors));
|
||||
}
|
||||
|
||||
private int[] getThumbColors() {
|
||||
return new int[] {
|
||||
AndroidUtils.getResources().getColor(
|
||||
ThemesUtils.getCurrentTheme().a() ? R.color.steel_gray_150: R.color.white),
|
||||
AndroidUtils.getResources().getColor(
|
||||
ThemesUtils.getCurrentTheme().a() ? R.color.switch_disabled_on_dark : R.color.switch_disabled_on_light),
|
||||
AndroidUtils.getResources().getColor(R.color.gray_20),
|
||||
VKThemeHelper.d(R.attr.accent)
|
||||
};
|
||||
}
|
||||
|
||||
private int[] getTrackColors() {
|
||||
return new int[] {
|
||||
ColorUtils.b(VKThemeHelper.d(R.attr.loader_track_fill), 0.4F),
|
||||
ColorUtils.b(ThemesUtils.getAccentColor(), 0.12F),
|
||||
VKThemeHelper.d(R.attr.loader_track_fill),
|
||||
ColorUtils.b(ThemesUtils.getAccentColor(), 0.48F)
|
||||
};
|
||||
}
|
||||
|
||||
private void recolorSwitch(Switch s) {
|
||||
DrawableCompat.setTintList(DrawableCompat.wrap(s.getThumbDrawable()), new ColorStateList(STATES, getThumbColors()));
|
||||
DrawableCompat.setTintList(DrawableCompat.wrap(s.getTrackDrawable()), new ColorStateList(STATES, getTrackColors()));
|
||||
}
|
||||
|
||||
private void recolorSwitchCompat(SwitchCompat s) {
|
||||
DrawableCompat.setTintList(DrawableCompat.wrap(s.getThumbDrawable()), new ColorStateList(STATES, getThumbColors()));
|
||||
DrawableCompat.setTintList(DrawableCompat.wrap(s.getTrackDrawable()), new ColorStateList(STATES, getTrackColors()));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user