「Update」

1、增加isUseSkin属性,来针对性的开启换肤,防止大面积误伤其它View。原因是很多数据、图片都是动态设置的。会把设置的数据冲掉;
This commit is contained in:
donghongyu
2024-10-25 17:47:31 +08:00
parent 2ccbe54756
commit cb397d919a
7 changed files with 43 additions and 18 deletions

View File

@@ -86,11 +86,17 @@ public class MainActivity extends AppCompatActivity {
Skin skin; Skin skin;
if (isCheck) { if (isCheck) {
skin = new Skin( skin = new Skin(
"88a7b397d6a03966aa332aea17f5210a", "ee3e1b0ed6e33a51366949294b07787d",
"YiXin-skin_v1_2024_10_24.apk", "YiXin-skin_v1_2024_10_25.zip",
"https://carlife-static-1255510688.cos.ap-beijing.myqcloud.com/MoGoEagleEye/YiXin-skin_v1_2024_10_24.apk" "https://carlife-static-1255510688.cos.ap-beijing.myqcloud.com/MoGoEagleEye/YiXin-skin_v1_2024_10_25.zip"
); );
// skin = new Skin(
// "a841e8819f06cfefa646f7adc697e070",
// "DeQing-skin_v1_2024_10_25.apk",
// "https://carlife-static-1255510688.cos.ap-beijing.myqcloud.com/MoGoEagleEye/DeQing-skin_v1_2024_10_25.apk"
// );
//换肤 //换肤
SkinManager.getInstance().downloadSkin(this, skin, new SkinManager.SkinLoadListener() { SkinManager.getInstance().downloadSkin(this, skin, new SkinManager.SkinLoadListener() {
@Override @Override

View File

@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android" <ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
@@ -14,12 +15,14 @@
android:id="@+id/bGConstraintLayout" android:id="@+id/bGConstraintLayout"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:background="@drawable/icon_notice_default"> android:background="@drawable/icon_notice_default"
app:isUseSkin="true">
<com.mogo.skin.widget.SkinImageView <com.mogo.skin.widget.SkinImageView
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:src="@drawable/icon_notice_default" /> android:src="@drawable/icon_notice_default"
app:isUseSkin="true" />
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -58,4 +58,4 @@ MOGO_TELEMATIC_VERSION=1.4.7.42
# v2x # v2x
MOGO_V2X_VERSION=1.4.7.42 MOGO_V2X_VERSION=1.4.7.42
# SKIN # SKIN
MOGO_SKIN_VERSION=1.4.7.49.14-debug MOGO_SKIN_VERSION=1.4.7.49.18-debug

View File

@@ -1,8 +1,8 @@
package com.mogo.skin; package com.mogo.skin;
import android.util.AttributeSet; import android.util.AttributeSet;
import android.util.Log;
import android.view.View; import android.view.View;
import android.widget.TextView;
import com.mogo.skin.utils.SkinThemeUtils; import com.mogo.skin.utils.SkinThemeUtils;
@@ -30,6 +30,8 @@ public class SkinAttribute {
mAttributes.add("skinTypeface"); mAttributes.add("skinTypeface");
mAttributes.add("isUseSkin");
mAttributes.add("text"); mAttributes.add("text");
mAttributes.add("hint"); mAttributes.add("hint");
} }
@@ -48,14 +50,18 @@ public class SkinAttribute {
* 记录View中哪几个属性需要换肤,找到当前页面的所有属性 * 记录View中哪几个属性需要换肤,找到当前页面的所有属性
*/ */
public void load(View view, AttributeSet attrs) { public void load(View view, AttributeSet attrs) {
// 记录View是否配置了isUseSkin属性
boolean isUseSkin = false;
List<SkinPair> skinPairs = new ArrayList<>(); List<SkinPair> skinPairs = new ArrayList<>();
for (int i = 0; i < attrs.getAttributeCount(); i++) { for (int i = 0; i < attrs.getAttributeCount(); i++) {
//获得属性名 //获得属性名
String attributeName = attrs.getAttributeName(i); String attributeName = attrs.getAttributeName(i);
// 筛选配置了换肤属性的View防止因为换肤导致。动态控制了状态的View被还原的问题 // 筛选配置了换肤属性的View防止因为换肤导致。动态控制了状态的View被还原的问题
if (attributeName.equals("isUseSkin")) {
isUseSkin = true;
}
//是否符合 需要筛选的属性名 //是否符合 需要筛选的属性名
if (mAttributes.contains(attributeName)) { else if (mAttributes.contains(attributeName)) {
//属性名写法 //属性名写法
//#ffff //#ffff
//?attr/xxx //?attr/xxx
@@ -95,13 +101,16 @@ public class SkinAttribute {
} }
//将View与之对应的可以动态替换的属性集合 放入 集合中 //将View与之对应的可以动态替换的属性集合 放入 集合中
if (!skinPairs.isEmpty() || view instanceof TextView || view instanceof SkinViewSupport) { if (isUseSkin) {
Log.d(TAG, "View 开启了换肤……isUseSkin");
if (!skinPairs.isEmpty() || view instanceof SkinViewSupport) {
//选择皮肤 更新 //选择皮肤 更新
SkinView skinView = new SkinView(view, skinPairs); SkinView skinView = new SkinView(view, skinPairs);
skinView.applySkin(); skinView.applySkin();
mSkinViews.add(skinView); mSkinViews.add(skinView);
} }
} }
}
public static boolean isNumeric(String str) { public static boolean isNumeric(String str) {
if (str == null) { if (str == null) {

View File

@@ -180,7 +180,8 @@ public class SkinManager extends Observable {
//下载成功将皮肤包信息insert已下载数据库 //下载成功将皮肤包信息insert已下载数据库
Log.e(TAG, "DownloadManager 皮肤包下载完成开始校验"); Log.e(TAG, "DownloadManager 皮肤包下载完成开始校验");
//皮肤包的md5校验 防止下载文件损坏(但是会减慢速度。从数据库查询已下载皮肤表数据库中保留md5字段) //皮肤包的md5校验 防止下载文件损坏(但是会减慢速度。从数据库查询已下载皮肤表数据库中保留md5字段)
if (TextUtils.equals(SkinUtils.getSkinMD5(skinFile), skin.md5)) { String localSkinFileMd5 = SkinUtils.getSkinMD5(skinFile);
if (TextUtils.equals(localSkinFileMd5, skin.md5)) {
Log.d(TAG, "DownloadManager 校验成功,修改文件名。"); Log.d(TAG, "DownloadManager 校验成功,修改文件名。");
// 加载指定皮肤包 // 加载指定皮肤包
SkinManager.getInstance().loadSkin(skin.getPathLocal()); SkinManager.getInstance().loadSkin(skin.getPathLocal());
@@ -191,8 +192,8 @@ public class SkinManager extends Observable {
} else { } else {
// 回调给使用方成功 // 回调给使用方成功
skinLoadListener.onLoadFailed(new Exception("皮肤文件校验出错,本地文件MD5 与云端文件MD5 不一致。")); skinLoadListener.onLoadFailed(new Exception("皮肤文件校验出错,本地文件MD5 与云端文件MD5 不一致。"));
Log.e(TAG, "DownloadManager 皮肤文件校验出错,本地文件MD5 与云端文件MD5 不一致。"); Log.e(TAG, "DownloadManager 皮肤文件校验出错,本地文件 MD5 = " + localSkinFileMd5 + " 与云端文件 MD5 = " + skin.md5 + " 不一致。");
Toast.makeText(mApplication, "皮肤文件校验出错,本地文件MD5 与云端文件MD5 不一致。", Toast.LENGTH_SHORT).show(); Toast.makeText(mApplication, "皮肤文件校验出错,本地文件 MD5 = " + localSkinFileMd5 + " 与云端文件 MD5 = " + skin.md5 + " 不一致。", Toast.LENGTH_LONG).show();
// TODO 删除本地皮肤文件并重新下载这个操作比较危险需要严格保证配置文件中的md5与实际皮肤包一致否则将是灾难 // TODO 删除本地皮肤文件并重新下载这个操作比较危险需要严格保证配置文件中的md5与实际皮肤包一致否则将是灾难
} }
} catch (Exception e) { } catch (Exception e) {

View File

@@ -8,6 +8,7 @@ import java.io.FileOutputStream;
import java.io.InputStream; import java.io.InputStream;
import java.io.OutputStream; import java.io.OutputStream;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.util.Arrays;
public class FileUtils { public class FileUtils {
private static final String TAG = "FileUtils"; private static final String TAG = "FileUtils";
@@ -48,9 +49,11 @@ public class FileUtils {
* @param fields 获取raw文件夹的资源ID * @param fields 获取raw文件夹的资源ID
*/ */
public static void copyVideoRawToFile(Context context, Field[] fields) { public static void copyVideoRawToFile(Context context, Field[] fields) {
Log.i(TAG, "File copyVideoRawToFile " + Arrays.toString(fields));
for (Field field : fields) {// 将资源文件的名称添加到列表中 for (Field field : fields) {// 将资源文件的名称添加到列表中
// 过滤名称带有Video的Raw文件到指定目录 // 过滤名称带有Video的Raw文件到指定目录
if (field.getName().startsWith("video_")) { if (field.getName().startsWith("video_")) {
Log.i(TAG, "File copyVideoRawToFile field = " + field.getName());
copyVideoRawToFile(SkinResources.getInstance().getIdentifier(field.getName(), "raw"), copyVideoRawToFile(SkinResources.getInstance().getIdentifier(field.getName(), "raw"),
getExternalAppDirectory(context).getAbsolutePath() + "/raw/"); getExternalAppDirectory(context).getAbsolutePath() + "/raw/");
} }
@@ -72,6 +75,7 @@ public class FileUtils {
// 创建目标文件夹 // 创建目标文件夹
File targetDirectory = new File(targetPath); File targetDirectory = new File(targetPath);
if (!targetDirectory.exists()) { if (!targetDirectory.exists()) {
Log.i(TAG, "File mkdirs path = " + targetDirectory);
targetDirectory.mkdirs(); targetDirectory.mkdirs();
} }

View File

@@ -1,4 +1,6 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources> <resources>
<attr name="skinTypeface" format="string" /> <attr name="skinTypeface" format="string" />
<!--防止大面积误伤原生View这里做一个手动开启换肤的开关来控制是否要在这个控件上使用-->
<attr name="isUseSkin" format="boolean" />
</resources> </resources>