「Update」
1、增加动态皮肤加载SDK开发
This commit is contained in:
@@ -0,0 +1,255 @@
|
||||
package com.mogo.skin;
|
||||
|
||||
import android.graphics.Typeface;
|
||||
import android.graphics.drawable.ColorDrawable;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.widget.EditText;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.core.view.ViewCompat;
|
||||
|
||||
import com.mogo.skin.utils.SkinResources;
|
||||
import com.mogo.skin.utils.SkinThemeUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* donghongyu
|
||||
*/
|
||||
public class SkinAttribute {
|
||||
|
||||
private static final List<String> mAttributes = new ArrayList<>();
|
||||
|
||||
static {
|
||||
mAttributes.add("background");
|
||||
mAttributes.add("src");
|
||||
|
||||
mAttributes.add("textColor");
|
||||
mAttributes.add("textColorHint");
|
||||
mAttributes.add("drawableLeft");
|
||||
mAttributes.add("drawableTop");
|
||||
mAttributes.add("drawableRight");
|
||||
mAttributes.add("drawableBottom");
|
||||
|
||||
mAttributes.add("skinTypeface");
|
||||
|
||||
mAttributes.add("text");
|
||||
mAttributes.add("hint");
|
||||
}
|
||||
|
||||
private Typeface typeface;
|
||||
|
||||
private static final String TAG = "SkinAttribute";
|
||||
|
||||
List<SkinView> mSkinViews = new ArrayList<>();
|
||||
|
||||
public SkinAttribute(Typeface typeface) {
|
||||
this.typeface = typeface;
|
||||
}
|
||||
|
||||
public void load(View view, AttributeSet attrs) {
|
||||
List<SkinPair> skinPairs = new ArrayList<>();
|
||||
for (int i = 0; i < attrs.getAttributeCount(); i++) {
|
||||
//获得属性名
|
||||
String attributeName = attrs.getAttributeName(i);
|
||||
//是否符合 需要筛选的属性名
|
||||
if (mAttributes.contains(attributeName)) {
|
||||
String attributeValue = attrs.getAttributeValue(i);
|
||||
//写死了,不管了
|
||||
if (attributeValue.startsWith("#")) {
|
||||
continue;
|
||||
}
|
||||
//资源id
|
||||
int resId = 0;
|
||||
if (attributeValue.startsWith("?")) {
|
||||
//attr Id
|
||||
int attrId = Integer.parseInt(attributeValue.substring(1));
|
||||
//获得 主题 style 中的 对应 attr 的资源id值
|
||||
resId = SkinThemeUtils.getResId(view.getContext(), new int[]{attrId})[0];
|
||||
} else {
|
||||
try {
|
||||
// @12343455332
|
||||
if (isNumeric(attributeValue.substring(1))) {
|
||||
resId = Integer.parseInt(attributeValue.substring(1));
|
||||
}
|
||||
} catch (NumberFormatException e) {
|
||||
// 由于有时候TextView会直接配置文字,而不是用 @string/XXX 所以会导致这里转换异常,车里简单的处理异常跳过即可
|
||||
//e.printStackTrace();
|
||||
}
|
||||
}
|
||||
if (resId != 0) {
|
||||
//可以被替换的属性
|
||||
SkinPair skinPair = new SkinPair(attributeName, resId);
|
||||
skinPairs.add(skinPair);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//将View与之对应的可以动态替换的属性集合 放入 集合中
|
||||
if (!skinPairs.isEmpty() || view instanceof TextView || view instanceof SkinViewSupport) {
|
||||
SkinView skinView = new SkinView(view, skinPairs);
|
||||
skinView.applySkin(typeface);
|
||||
mSkinViews.add(skinView);
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isNumeric(String str) {
|
||||
if (str == null) {
|
||||
return false;
|
||||
}
|
||||
return str.matches("-?\\d+(\\.\\d+)?"); // 匹配整数或小数
|
||||
}
|
||||
|
||||
/**
|
||||
* 换皮肤
|
||||
*/
|
||||
public void applySkin(Typeface typeface) {
|
||||
for (SkinView mSkinView : mSkinViews) {
|
||||
mSkinView.applySkin(typeface);
|
||||
}
|
||||
}
|
||||
|
||||
static class SkinView {
|
||||
|
||||
View view;
|
||||
List<SkinPair> skinPairs;
|
||||
|
||||
public SkinView(View view, List<SkinPair> skinPairs) {
|
||||
this.view = view;
|
||||
this.skinPairs = skinPairs;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param typeface 字体
|
||||
*/
|
||||
public void applySkin(Typeface typeface) {
|
||||
applySkinTypeface(typeface);
|
||||
applySkinViewSupport();
|
||||
for (SkinPair skinPair : skinPairs) {
|
||||
Drawable left = null, top = null, right = null, bottom = null;
|
||||
String textStr;
|
||||
switch (skinPair.attributeName) {
|
||||
case "background":
|
||||
Object background = SkinResources.getInstance().getBackground(skinPair.resId);
|
||||
//Color
|
||||
if (background instanceof Integer) {
|
||||
view.setBackgroundColor((Integer) background);
|
||||
} else {
|
||||
ViewCompat.setBackground(view, (Drawable) background);
|
||||
}
|
||||
break;
|
||||
case "src":
|
||||
background = SkinResources.getInstance().getBackground(skinPair.resId);
|
||||
if (background instanceof Integer) {
|
||||
((ImageView) view).setImageDrawable(new ColorDrawable((Integer) background));
|
||||
} else {
|
||||
((ImageView) view).setImageDrawable((Drawable) background);
|
||||
}
|
||||
break;
|
||||
case "textColor":
|
||||
((TextView) view).setTextColor(SkinResources.getInstance().getColorStateList(skinPair.resId));
|
||||
break;
|
||||
case "textColorHint":
|
||||
((EditText) view).setHintTextColor(SkinResources.getInstance().getColorStateList(skinPair.resId));
|
||||
break;
|
||||
case "drawableLeft":
|
||||
left = SkinResources.getInstance().getDrawable(skinPair.resId);
|
||||
break;
|
||||
case "drawableTop":
|
||||
top = SkinResources.getInstance().getDrawable(skinPair.resId);
|
||||
break;
|
||||
case "drawableRight":
|
||||
right = SkinResources.getInstance().getDrawable(skinPair.resId);
|
||||
break;
|
||||
case "drawableBottom":
|
||||
bottom = SkinResources.getInstance().getDrawable(skinPair.resId);
|
||||
break;
|
||||
case "skinTypeface":
|
||||
Typeface typeface1 = SkinResources.getInstance().getTypeface(skinPair.resId);
|
||||
applySkinTypeface(typeface1);
|
||||
break;
|
||||
case "text":
|
||||
textStr = SkinResources.getInstance().getString(skinPair.resId);
|
||||
applyText(textStr);
|
||||
break;
|
||||
case "hint":
|
||||
textStr = SkinResources.getInstance().getString(skinPair.resId);
|
||||
applyHintText(textStr);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (null != left || null != right || null != top || null != bottom) {
|
||||
((TextView) view).setCompoundDrawablesWithIntrinsicBounds(left, top, right, bottom);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static Handler mHandler = new Handler(Looper.getMainLooper());
|
||||
|
||||
private void applySkinViewSupport() {
|
||||
if (view instanceof SkinViewSupport) {
|
||||
((SkinViewSupport) view).applySkin();
|
||||
}
|
||||
}
|
||||
|
||||
private void applySkinTypeface(final Typeface typeface) {
|
||||
if (view instanceof TextView) {
|
||||
Log.d(TAG, "applySkinTypeface() called with: view = [" + ((TextView) view).getText() + "] Parent = " + view.getParent());
|
||||
//post 防止某些控件的属性设置是在构造函数调用完成之后进行的。
|
||||
mHandler.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
((TextView) view).setTypeface(typeface);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void applyText(final String textStr) {
|
||||
if (view instanceof TextView) {
|
||||
Log.d(TAG, "applyText() called with: view = [" + ((TextView) view).getText() + "] Parent = " + view.getParent());
|
||||
//post 防止某些控件的属性设置是在构造函数调用完成之后进行的。
|
||||
mHandler.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
((TextView) view).setText(textStr);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void applyHintText(final String textStr) {
|
||||
if (view instanceof EditText) {
|
||||
Log.d(TAG, "applyHintText() called with: view = [" + ((TextView) view).getText() + "] Parent = " + view.getParent());
|
||||
//post 防止某些控件的属性设置是在构造函数调用完成之后进行的。
|
||||
mHandler.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
((EditText) view).setHint(textStr);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static class SkinPair {
|
||||
|
||||
String attributeName;
|
||||
int resId;
|
||||
|
||||
public SkinPair(String attributeName, int resId) {
|
||||
this.attributeName = attributeName;
|
||||
this.resId = resId;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user