「Update」
1、增加isUseSkin属性,来针对性的开启换肤,防止大面积误伤其它View。原因是很多数据、图片都是动态设置的。会把设置的数据冲掉;
This commit is contained in:
@@ -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
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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,11 +101,14 @@ public class SkinAttribute {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//将View与之对应的可以动态替换的属性集合 放入 集合中
|
//将View与之对应的可以动态替换的属性集合 放入 集合中
|
||||||
if (!skinPairs.isEmpty() || view instanceof TextView || view instanceof SkinViewSupport) {
|
if (isUseSkin) {
|
||||||
//选择皮肤 更新
|
Log.d(TAG, "View 开启了换肤……isUseSkin");
|
||||||
SkinView skinView = new SkinView(view, skinPairs);
|
if (!skinPairs.isEmpty() || view instanceof SkinViewSupport) {
|
||||||
skinView.applySkin();
|
//选择皮肤 更新
|
||||||
mSkinViews.add(skinView);
|
SkinView skinView = new SkinView(view, skinPairs);
|
||||||
|
skinView.applySkin();
|
||||||
|
mSkinViews.add(skinView);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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) {
|
||||||
|
|||||||
@@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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>
|
||||||
Reference in New Issue
Block a user