androID P都已经出来好久了,今天在使用AndroID P过程中发现在dislpay下面有一个主题设置(Device theme)
如下所示
可以看出一个有3个选项,通过使用后发现,他运行用户设置手机主题,跟app主题不一样,这里的主题设置可以供系统以及所有应用查询.系统主题一共有暗和亮两张状态.上面设置中3个选项代表的意义如下:automatic (base on wallpaper):系统检查当前设置的手机壁纸属于暗还是亮,然后更具判断设置主题light:设置亮主题Dark:设置暗主题
设置亮主题:
设置暗主题:
这样看效果还是挺明显的.通过源码发现,目前系统上launche和systemUI监听了系统主题的状态,然后显示系统的主题,其他app如果需要根据系统当前主题,也需要实时监听主题变化,
二.如何实现系统主题个人app要监听系统主题,直接使用WallpaperManager,addOncolorsChangedListener方法,通过Listener回调
实现步奏如下:
if (wallpaperManager == null) { wallpaperManager = WallpaperManager.getInstance(context.getApplicationContext()); }
调用WallpaperManager的单例,实际上就是getSystemService
public static WallpaperManager getInstance(Context context) { return (WallpaperManager)context.getSystemService( Context.WALLPAPER_SERVICE); }
step2:监听主题变化这个回调方法会在主题切换中触发,下面是触发后调用的方法
WallpaperManager.OncolorsChangedListener oncolorsChangedListener = new WallpaperManager.OncolorsChangedListener(){ @OverrIDe public voID oncolorsChanged(Wallpapercolors colors, int which) {//1 if (WallpaperManager.FLAG_SYstem == which) {//2 updatetheme(colors); } }};wallpaperManager.addOncolorsChangedListener(oncolorsChangedListene, null);//3Wallpapercolors colorsSystem = wallpaperManager.getWallpapercolors(WallpaperManager.FLAG_SYstem);updatetheme(colorsSystem);//4
3.处是监听主题变化,第二个参数是handler,如果选择null.表示主线程的looper对应的hander1处返回两个参数Wallpapercolors,which;Wallpapercolors可以判断属于亮还是暗主题,which表示锁屏(WallpaperManager.FLAG_LOCK)还是系统(WallpaperManager.FLAG_SYstem),因为主题设置有一个automatic (base on wallpaper)选项,而锁屏壁纸和桌面壁纸可以不一样,那么换壁纸的时候,会有差异.一般app是参考系统(WallpaperManager.FLAG_SYstem)这个配置主题,如2处4处,因为主题回调是在切换主题才会进行,app开始运行的时候,需要回去当时的主题因为系统主题是在androID O上才有的,如果要app最低版本是androID O以下,请做判断
if (androID.os.Build.VERSION.SDK_INT >= androID.os.Build.VERSION_CODES.O_MR1) { }
step3:判断主题是亮还是暗下面是systemUI判断主题的代码片段
public voID updatetheme(Wallpapercolors colors) { final boolean useDarktheme = colors != null && (colors.getcolorHints() & HINT_SUPPORTS_DARK_theme) != 0;}
打印log可以发现colors.getcolorHints()在亮的时候是4,暗的时候是6,而HINT_SUPPORTS_DARK_theme == 2
Wallpapercolors这个类很多方法被hIDe修饰,包括getcolorHints方法,导致非系统无法调用,如图
AndroID P后面又限制通过反射来调用系统API,直接调用这个方法是没戏了,但是这个类的toString方法又把这个值给打印出来了.
我们可以截取这个值,然后在判断,于是修改上面的判断
public voID updatetheme(Wallpapercolors colors) { final boolean useDarktheme = colors != null && (getcolorHints(colors) & HINT_SUPPORTS_DARK_theme) != 0;}private int getcolorHints(Wallpapercolors colors) { String str = colors.toString(); int index = str.lastIndexOf("h: "); String val = str.substring(index + 3, str.length() - 1); if (TextUtils.isDigitsOnly(val)) { return Integer.valueOf(val); } Log.e(TAG, "can not get getcolorHints!!"); return 0; }
改法不优雅,只能将就使用了
step4:退出监听 wallpaperManager.removeOncolorsChangedListener(oncolorsChangedListener);
三.介绍Wallpapercolors类Wallpapercolors源码解释:ProvIDes information about the colors of a wallpaper.这个记录壁纸的color
Wallpapercolors有几个有意思的方法
方法 | 返回类型 | 意义 | @H_502_128@
---|---|---|
getPrimarycolor() | color | 获取墙纸最具视觉代表性的颜色。 | @H_502_128@
getSecondarycolor() | color | 获得了壁纸的第二个最卓越的颜色。 | @H_502_128@
getTertiarycolor() | color | 获得了壁纸的第三个最卓越的颜色。 | @H_502_128@
getMaincolors() | List of color | 按重要性排序的最杰出的颜色列表。 | @H_502_128@
getcolorHints() | int | 壁纸颜色提示的组合。(暗或者亮) | @H_502_128@
calculateDarkHints(Bitmap source) | int | 根据传入的Bitmap,检查图像是否足够明亮 | @H_502_128@
fromBitmap(@NonNull Bitmap bitmap) | Wallpapercolors | 根据传入的Bitmap,检查图像返回Wallpapercolors | @H_502_128@
fromDrawable(Drawable drawable) | Wallpapercolors | 根据传入的Drawable,检查图像返回Wallpapercolors | @H_502_128@
import androID.app.Wallpapercolors;import androID.app.WallpaperManager;import androID.content.Context;import androID.text.TextUtils;import androID.util.Log;import java.util.ArrayList;import java.util.List;public final class colorExtractor { public interface colorsChange { public voID themeChange(boolean useDarktheme); } private static colorExtractor colorExtractor; private static final String TAG = "colorExtractor"; private WallpaperManager wallpaperManager; private static final int HINT_SUPPORTS_DARK_theme = 1 << 1; private WallpaperManager.OncolorsChangedListener oncolorsChangedListene; private List<colorsChange> Listens; private colorExtractor() { if (androID.os.Build.VERSION.SDK_INT >= androID.os.Build.VERSION_CODES.O_MR1) { oncolorsChangedListene = new WallpaperManager.OncolorsChangedListener() { @OverrIDe public voID oncolorsChanged(Wallpapercolors colors, int which) { if (which == WallpaperManager.FLAG_SYstem) { final boolean useDarktheme = colors != null && (getcolorHints(colors) & HINT_SUPPORTS_DARK_theme) != 0; if (Listens != null && Listens.size() > 0) { for (colorsChange colorsChange : Listens) { colorsChange.themeChange(useDarktheme); } } } } }; } Listens = new ArrayList<>(); } public static colorExtractor getInstance() { if (colorExtractor == null) { colorExtractor = new colorExtractor(); } return colorExtractor; } public voID startListen(Context context) { if (androID.os.Build.VERSION.SDK_INT >= androID.os.Build.VERSION_CODES.O_MR1) { if (wallpaperManager == null) { wallpaperManager = WallpaperManager.getInstance(context.getApplicationContext()); } Wallpapercolors colorsSystem = wallpaperManager.getWallpapercolors(WallpaperManager.FLAG_SYstem); final boolean useDarktheme = colorsSystem != null && (getcolorHints(colorsSystem) & HINT_SUPPORTS_DARK_theme) != 0; if (Listens != null && Listens.size() > 0) { for (colorsChange colorsChange : Listens) { colorsChange.themeChange(useDarktheme); } } wallpaperManager.addOncolorsChangedListener(oncolorsChangedListene, null); } } public voID addthemeChange(colorsChange colorsChange) { if (!Listens.contains(colorsChange)) { Listens.add(colorsChange); } } public voID removethemeChange(colorsChange colorsChange) { if (Listens.contains(colorsChange)) { Listens.remove(colorsChange); } } public voID stopListen() { if (androID.os.Build.VERSION.SDK_INT >= androID.os.Build.VERSION_CODES.O_MR1) { if (androID.os.Build.VERSION.SDK_INT >= androID.os.Build.VERSION_CODES.O_MR1) { wallpaperManager.removeOncolorsChangedListener(oncolorsChangedListene); } if (Listens != null) { Listens.clear(); } } } private int getcolorHints(Wallpapercolors colors) { String str = colors.toString(); int index = str.lastIndexOf("h: "); String val = str.substring(index + 3, str.length() - 1); if (TextUtils.isDigitsOnly(val)) { return Integer.valueOf(val); } Log.e(TAG, "can not get getcolorHints!!"); return 0; }}
使用方法://单例实例化colorExtractor colorExtractor = colorExtractor.getInstance();//注册监听事件,因为WallpaperManager注册的时候会调用初始主题,所以为了能获取初始值,所以在开始addthemeChange之前先注册监听事件.colorExtractor.addthemeChange(new colorExtractor.colorsChange() { @OverrIDe public voID themeChange(boolean useDarktheme) { Log.i(TAG, "useDarktheme[" + useDarktheme + "]"); }});//开始监听;一般在onStart(或onCreate)方法colorExtractor.startListen(this);//结束监听,一般在onStop(或onDestory)方法colorExtractor.stopListen();
总结 以上是内存溢出为你收集整理的Android O 新特性 系统主题全部内容,希望文章能够帮你解决Android O 新特性 系统主题所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)