Android 播放器通知栏样式适配
来源:互联网 发布:企业cms开源 编辑:程序博客网 时间:2024/06/18 18:00
一、获取通知栏主题颜色
由于调用系统的属性,获取颜色在某些手机上是不兼容的。因此采用先创建一个系统通知栏对象,然后迭代其中的 View 获取对应的颜色。代码如下:
import android.app.Notification;import android.content.Context;import android.support.v4.app.NotificationCompat;import android.support.v7.app.AppCompatActivity;import android.util.Log;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.FrameLayout;import android.widget.TextView;import java.util.ArrayList;import java.util.List;/** * Created by iOnesmile on 06/07/2017. */public class NotificationColor { private static final String NOTIFICATION_TITLE = "notification_title"; public static final int INVALID_COLOR = -1; // 无效颜色 private static int notificationTitleColor = INVALID_COLOR; // 获取到的颜色缓存 /** * 获取系统通知栏主标题颜色,根据Activity继承自AppCompatActivity或FragmentActivity采取不同策略。 * * @param context 上下文环境 * @return 系统主标题颜色 */ public static int getNotificationColor(Context context) { try { if (notificationTitleColor == INVALID_COLOR) { if (context instanceof AppCompatActivity) { notificationTitleColor = getNotificationColorCompat(context); } else { notificationTitleColor = getNotificationColorInternal(context); } } } catch (Exception ignored) { } return notificationTitleColor; } /** * 通过一个空的Notification拿到Notification.contentView,通过{@link RemoteViews#apply(Context, ViewGroup)}方法返回通知栏消息根布局实例。 * * @param context 上下文 * @return 系统主标题颜色 */ private static int getNotificationColorInternal(Context context) { NotificationCompat.Builder builder = new NotificationCompat.Builder(context); builder.setContentTitle(NOTIFICATION_TITLE); Notification notification = builder.build(); try { ViewGroup root = (ViewGroup) notification.contentView.apply(context, new FrameLayout(context)); TextView titleView = (TextView) root.findViewById(android.R.id.title); if (null == titleView) { iteratorView(root, new Filter() { @Override public void filter(View view) { if (view instanceof TextView) { TextView textView = (TextView) view; if (NOTIFICATION_TITLE.equals(textView.getText().toString())) { notificationTitleColor = textView.getCurrentTextColor(); } } } }); return notificationTitleColor; } else { return titleView.getCurrentTextColor(); } } catch (Exception e) { Log.e("NotificationColor", "", e); return getNotificationColorCompat(context); } } /** * 使用getNotificationColorInternal()方法,Activity不能继承自AppCompatActivity(实测5.0以下机型可以,5.0及以上机型不行), * 大致的原因是默认通知布局文件中的ImageView(largeIcon和smallIcon)被替换成了AppCompatImageView, * 而在5.0及以上系统中,AppCompatImageView的setBackgroundResource(int)未被标记为RemotableViewMethod,导致apply时抛异常。 * * @param context 上下文 * @return 系统主标题颜色 */ private static int getNotificationColorCompat(Context context) { try { NotificationCompat.Builder builder = new NotificationCompat.Builder(context); Notification notification = builder.build(); int layoutId = notification.contentView.getLayoutId(); ViewGroup root = (ViewGroup) LayoutInflater.from(context).inflate(layoutId, null); TextView titleView = (TextView) root.findViewById(android.R.id.title); if (null == titleView) { return getTitleColorIteratorCompat(root); } else { return titleView.getCurrentTextColor(); } } catch (Exception e) { } return INVALID_COLOR; } private static void iteratorView(View view, Filter filter) { if (view == null || filter == null) { return; } filter.filter(view); if (view instanceof ViewGroup) { ViewGroup viewGroup = (ViewGroup) view; for (int i = 0; i < viewGroup.getChildCount(); i++) { View child = viewGroup.getChildAt(i); iteratorView(child, filter); } } } private static int getTitleColorIteratorCompat(View view) { if (view == null) { return INVALID_COLOR; } List<TextView> textViews = getAllTextViews(view); int maxTextSizeIndex = findMaxTextSizeIndex(textViews); if (maxTextSizeIndex != Integer.MIN_VALUE) { return textViews.get(maxTextSizeIndex).getCurrentTextColor(); } return INVALID_COLOR; } private static int findMaxTextSizeIndex(List<TextView> textViews) { float max = Integer.MIN_VALUE; int maxIndex = Integer.MIN_VALUE; int index = 0; for (TextView textView : textViews) { if (max < textView.getTextSize()) { // 找到字号最大的字体,默认把它设置为主标题字号大小 max = textView.getTextSize(); maxIndex = index; } index++; } return maxIndex; } /** * 实现遍历View树中的TextView,返回包含TextView的集合。 * * @param root 根节点 * @return 包含TextView的集合 */ private static List<TextView> getAllTextViews(View root) { final List<TextView> textViews = new ArrayList<>(); iteratorView(root, new Filter() { @Override public void filter(View view) { if (view instanceof TextView) { textViews.add((TextView) view); } } }); return textViews; } private interface Filter { void filter(View view); }}
二、渲染播放图标
播放器图标的渲染,采用 v4
包中的 tint
方法,代码如下:
public static Bitmap getBitmapByIdAndRender(Context context, int drawableResId, int renderColor) { Drawable drawable = getDrawable(context, drawableResId); drawable = tintDrawable(drawable, ColorStateList.valueOf(renderColor)); return drawableToBitmap(drawable);}public static Drawable getDrawable(Context context, int imageRes) { Drawable drawable = context.getResources().getDrawable(imageRes); drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight()); return drawable;}public static Drawable tintDrawable(Drawable drawable, ColorStateList colors) { final Drawable wrappedDrawable = DrawableCompat.wrap(drawable); DrawableCompat.setTintList(wrappedDrawable, colors); return wrappedDrawable;}
在设置副标题的颜色时,我采用了给主标题设置一个透明度的方式来达到,通过 HSV 模型把颜色和透明度合成一个新的色值:
/** * 把RGB + Alpha合成为一个新的RGB * @param alpha * @param color * @return */public static int getCompoundColor(int alpha, int color) { float[] hsv = new float[]{0, 0, 1}; Color.colorToHSV(color, hsv); hsv[2] = (alpha + 0.0f) / 0xFF; color = Color.HSVToColor(hsv); return color;}
三、参考链接
Android自定义通知样式适配 http://www.jianshu.com/p/426d85f34561
Android通知栏介绍与适配总结 http://iluhcm.com/2017/03/12/experience-of-adapting-to-android-notifications/
阅读全文
0 0
- Android 播放器通知栏样式适配
- Android自定义通知样式适配
- Android自定义通知样式适配
- Android 音乐播放器的通知栏
- Android自定义通知样式适配不同系统样式
- 【黑马Android】(11)音乐播放器/视频播放器/照相机/常见对话框/notification通知/样式和主题/帧动画/传感器/应用程序反编译与安装
- android 通知播放系统声音
- android 通知栏中自定义进度条长方形样式
- Android 自定义样式通知栏的坑RemoteServiceException
- Android 音乐播放器的开发教程(十)通知栏Notification的使用 ----- 小达
- Android仿虾米音乐播放器之通知栏notification解析
- 基于android的网络音乐播放器-通知栏控制(RemoteViews)(十)
- Android通知栏通知
- Android 通知栏Notification,NotificationManager,RemoteViews使用流程,自定义通知栏样式简介
- Android实战 - 音心播放器 (通知实现音乐的播放/暂停/下一曲控制)
- Android中通知的简单使用和自定义通知样式
- Android(六)通知、样式、主题、HTML
- 使用RemoteViews自定义通知栏样式
- MySQL普通用户修改密码
- 构建微服务:Spring boot 入门篇
- Tempter of the Bone(dfs好题)
- pacemaker+corosync实现高可用集群
- SetThreadAffinityMask中掩码的问题
- Android 播放器通知栏样式适配
- Red and Black
- 【Unity Shader入门练习】调整屏幕的亮度、饱和度和对比度
- PDF怎么转换成WORD转换器以及在线转换汇总
- mysql查询查询树结构,通过树结构查询一个自己昵称和父级节点的昵称
- 英语总结—— 翩若惊鸿, 婉若游龙
- poi写出报表
- 最小路径覆盖
- Java 注解