供参考
import android.content.Context;
import android.content.SharedPreferences;
import android.content.res.ColorStateList;
import android.graphics.Color;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.util.ArrayMap;
import android.util.AttributeSet;
import android.util.Log;
import android.view.*;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.SearchView;
import androidx.appcompat.widget.Toolbar;
import androidx.core.content.ContextCompat;
import androidx.fragment.app.FragmentActivity;
import androidx.recyclerview.widget.RecyclerView;
import androidx.viewbinding.ViewBinding;
import com.bumptech.glide.Glide;
import com.fast_gathering.Util.StatusBarUtil;
import com.fast_gathering.app.BindingActivity;
import com.fast_gathering.plugin.app.Activity;
import com.google.android.material.appbar.AppBarLayout;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.File;
import java.lang.reflect.Constructor;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import static android.content.Context.MODE_PRIVATE;
public class SkinFactoryLayoutInflaterFactory implements LayoutInflater.Factory {
private AppCompatActivity activity;
public SkinFactoryLayoutInflaterFactory(AppCompatActivity activity) {
this.activity = activity;
}
// 默认前缀包名列表
private static final String[] sClassPrefixList = {"android.widget.", "android.view.", "android.webkit."};
private static final Object[] mConstructorArgs = new Object[2];
private static final Map<String, Constructor<? extends View>> sConstructorMap = new ArrayMap<>();
private static final Class<?>[] sConstructorSignature = new Class[]{Context.class, AttributeSet.class};
private final List<skin> viewList = new ArrayList<>();
class skin {
private Context context;
private AttributeSet attrs;
private String name;
private View view;
public Context getContext() {
return context;
}
public void setContext(Context context) {
this.context = context;
}
public AttributeSet getAttrs() {
return attrs;
}
public void setAttrs(AttributeSet attrs) {
this.attrs = attrs;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public View getView() {
return view;
}
public void setView(View view) {
this.view = view;
}
}
@Nullable
@Override
public View onCreateView(@NonNull String name, @NonNull Context context, @NonNull AttributeSet attrs) {
View view = createViewFromTag(context, name, attrs);
if (view instanceof AppBarLayout) {
try {
initSkin(context, view, name, attrs);
} catch (JSONException e) {
e.printStackTrace();
}
}
if (IsSkin(attrs)) {
//需要更换主题
try {
initSkin(context, view, name, attrs);
skin skin = new skin();
skin.setContext(context);
skin.setAttrs(attrs);
skin.setView(view);
skin.setName(name);
viewList.add(skin);
} catch (JSONException e) {
e.printStackTrace();
}
}
return view;
}
/**
* 重新初始化
*/
public void initSkin() {
for (skin view : viewList) {
try {
if (view.view != null) {
initSkin(view.context, view.view, view.name, view.attrs);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}
private void initSkin(Context context, View view, String name, AttributeSet attributeSet) throws JSONException {
int skin_type = getSkin(attributeSet);
SharedPreferences theme = context.getSharedPreferences("set_Themes", MODE_PRIVATE);
String json = theme.getString("json", getSkin().toString());
JSONObject jsonObject = new JSONObject(json);
//状态栏字体颜色
if (!jsonObject.isNull("mode") && activity != null) {
int mode = jsonObject.getInt("mode");
if (mode == 0) {
StatusBarUtil.setLightMode(activity);
} else {
StatusBarUtil.setDarkMode(activity);
}
}
if (!jsonObject.isNull("StatusBar") && activity != null) {
JSONObject StatusBar = jsonObject.getJSONObject("StatusBar");
String color = StatusBar.getString("Color");
StatusBarUtil.setColor(activity, Color.parseColor(color), 0);
}
if (!jsonObject.isNull(name)) {
JSONObject value = jsonObject.getJSONObject(name);
if (name.equals("androidx.appcompat.widget.Toolbar")) {
Toolbar toolbar = (Toolbar) view;
String Tint = value.getString("Tint");
String TitleColor = value.getString("TitleColor");
String background = value.getString("Background");
toolbar.setTitleTextColor(Color.parseColor(TitleColor));
if (toolbar.getNavigationIcon() != null) {
toolbar.getNavigationIcon().setTint(Color.parseColor(Tint));
}
if (background.startsWith("#")) {
toolbar.setBackgroundColor(Color.parseColor(background));
} else {
File file = context.getDir("Skin", MODE_PRIVATE);
File file1 = new File(file, "themes");
toolbar.setBackground(BitmapDrawable.createFromPath(new File(file1, background).getAbsolutePath()));
}
if (toolbar.getMenu() != null) {
String type = value.getString("Menu");
if (type.equals("menu_white")) {
toolbar.setPopupTheme(R.style.menu_white);
} else if (type.equals("menu_black")) {
toolbar.setPopupTheme(R.style.menu_black);
}
}
}
if (name.equals("Toolbar")) {
android.widget.Toolbar toolbar = (android.widget.Toolbar) view;
toolbar.setFitsSystemWindows(true);
String Tint = value.getString("Tint");
String TitleColor = value.getString("TitleColor");
String background = value.getString("Background");
toolbar.setTitleTextColor(Color.parseColor(TitleColor));
if (toolbar.getNavigationIcon() != null) {
Log.d("颜色", TitleColor);
toolbar.getNavigationIcon().setTint(Color.parseColor(Tint));
}
toolbar.setBackgroundColor(Color.parseColor(background));
if (toolbar.getMenu() != null) {
String type = value.getString("Menu");
if (type.equals("menu_white")) {
toolbar.setPopupTheme(R.style.menu_white);
} else if (type.equals("menu_black")) {
toolbar.setPopupTheme(R.style.menu_black);
}
}
}
if (name.equals("RelativeLayout")) {
String background = value.getString("Background");
view.setBackgroundColor(Color.parseColor(background));
}
if (name.equals("ImageButton")) {
ImageButton imageButton = (ImageButton) view;
String Tint = value.getString("Tint");
imageButton.setImageTintList(ColorStateList.valueOf(Color.parseColor(Tint)));
}
if (name.equals("TextView")) {
TextView textView = (TextView) view;
String color;
if (skin_type == 1) {
color = value.getString("TextColor1");
} else {
color = value.getString("TextColor");
}
textView.setTextColor(Color.parseColor(color));
}
if (name.equals("androidx.appcompat.widget.SearchView")) {
SearchView searchView = (SearchView) view;
String tint = value.getString("Tint");
ImageView search_close_btn = searchView.findViewById(androidx.appcompat.R.id.search_close_btn);
ImageView search_go_btn = searchView.findViewById(androidx.appcompat.R.id.search_go_btn);
ImageView button = searchView.findViewById(androidx.appcompat.R.id.search_button);
ImageView search_mag_icon = searchView.findViewById(androidx.appcompat.R.id.search_mag_icon);
//ImageView search_edit_frame = searchView.findViewById(androidx.appcompat.R.id.search_edit_frame);
//ImageView search_plate=searchView.findViewById(androidx.appcompat.R.id.search_plate);
if (button.getDrawable() != null) {
button.getDrawable().setTint(Color.parseColor(tint));
}
if (search_mag_icon != null) {
search_mag_icon.setImageTintList(ColorStateList.valueOf(Color.parseColor(tint)));
}
search_go_btn.setImageTintList(ColorStateList.valueOf(Color.parseColor(tint)));
search_close_btn.setImageTintList(ColorStateList.valueOf(Color.parseColor(tint)));
button.setImageTintList(ColorStateList.valueOf(Color.parseColor(tint)));
}
if (name.equals("com.google.android.material.appbar.AppBarLayout")) {
String background = value.getString("Background");
AppBarLayout appBarLayout = (AppBarLayout) view;
appBarLayout.setFitsSystemWindows(true);
appBarLayout.setBackgroundColor(Color.parseColor(background));
}
if (name.equals("androidx.recyclerview.widget.RecyclerView")) {
String background = value.getString("Background");
RecyclerView recyclerView = (RecyclerView) view;
if (recyclerView.getBackground() != null) {
recyclerView.getBackground().setTint(Color.parseColor(background));
}
}
}
}
public static JSONObject getSkin() {
try {
JSONObject attributeSet = new JSONObject();
attributeSet.put("mode", 0);
attributeSet.put("themes_id", 0);
attributeSet.put("name", "默认主题");
attributeSet.put("color", "#FFFFFF");
attributeSet.put("introduce", "极致简约的白色");
JSONObject StatusBar = new JSONObject();
StatusBar.put("Color", "#FFFFFF");
attributeSet.put("StatusBar", StatusBar);
JSONObject RecyclerView = new JSONObject();
RecyclerView.put("Background", "#FFFFFF");
attributeSet.put("androidx.recyclerview.widget.RecyclerView", RecyclerView);
JSONObject TextView = new JSONObject();
TextView.put("TextColor", "#000000");
TextView.put("TextColor1", "#997F7F7F");
attributeSet.put("TextView", TextView);
JSONObject SearchView = new JSONObject();
SearchView.put("Tint", "#000000");
attributeSet.put("androidx.appcompat.widget.SearchView", SearchView);
JSONObject RelativeLayout = new JSONObject();
RelativeLayout.put("Background", "#FFFFFF");
attributeSet.put("RelativeLayout", RelativeLayout);
JSONObject toolbar = new JSONObject();
toolbar.put("Menu", "menu_white");
toolbar.put("Background", "#FFFFFF");
toolbar.put("TitleColor", "#000000");
toolbar.put("Tint", "#000000");
attributeSet.put("androidx.appcompat.widget.Toolbar", toolbar);
attributeSet.put("Toolbar", toolbar);
JSONObject ImageButton = new JSONObject();
ImageButton.put("Tint", "#000000");
attributeSet.put("ImageButton", ImageButton);
JSONObject AppBarLayout = new JSONObject();
AppBarLayout.put("Background", "#FFFFFF");
attributeSet.put("com.google.android.material.appbar.AppBarLayout", AppBarLayout);
return attributeSet;
} catch (Exception e) {
e.printStackTrace();
}
return new JSONObject();
}
/**
* 返回需要设置的类型
*
* @param attrs 数据
* @return 默认0
*/
private int getSkin(AttributeSet attrs) {
//获取AttributeSet中所有的XML属性的数量
int count = attrs.getAttributeCount();
//遍历AttributeSet中的XML属性
for (int i = 0; i < count; i++) {
String attributeName = attrs.getAttributeName(i);
if (attributeName.equals("skin")) {
//获取attr的资源ID
return attrs.getAttributeIntValue(i, 0);
}
}
return 0;
}
/**
* @param attrs 数据
* @return 判断是否需要更换主题
*/
private boolean IsSkin(AttributeSet attrs) {
//获取AttributeSet中所有的XML属性的数量
int count = attrs.getAttributeCount();
//遍历AttributeSet中的XML属性
for (int i = 0; i < count; i++) {
//获取attr的资源ID
String attributeName = attrs.getAttributeName(i);
if (attributeName.equals("is_skin")) {
return true;
}
}
return false;
}
/**
* copy android.support.v7.app.AppcompatViewInflater #createViewFromTag()
*
* @param context
* @param name
* @param attrs
* @return
*/
public static View createViewFromTag(Context context, String name, AttributeSet attrs) {
if (name.equals("view")) {
name = attrs.getAttributeValue(null, "class");
}
try {
mConstructorArgs[0] = context;
mConstructorArgs[1] = attrs;
if (-1 == name.indexOf('.')) {
for (int i = 0; i < sClassPrefixList.length; i++) {
final View view = createView(context, name, sClassPrefixList[i]);
if (view != null) {
return view;
}
}
return null;
} else {
return createView(context, name, null);
}
} catch (Exception e) {
// We do not want to catch these, lets return null and let the actual LayoutInflater
// try
return null;
} finally {
// Don't retain references on context.
mConstructorArgs[0] = null;
mConstructorArgs[1] = null;
}
}
/**
* 创建view
*
* @param context
* @param name
* @param prefix
* @return
* @throws InflateException
*/
private static View createView(Context context, String name, String prefix) throws InflateException {
Constructor<? extends View> constructor = sConstructorMap.get(name);
try {
if (constructor == null) {
// Class not found in the cache, see if it's real, and try to add it
Class<? extends View> clazz = context.getClassLoader().loadClass(prefix != null ? (prefix + name) : name).asSubclass(View.class);
constructor = clazz.getConstructor(sConstructorSignature);
sConstructorMap.put(name, constructor);
}
constructor.setAccessible(true);
return constructor.newInstance(mConstructorArgs);
} catch (Exception e) {
// We do not want to catch these, lets return null and let the actual LayoutInflater
// try
return null;
}
}
}