背景:

在通知栏使用自定义布局时,经常会有各种奇葩的需求,更改字体,更改字体颜色,更改图片等等。。。

实践:

让我们一条一条来分析:

1,动态设置文字:remoteViews.setTextViewText(R.id.fn_flow_noti_hotword_content_black, keyWord);  get;

2.动态设置文字颜色:emoteViews.setTextColor(R.id.fn_flow_noti_text_int_flow_black, Color.parseColor("#CD3E3E"));  get

3.动态设置文字大小:remoteViews.setTextViewTextSize(R.id.fn_flow_noti_info_layout_time_black,13); but

 解决方案:

SpannableString mspInt= null;
            mspInt = new SpannableString(leftString[1]);
            mspInt.setSpan(new AbsoluteSizeSpan(sp2px(context,25)), 0, leftString[1].length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
            remoteViews.setTextViewText(R.id.fn_flow_noti_text_int_flow_black,mspInt);

这里用到了SpannableString 这个黑科技,具体与String的关系,大家自行百度。

我们看下remoteViews.setText()第二个参数,发现是CharSequence;

只要支持CharSequence那么就可以使用SpannableString。get

4.通知栏使用自定义字体

通知栏使用大号字体会出现字体太粗,字体间隔太大的问题,我们尝试使用SpannableString来解决这个问题,但是发现,及时你给SpannableString 设定了自定义字体,运行发现并没有生效,简单看下源码会发现通知栏屏蔽了textview的字体效果。

TextView行不通,那么就只能考虑imgaeview,imageview也有两种方案:

1) 在uc浏览器的常驻通知栏上有一个温度的数字显示,也是大号字体,但是确实没有特别粗,间距也不大,粗布分析时使用了图片,解压缩一下apk,在res下可以找到0-9的10张图片,这是一种实现方式

2)使用画布的方式来手动绘制,废话不多上,上代码:

/**
     * 使用自定义字体绘制流量信息以及低流量图片
     * @param context
     * @param str
     * @param flowStatus
     * @return
     */
    private static Bitmap buildUpdate(Context context,SpannableString str,int flowStatus)     {
        //初始化画笔
        Paint paint = new Paint();
        Typeface clock = Typeface.createFromAsset(context.getAssets(),"iconfont/light.otf");
        paint.setAntiAlias(true);
        paint.setSubpixelText(true);
        paint.setTextAlign(Paint.Align.LEFT);
        paint.setTypeface(clock);
        paint.setStyle(Paint.Style.FILL);
        paint.setColor(Color.RED);
        

        /**
         * 提取出来作为方法,65写出来 fixed me
         */
        int mCanvasWidth = 0;
        //计算整数位上的宽度
        paint.setTextSize(sp2px(context,40));
        Rect boundsLeft = new Rect();
        paint.getTextBounds(str.toString(), 0, 3, boundsLeft);
        mCanvasWidth += boundsLeft.width();
        //计算小数位上的宽度
        paint.setTextSize(sp2px(context,20));
        Rect boundsRight = new Rect();
        paint.getTextBounds(str.toString(), 3, str.length(), boundsRight);
        
        //根据文字宽度生成画布,比较图片和小数位宽度,取最大值
        Bitmap flowLowBmp = BitmapFactory.decodeResource(context.getResources(), R.mipmap.img_flow_low);
        if (flowLowBmp.getWidth()>boundsRight.width()) {
            mCanvasWidth += flowLowBmp.getWidth();
        } else {
            mCanvasWidth += boundsRight.width();
        }
        //生成画布  宽度为文字宽度,加30保证不被压缩到,高度为通知栏高度
        Bitmap mBitmap = Bitmap.createBitmap(mCanvasWidth+30,dip2px(context,65), Bitmap.Config.ARGB_4444);
        Canvas mCanvas = new Canvas(mBitmap);
        //计算文字的左下起点y值,画布中线家加上文字高度的一半
        float baseline = dip2px(context,65)/2 + paint.getTextSize()/2;
        //绘制整数位
        paint.setTextSize(sp2px(context,40));
        mCanvas.drawText(str,0,3, 10, baseline, paint);
        //绘制小数位
        paint.setTextSize(sp2px(context,20));
        mCanvas.drawText(str,3,str.length(), boundsLeft.width()+15,baseline, paint);

        //流量不足时显示低流量图片
        if(flowStatus == FlowDataUtils.STATE_WARNING) {
            mCanvas.drawBitmap(flowLowBmp, boundsLeft.width()+20, dip2px(context, 10), paint);
        }
        return mBitmap;
    }