package com.jaydenxiao.common.daynightmodeutils; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.animation.ValueAnimator; import android.app.Activity; import android.content.Context; import android.content.res.Resources; import android.graphics.Bitmap; import android.graphics.drawable.BitmapDrawable; import android.os.Build; import android.support.v4.view.LayoutInflaterCompat; import android.support.v4.view.LayoutInflaterFactory; import android.util.AttributeSet; import android.util.TypedValue; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.TextView; import com.jaydenxiao.common.R; import java.lang.reflect.Field; import java.util.ArrayList; import java.util.List; /** * 夜间模式控制器 * */ public class ChangeModeController { /** * 属性背景 */ private static final String ATTR_BACKGROUND = "dayNightBackgroundAttr"; /** * 属性背景图片 */ private static final String ATTR_BACKGROUND_DRAWABLE = "dayNightBackgroundDrawableAttr"; /** * 属性一级字体颜色 */ private static final String ATTR_TEXTCOLOR = "dayNightOneTextColorAttr"; /** * 属性二级字体颜色 */ private static final String ATTR_TWO_TEXTCOLOR = "dayNightTwoTextColorAttr"; /** * 属性三级字体颜色 */ private static final String ATTR_THREE_TEXTCOLOR = "dayNightThreeTextColorAttr"; private static List<AttrEntity<View>> mBackGroundViews; private static List<AttrEntity<View>> mBackGroundDrawableViews; private static List<AttrEntity<TextView>> mOneTextColorViews; private static List<AttrEntity<TextView>> mTwoTextColorViews; private static List<AttrEntity<TextView>> mThreeTextColorViews; private static ChangeModeController mChangeModeController; private ChangeModeController(){} public static ChangeModeController getInstance(){ if(mChangeModeController == null){ mChangeModeController = new ChangeModeController(); } return mChangeModeController; } /** * 初始化保存集合 */ private void init(){ mBackGroundViews = new ArrayList<>(); mOneTextColorViews = new ArrayList<>(); mTwoTextColorViews=new ArrayList<>(); mThreeTextColorViews=new ArrayList<>(); mBackGroundDrawableViews = new ArrayList<>(); } /** * 初始化夜间控制器 * @param activity 上下文 * @return */ public ChangeModeController init(final Activity activity,final Class mClass){ init(); LayoutInflaterCompat.setFactory(LayoutInflater.from(activity), new LayoutInflaterFactory() { @Override public View onCreateView(View parent, String name, Context context, AttributeSet attrs) { View view = null; try { if(name.indexOf('.') == -1){ if ("View".equals(name)) { view = LayoutInflater.from(context).createView(name, "android.view.", attrs); } if (view == null) { view = LayoutInflater.from(context).createView(name, "android.widget.", attrs); } if (view == null) { view = LayoutInflater.from(context).createView(name, "android.webkit.", attrs); } }else{ if (view == null){ view = LayoutInflater.from(context).createView(name, null, attrs); } } if(view != null){ // Log.e("TAG", "name = " + name); for (int i = 0; i < attrs.getAttributeCount(); i++) { // Log.e("TAG", attrs.getAttributeName(i) + " , " + attrs.getAttributeValue(i)); if (attrs.getAttributeName(i).equals(ATTR_BACKGROUND)) { mBackGroundViews.add(new AttrEntity<View>(view,getAttr(mClass,attrs.getAttributeValue(i)))); } if (attrs.getAttributeName(i).equals(ATTR_TEXTCOLOR)) { mOneTextColorViews.add(new AttrEntity<TextView>((TextView)view,getAttr(mClass,attrs.getAttributeValue(i)))); } if (attrs.getAttributeName(i).equals(ATTR_TWO_TEXTCOLOR)) { mOneTextColorViews.add(new AttrEntity<TextView>((TextView)view,getAttr(mClass,attrs.getAttributeValue(i)))); } if (attrs.getAttributeName(i).equals(ATTR_THREE_TEXTCOLOR)) { mOneTextColorViews.add(new AttrEntity<TextView>((TextView)view,getAttr(mClass,attrs.getAttributeValue(i)))); } if (attrs.getAttributeName(i).equals(ATTR_BACKGROUND_DRAWABLE)) { mBackGroundDrawableViews.add(new AttrEntity<View>(view,getAttr(mClass,attrs.getAttributeValue(i)))); } } } }catch (Exception e){ e.printStackTrace(); } return view; } }); return this; } /** * 反射获取文件id * @param attrName 属性名称 * @return 属性id */ public static int getAttr(Class draw,String attrName) { if (attrName == null || attrName.trim().equals("") || draw == null) { return R.attr.colorPrimary; } try { Field field = draw.getDeclaredField(attrName); field.setAccessible(true); return field.getInt(attrName); } catch (Exception e) { return R.attr.colorPrimary; } } /** * 设置当前主题 * @param ctx 上下文 * @param Style_Day 白天 * @param Style_Night 夜间 */ public static void setTheme(Context ctx,int Style_Day,int Style_Night){ if(ChangeModeHelper.getChangeMode(ctx) == ChangeModeHelper.MODE_DAY){ ctx.setTheme(Style_Day); }else if(ChangeModeHelper.getChangeMode(ctx) == ChangeModeHelper.MODE_NIGHT){ ctx.setTheme(Style_Night); } } /** * 动态切换主题 */ public static void toggleThemeSetting(Activity ctx) { if(ChangeModeHelper.getChangeMode(ctx) == ChangeModeHelper.MODE_DAY){ changeNight(ctx,R.style.NightTheme); }else if(ChangeModeHelper.getChangeMode(ctx) == ChangeModeHelper.MODE_NIGHT){ changeDay(ctx,R.style.DayTheme); } } /** * * @param ctx 上下文 * @param style 切换style */ public static void changeNight(Activity ctx,int style) { if(mBackGroundDrawableViews == null || mOneTextColorViews == null || mBackGroundViews == null){ throw new RuntimeException("请先调用init()初始化方法!"); } ChangeModeHelper.setChangeMode(ctx, ChangeModeHelper.MODE_NIGHT); ctx.setTheme(style); showAnimation(ctx); refreshUI(ctx); } /** * * @param ctx 上下文 * @param style 切换style */ public static void changeDay(Activity ctx,int style) { if(mBackGroundDrawableViews == null || mOneTextColorViews == null || mTwoTextColorViews == null ||mThreeTextColorViews == null ||mBackGroundViews == null){ throw new RuntimeException("请先调用init()初始化方法!"); } ChangeModeHelper.setChangeMode(ctx, ChangeModeHelper.MODE_DAY); ctx.setTheme(style); showAnimation(ctx); refreshUI(ctx); } /** * 刷新UI界面 * @param ctx 上下文 */ private static void refreshUI(Activity ctx) { TypedValue typedValue = new TypedValue(); Resources.Theme theme = ctx.getTheme(); theme.resolveAttribute(R.attr.colorPrimary, typedValue, true); View view = ctx.findViewById(R.id.action_bar); if(view!=null){ view.setBackgroundResource(typedValue.resourceId); } for(AttrEntity<View> entity:mBackGroundViews){ theme.resolveAttribute(entity.colorId, typedValue, true); entity.v.setBackgroundResource(typedValue.resourceId); } for(AttrEntity<View> entity:mBackGroundDrawableViews){ theme.resolveAttribute(entity.colorId, typedValue, true); entity.v.setBackgroundResource(typedValue.resourceId); } for (AttrEntity<TextView> entity: mOneTextColorViews){ theme.resolveAttribute(entity.colorId, typedValue, true); entity.v.setTextColor(ctx.getResources().getColor(typedValue.resourceId)); } for (AttrEntity<TextView> entity: mOneTextColorViews){ theme.resolveAttribute(entity.colorId, typedValue, true); entity.v.setTextColor(ctx.getResources().getColor(typedValue.resourceId)); } //refreshStatusBar(ctx); } /** * 获取某个属性的TypedValue * @param ctx 上下文 * @param attr 属性id * @return */ public static TypedValue getAttrTypedValue(Activity ctx,int attr){ TypedValue typedValue = new TypedValue(); Resources.Theme theme = ctx.getTheme(); theme.resolveAttribute(attr, typedValue, true); return typedValue; } /** * 刷新 StatusBar * @param ctx 上下文 */ private static void refreshStatusBar(Activity ctx) { if (Build.VERSION.SDK_INT >= 21) { TypedValue typedValue = new TypedValue(); Resources.Theme theme = ctx.getTheme(); theme.resolveAttribute(R.attr.colorPrimaryDark, typedValue, true); ctx.getWindow().setStatusBarColor(ctx.getResources().getColor(typedValue.resourceId)); } } /** * 展示切换动画 */ private static void showAnimation(Activity ctx) { final View decorView = ctx.getWindow().getDecorView(); Bitmap cacheBitmap = getCacheBitmapFromView(decorView); if (decorView instanceof ViewGroup && cacheBitmap != null) { final View view = new View(ctx); view.setBackgroundDrawable(new BitmapDrawable(ctx.getResources(), cacheBitmap)); ViewGroup.LayoutParams layoutParam = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT); ((ViewGroup) decorView).addView(view, layoutParam); ValueAnimator objectAnimator = ValueAnimator.ofFloat(1f, 0f);//view, "alpha", objectAnimator.setDuration(500); objectAnimator.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { super.onAnimationEnd(animation); ((ViewGroup) decorView).removeView(view); } }); objectAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { float alpha = (Float) animation.getAnimatedValue(); view.setAlpha(alpha); } }); objectAnimator.start(); } } /** * 获取一个 View 的缓存视图 * * @param view * @return */ private static Bitmap getCacheBitmapFromView(View view) { final boolean drawingCacheEnabled = true; view.setDrawingCacheEnabled(drawingCacheEnabled); view.buildDrawingCache(drawingCacheEnabled); final Bitmap drawingCache = view.getDrawingCache(); Bitmap bitmap; if (drawingCache != null) { bitmap = Bitmap.createBitmap(drawingCache); view.setDrawingCacheEnabled(false); } else { bitmap = null; } return bitmap; } /** * 视图销毁时调用 */ public static void onDestory(){ mBackGroundViews.clear(); mOneTextColorViews.clear(); mTwoTextColorViews.clear(); mThreeTextColorViews.clear(); mBackGroundDrawableViews.clear(); mBackGroundViews = null; mOneTextColorViews = null; mTwoTextColorViews=null; mThreeTextColorViews=null; mBackGroundDrawableViews = null; mChangeModeController = null; } /** * 添加背景颜色属性 * @param view * @param colorId * @return */ public ChangeModeController addBackgroundColor(View view, int colorId) { mBackGroundViews.add(new AttrEntity(view,colorId)); return this; } /** *添加背景图片属性 * @param view * @param drawableId 属性id * @return */ public ChangeModeController addBackgroundDrawable(View view, int drawableId) { mBackGroundDrawableViews.add(new AttrEntity(view,drawableId)); return this; } /** * 添加一级字体颜色属性 * @param view * @param colorId 属性id * @return */ public ChangeModeController addTextColor(View view, int colorId) { mOneTextColorViews.add(new AttrEntity<TextView>((TextView) view,colorId)); return this; } /** * 添加二级字体颜色属性 * @param view * @param colorId 属性id * @return */ public ChangeModeController addTwoTextColor(View view, int colorId) { mTwoTextColorViews.add(new AttrEntity<TextView>((TextView) view,colorId)); return this; } /** * 添加三级字体颜色属性 * @param view * @param colorId 属性id * @return */ public ChangeModeController addThreeTextColor(View view, int colorId) { mThreeTextColorViews.add(new AttrEntity<TextView>((TextView) view,colorId)); return this; } class AttrEntity<T>{ T v;//控件 int colorId;//属性id public AttrEntity(T v, int colorId) { this.v = v; this.colorId = colorId; } } }