1 Android 动态式换肤框架1-setContentView源码分析:
https://blog.csdn.net/hongxue8888/article/details/95494195
2 Android 动态式换肤框架2-实现背景替换:
https://blog.csdn.net/hongxue8888/article/details/95390639
3 Android 动态式换肤框架3-Fragment、状态栏换肤
https://blog.csdn.net/hongxue8888/article/details/96310094
1 自定义实现SkinViewSupport接口
public interface SkinViewSupport {
void applySkin();
}
所有需要换肤的自定义View都需要实现SkinViewSupport接口。
2 app的资源和布局
自定义一个CircleView实现SkinViewSupport接口。
在attrs.xml文件中添加自定义属性:
<resources>
<declare-styleable name="CircleView">
<attr name="corcleColor" format="color"/>
</declare-styleable>
</resources>
activity_skin.xml布局文件中:
<com.hongx.skinview.widget.CircleView
android:layout_width="32dp"
android:layout_height="32dp"
android:layout_marginTop="50dp"
app:corcleColor="@color/colorAccent"/>
在color.xml中添加:
<!-- 文字正常主色 -->
<color name="colorAccent">#1f1f1f</color>
3 皮肤包的资源颜色资源
只需在color.xml中添加:
<color name="colorAccent">#ff00ddff</color>
4 CircleView.java
public class CircleView extends View implements SkinViewSupport {
private AttributeSet attrs;
//画笔
private Paint mTextPain;
//半径
private int radius;
private int corcleColorResId;
public CircleView(Context context) {
this(context, null, 0);
}
public CircleView(Context context, @Nullable AttributeSet attrs) {
this(context, attrs, 0);
}
public CircleView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
this.attrs = attrs;
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.CircleView);
corcleColorResId = typedArray.getResourceId(R.styleable.CircleView_corcleColor, 0);//1
typedArray.recycle();
mTextPain = new Paint();
mTextPain.setColor(getResources().getColor(corcleColorResId));
//开启抗锯齿,平滑文字和圆弧的边缘
mTextPain.setAntiAlias(true);
//设置文本位于相对于原点的中间
mTextPain.setTextAlign(Paint.Align.CENTER);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//获取宽度一半
int width = getWidth() / 2;
//获取高度一半
int height = getHeight() / 2;
//设置半径为宽或者高的最小值
radius = Math.min(width, height);
//利用canvas画一个圆
canvas.drawCircle(width, height, radius, mTextPain);
}
public void setCorcleColor(@ColorInt int color) {
mTextPain.setColor(color);
invalidate();
}
@Override
public void applySkin() {//2
if (corcleColorResId != 0) {
int color = SkinResources.getInstance().getColor(corcleColorResId);
setCorcleColor(color);
}
}
}
注释1:获取我们自定义属性的值,这里corcleColorResId = 2131034154,在R.class文件中
public static final int colorAccent = 2131034154;
注释2:使用这个颜色值
5 load方法
在SkinAttribute的load方法中添加如下代码,表明只有view实现了SkinViewSupport接口才去换肤。
if ( view instanceof SkinViewSupport) {
//没有属性满足 但是需要修改字体
SkinView skinView = new SkinView(view, mSkinPars);
skinView.applySkin(typeface);
mSkinViews.add(skinView);
}
6 applySkinSupport方法
在SkinAttribute的内部类SkinView的applySkin方法中调用
//自定义View
private void applySkinSupport() {
if(view instanceof SkinViewSupport){
((SkinViewSupport)view).applySkin();
}
}
skinId = 2130968614,打开皮肤包的R.class文件查看public static final int colorAccent = 2130968614;
效果如下: