首页 > 其他分享 >android 12 修改Launcher3 app hotseat 图标形状为圆角图标

android 12 修改Launcher3 app hotseat 图标形状为圆角图标

时间:2023-11-08 11:55:37浏览次数:27  
标签:info canvas 12 app FastBitmapDrawable drawable public 图标

1.概述

在对11.0产品开发中,对于Launcher3做各种定制化开发,也是常见的,最近有功能需求要求,对于修改图标的形状为圆角图标,而在Launcher3中,所有的app和hotseat 都是由BubbleTextView负责构建的,所以对于图标的修改也是要从BubbleTextView.java修改的

在这里插入图片描述

2.修改Launcher3 app hotseat 图标形状为圆角图标的相关类

/package/app/Launcher3/src/com/android/launcher3/BubbleTextView.java
/packages/apps/Launcher3/src/com/android/launcher3/FastBitmapDrawable.java

3.修改Launcher3 app hotseat 图标形状为圆角图标的相关功能分析和实现

3.1看BubbleTextView.java 源码关于图标的绑定

/package/app/Launcher3/src/com/android/launcher3/BubbleTextView.java
public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver, OnResumeCallback,
         IconLabelDotView, DraggableView, Reorderable {
 
     private static final int DISPLAY_WORKSPACE = 0;
     private static final int DISPLAY_ALL_APPS = 1;
     private static final int DISPLAY_FOLDER = 2;
 
     private static final int[] STATE_PRESSED = new int[] {android.R.attr.state_pressed};

public void applyFromWorkspaceItem(WorkspaceItemInfo info) {
        applyFromWorkspaceItem(info, false);
    }

    public void applyFromWorkspaceItem(WorkspaceItemInfo info, boolean promiseStateChanged) {
        applyIconAndLabel(info);
        setTag(info);
        if (promiseStateChanged || (info.hasPromiseIconUi())) {
            applyPromiseState(promiseStateChanged);
        }

        applyDotState(info, false /* animate */);
    }

    public void applyFromApplicationInfo(AppInfo info) {
        applyIconAndLabel(info);

        // We don't need to check the info since it's not a WorkspaceItemInfo
        super.setTag(info);

        // Verify high res immediately
        verifyHighRes();

        if (info instanceof PromiseAppInfo) {
            PromiseAppInfo promiseAppInfo = (PromiseAppInfo) info;
            applyProgressLevel(promiseAppInfo.level);
        }
        applyDotState(info, false /* animate */);
    }

@UiThread
protected void applyIconAndLabel(ItemInfoWithIcon info) {
boolean useTheme = mDisplay == DISPLAY_WORKSPACE || mDisplay == DISPLAY_FOLDER
|| mDisplay == DISPLAY_TASKBAR;
FastBitmapDrawable iconDrawable = info.newIcon(getContext(), useTheme);
mDotParams.color = IconPalette.getMutedColor(iconDrawable.getIconColor(), 0.54f);

setIcon(iconDrawable);
applyLabel(info);
}

packages\apps\Launcher3\src\com\android\launcher3\model\data\ItemInfoWithIcon.java

/**
* The bitmap for the application icon
*/
public BitmapInfo bitmap = BitmapInfo.LOW_RES_INFO;


/** * Returns a FastBitmapDrawable with the icon and context theme applied */ public FastBitmapDrawable newIcon(Context context, boolean applyTheme) { FastBitmapDrawable drawable = applyTheme ? bitmap.newThemedIcon(context) : bitmap.newIcon(context); drawable.setIsDisabled(isDisabled()); return drawable; }

frameworks\libs\systemui\iconloaderlib\src\com\android\launcher3\icons\BitmapInfo.java

  /**
     * Creates a drawable for the provided BitmapInfo
     */
    public FastBitmapDrawable newIcon(Context context) {
        FastBitmapDrawable drawable = isLowRes()
                ? new PlaceHolderIconDrawable(this, context)
                : new FastBitmapDrawable(this);
        drawable.mDisabledAlpha = GraphicsUtils.getFloat(context, R.attr.disabledIconAlpha, 1f);
        return drawable;
    }

 

在上述代码中发现调用applyFromApplicationInfo((AppInfo) info)进行图标数据的绑定加载,而在applyFromApplicationInfo((AppInfo) info)中applyIconAndLabel(info)是绑定图标和文字的
applyIconAndLabel 是对图标做处理显示的
所以就从这里解决问题

frameworks\libs\systemui\iconloaderlib\src\com\android\launcher3\icons\FastBitmapDrawable.java

进入FastBitmapDrawable .newIcon();

public class FastBitmapDrawable extends Drawable {
  
      private static final float PRESSED_SCALE = 1.1f;
  
      private static final float DISABLED_DESATURATION = 1f;
      private static final float DISABLED_BRIGHTNESS = 0.5f;
  
      public static final int CLICK_FEEDBACK_DURATION = 200;
  
      private static ColorFilter sDisabledFColorFilter;
  
      protected final Paint mPaint = new Paint(Paint.FILTER_BITMAP_FLAG | Paint.ANTI_ALIAS_FLAG);
      protected Bitmap mBitmap;
      protected final int mIconColor;
  
      private boolean mIsPressed;
      private boolean mIsDisabled;
      private float mDisabledAlpha = 1f;
  
      // Animator and properties for the fast bitmap drawable's scale
      private static final Property<FastBitmapDrawable, Float> SCALE
              = new Property<FastBitmapDrawable, Float>(Float.TYPE, "scale") {
          @Override
          public Float get(FastBitmapDrawable fastBitmapDrawable) {
              return fastBitmapDrawable.mScale;
          }
  
          @Override
          public void set(FastBitmapDrawable fastBitmapDrawable, Float value) {
              fastBitmapDrawable.mScale = value;
              fastBitmapDrawable.invalidateSelf();
          }
      };
 /**
       * Returns a FastBitmapDrawable with the icon.
       */
      public static FastBitmapDrawable newIcon(Context context, ItemInfoWithIcon info) {
          FastBitmapDrawable drawable = newIcon(context, info.bitmap);
          drawable.setIsDisabled(info.isDisabled());
          return drawable;
      }
  
      /**
       * Creates a drawable for the provided BitmapInfo
       */
      public static FastBitmapDrawable newIcon(Context context, BitmapInfo info) {
          final FastBitmapDrawable drawable;
          if (info instanceof Factory) {
              drawable = ((Factory) info).newDrawable();
          } else if (info.isLowRes()) {
              drawable = new PlaceHolderIconDrawable(info, context);
          } else {
              drawable = new FastBitmapDrawable(info);
          }
          drawable.mDisabledAlpha = Themes.getFloat(context, R.attr.disabledIconAlpha, 1f);
          return drawable;
      }
  }

 

通过调用FastBitmapDrawable .newIcon()等相关方法,发现最后
发现实际上是有FastBitmapDrawable来处理图标而在FastBitmapDrawable实际上也是Drawable 的资子类,最后得用draw(Canvas canvas)来绘制图标
继续跟踪FastBitmapDrawable

public FastBitmapDrawable(ItemInfoWithIcon info) {
        this(info.iconBitmap, info.iconColor);
    }

    protected FastBitmapDrawable(Bitmap b, int iconColor) {
        this(b, iconColor, false);
    }

    protected FastBitmapDrawable(Bitmap b, int iconColor, boolean isDisabled) {
        mBitmap = b;
        mIconColor = iconColor;
        setFilterBitmap(true);
        setIsDisabled(isDisabled);
    }

    @Override
    public final void draw(Canvas canvas) {
        if (mScale != 1f) {
            int count = canvas.save();
            Rect bounds = getBounds();
            canvas.scale(mScale, mScale, bounds.exactCenterX(), bounds.exactCenterY());
            drawInternal(canvas, bounds);
            canvas.restoreToCount(count);
        } else {
            drawInternal(canvas, getBounds());
        }
    }

    protected void drawInternal(Canvas canvas, Rect bounds) {
        canvas.drawBitmap(mBitmap, null, bounds, mPaint);
    }

在draw(Canvas canvas)绘制图标后,最终调用drawInternal(Canvas canvas, Rect bounds)负责绘制图标,从以上代码可以看出 具体处理图标的地方是在drawInternal来实现对图标的绘制
所以就在这里对图标做圆角处理 具体如下:

     protected void drawInternal(Canvas canvas, Rect bounds) {
-        canvas.drawBitmap(mBitmap, null, bounds, mPaint);
+        // 初始化绘制纹理图
+        BitmapShader bitmapShader = new BitmapShader(mBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
+               Paint paint = new Paint();
+               paint.setAntiAlias(true);
+               paint.setDither(true);
+        paint.setShader(bitmapShader);
+               paint.setStrokeWidth(16);
+        // 利用画笔将纹理图绘制到画布上面
+               int mWidth = Math.min(mBitmap.getWidth(), mBitmap.getHeight());
+        canvas.drawRoundRect(new RectF(8, 8, mWidth-8, mWidth-8), 40, 40, paint);
+               //canvas.drawCircle(mWidth / 2, mWidth / 2, mWidth / 2, paint);
+        //canvas.drawBitmap(mBitmap, null, bounds, mPaint);
     }
   

标签:info,canvas,12,app,FastBitmapDrawable,drawable,public,图标
From: https://www.cnblogs.com/wanglongjiang/p/17817071.html

相关文章

  • Web Profile Builder for Web Application Projects
    WebProfileBuilderforWebApplicationProjectsFilescanbedownloadedfromtheWebProfileBuilderprojectpage.IfyouuseWebApplicationProjects,youhaveprobablyrunintotheissueofnotbeingabletoaccesstheProfileatdesigntime.Thankfully......
  • javascript 手动实现 bind,call,apply
     js手动实现call方法Function.prototype.myCall=function(content,...args){letmyfn=Symbol()content=content||globalThis//console.log(content)content[myfn]=this//console.log(content)constresu......
  • FS2957 降压恒压芯片内置120V功率管36V48V60V72V80v降压5V
    随着科技的不断进步,电子设备在我们的生活中越来越普及,而电源管理芯片作为电子设备中的重要组成部分,也得到了广泛的应用。今天,我们要介绍的是一款具有高性价比的FS2957降压恒压芯片,它内置120V功率管,适用于36V、48V、60V、72V、80V的降压5V输出。FS2957降压恒压芯片采用专利的电流模......
  • 靓丽内蒙古旅游app设计与实现-计算机毕业设计源码+LW文档
    摘 要随着互联网的飞速发展,人民生活水平逐步上升,伴随着的是人们对生活质量的追求不断提高,而旅游就是提高生活质量的一种很好的方式。当旅游人数和旅游景点数同时飞速增加时,旅游相关的数据的管理就变得愈加困难,因此,旅游管理系统的开发也就应运而生。系统通过采用目前主流的设计......
  • uniapp小程序页面跳回携带参数
    B返回A1.B跳回事件letpages=getCurrentPages();//当前页页⾯实例            letnowPage=pages[pages.length-1];//当前页⾯实例            letprevPage=pages[pages.length-2];//上一页面实例            //......
  • IApplicationBuilder详解
    在上节中我们已经得知WebApplication实现了IApplicationBuilder,我们浅谈了其pipe特质和构建方法,本节中将深入了解ApplicationBuilder以窥探IApplicationBuilder真相publicinterfaceIApplicationBuilder{IServiceProviderApplicationServices{get;set;}I......
  • 整理《DQNViz: A Visual Analytics Approach to Understand Deep Q-Networks》
    DQNViz:AVisualAnalyticsApproachtoUnderstandDeepQ-Networks论文/强化学习可视化摘要打算研究深度强化学习方向,整理最近的一篇2019年的论文,作为总结思考!论文介绍该论文是一篇2019年,有关基于可视化进行强化学习可解释的文章。一作是JunpengWang,作者主要研究领......
  • uniApp:使用vue3+Vite4+pinia+sass技术栈构建(03)-封装对象类
    1.在src文件夹创建models文件夹import{user}from"@/service/api"//用户信息返回的数据类型interfaceuserInfoType{username:string,phone:string}//返回类型interfaceResultType<T>{errno:number,errmsg:string,datas:T}classuser......
  • Appium 2.X 做 iOS UI 自动化测试 —— 起步
    环境Appium2.0之后,安装方式简化了许多,和之前变化很大;必须使用Mac;分别安装node、appium#nodebrewinstallnodenpmconfigsetregistryhttps://registry.npm.taobao.org#appiumnpminstall-gappium安装appium-inspector客户端下载或者网络调试,不过速度较......
  • uniapp之文件保存
    uniapp之文件保存文件保存分几种情况:1.网络文件保存:使用uni.downloadFile创建临时文件地址,然后使用uni.saveFile保存uni.downloadFile({//下载 url:path, success:(res)=>{ if(res.statusCode==200){ uni.saveFile({ tempFileP......