圆形头像的7种显示方法

简介: 牙叔教程 简单易懂

牙叔教程 简单易懂


效果展示



环境

手机: Mi 11 Pro

Android版本: 11

Autojs版本: 9.0.11

图片形状: 正方形


圆形头像的7种显示方法


第1种: 使用ShapeableImageView控件

备注: material版本最低要求1.2.0, 因为ShapeableImageView控件是在1.2.0才添加的

"ui";
importClass(android.view.ViewOutlineProvider);
importClass(android.content.res.ColorStateList);
importClass(com.google.android.material.shape.RelativeCornerSize);
importClass(com.google.android.material.shape.AbsoluteCornerSize);
importClass(com.google.android.material.shape.CornerFamily);
importClass(com.google.android.material.shape.ShapeAppearanceModel);
ui.layout(
  <vertical>
    <com.google.android.material.imageview.ShapeableImageView
      android:id="@+id/image"
      android:layout_width="110dp"
      android:layout_height="110dp"
      android:padding="0dp"
      margin="20dp"
      app:strokeColor="#ff0000"
      android:src="file://./yashu.png"
    />
  </vertical>
);
imgView = ui.image;
imgView.shapeAppearanceModel = ShapeAppearanceModel.builder().setAllCornerSizes(ShapeAppearanceModel.PILL).build();


第2种: 使用setOutlineProvider设置view的轮廓

默认情况下,所有的view都是矩形的,虽然可以给view设置背景圆形的图片,即可以在界面显示出圆形的内容,但是view的大小实际上依然是矩形,并且设置的图片实际上也是矩形的,只是圆形以外的区域是透明色。


如果根据view大小来生成对应的阴影,就会出现很奇怪的效果,(一个看起来圆形的view展示出的却是一个矩形的阴影)为了解决这个问题,view增加了一个新的描述来指明内容显示的形状,这就是 轮廓

"ui";
importClass(android.view.ViewOutlineProvider);
ui.layout(
  <vertical>
    <img
      android:id="@+id/image"
      android:layout_width="110dp"
      android:layout_height="110dp"
      android:padding="0dp"
      margin="20dp"
      app:strokeColor="#ff0000"
      android:src="file://./yashu.png"
    />
  </vertical>
);
let img = $images.read("./yashu.png");
imgView = ui.image;
ui.post(function () {
  viewOutlineProvider = new ViewOutlineProvider({
    getOutline: function (view, outline) {
      outline.setRoundRect(0, 0, imgView.width, imgView.height, imgView.width / 2);
    },
  });
  imgView.setOutlineProvider(viewOutlineProvider);
  imgView.setClipToOutline(true);
});
events.on("exit", function () {
  img.recycle();
});


第3种: 使用card控件
将cardCornerRadius设置为控件宽度的一半即可

ui.layout(
  <vertical margin="100">
    <card android:layout_width="100dp" android:layout_height="100dp" cardCornerRadius="50dp">
      <img
        android:id="@+id/image"
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:padding="0dp"
        app:strokeColor="#ff0000"
        android:src="file://./yashu.png"
      />
    </card>
  </vertical>
);


第4种: 设置img控件的cornerRadius属性

和控件宽度一致即可, 注意控件的单位尺寸, 不带单位默认dp, dp和px可以互相转换

ui.layout(
  <vertical margin="100">
    <img id="image" src="file://./yashu.png" w="100" h="100" radius="30" scaleType="centerCrop" />
  </vertical>
);
imageView = ui.image;
const scale = context.getResources().getDisplayMetrics().density;
const dp2px = (dp) => Math.floor(dp * scale + 0.5);
ui.post(function () {
  imageView.attr("cornerRadius", dp2px(100)); //没反应
  imageView.invalidate();
});


第5种: 绘制控件时, 将显示区域裁剪为一个圆形,

使用setBackgroundDrawable给控件设置背景, 在draw事件发生时, 裁剪画板为圆形即可,

重写draw方法, 是自定义控件中最重要的内容之一.

ui.layout(
  <vertical margin="100">
    <View id="image" w="100" h="100" />
  </vertical>
);
imageView = ui.image;
let img = $images.read("./yashu.png");
bitmap = img.getBitmap();
const scale = context.getResources().getDisplayMetrics().density;
const dp2px = (dp) => Math.floor(dp * scale + 0.5);
ui.post(function () {
  var drawable = new android.graphics.drawable.Drawable({
    draw: function (canvas) {
      let paint = new Paint();
      var path = new Path();
      path.addCircle(imageView.getWidth() / 2, imageView.getHeight() / 2, imageView.getWidth() / 2, Path.Direction.CCW);
      canvas.clipPath(path);
      dst = new Rect(0, 0, imageView.getWidth(), imageView.getHeight()); //截取图片左上1/4的区域
      canvas.drawBitmap(bitmap, null, dst, paint);
    },
  });
  imageView.setBackgroundDrawable(drawable);
});


第6种: 使用BitmapShader

将图片添加到shader, 再给画笔设置shader, 画笔在画板上画一个圆形即可

"ui";
importClass(android.graphics.Rect);
importClass(android.graphics.PorterDuffXfermode);
importClass(android.graphics.Path);
importClass(android.graphics.Xfermode);
importClass(android.graphics.Paint);
importClass(android.graphics.Bitmap);
importClass(android.graphics.BitmapShader);
importClass(android.graphics.Shader);
importClass(android.graphics.Matrix);
importClass(android.graphics.PorterDuff);
ui.layout(
  <vertical margin="100">
    <View id="image" w="100" h="100" />
  </vertical>
);
imageView = ui.image;
let img = $images.read("./yashu.png");
bitmap = img.getBitmap();
const scale = context.getResources().getDisplayMetrics().density;
const dp2px = (dp) => Math.floor(dp * scale + 0.5);
ui.post(function () {
  var drawable = new android.graphics.drawable.Drawable({
    draw: function (canvas) {
      let paint = new Paint();
      radius = imageView.getWidth() / 2;
      bitmapShader = new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
      mScale = (radius * 2.0) / Math.min(bitmap.getHeight(), bitmap.getWidth());
      matrix = new Matrix();
      matrix.setScale(mScale, mScale);
      bitmapShader.setLocalMatrix(matrix);
      paint.setShader(bitmapShader);
      canvas.drawCircle(radius, radius, radius, paint);
    },
  });
  imageView.setBackgroundDrawable(drawable);
});
events.on("exit", function () {
  img.recycle();
});


第7种: 使用PorterDuffXfermode

实例化canvas时, 加入空图片作为实例参数,

然后绘制圆形, 再设置图层叠加模式为SRC_IN,


再绘制图片, 然后把canvas的画板内容保存为图片,

将该图片设置到img控件即可

"ui";
importClass(android.graphics.Rect);
importClass(android.graphics.RectF);
importClass(android.graphics.PorterDuffXfermode);
importClass(android.graphics.Path);
importClass(android.graphics.Xfermode);
importClass(android.graphics.Paint);
importClass(android.graphics.Bitmap);
importClass(android.graphics.PorterDuff);
ui.layout(
  <vertical margin="100">
    <img id="image" w="100" h="100" />
  </vertical>
);
imageView = ui.image;
let img = $images.read("./yashu.png");
bitmap = img.getBitmap();
const scale = context.getResources().getDisplayMetrics().density;
const dp2px = (dp) => Math.floor(dp * scale + 0.5);
let newImg;
ui.post(function () {
  let paint = new Paint();
  let mBitmap = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Bitmap.Config.ARGB_8888);
  let canvas = new Canvas(mBitmap);
  let rect = new Rect(0, 0, img.getWidth(), img.getWidth());
  let rectF = new RectF(rect);
  let ratio = 2;
  canvas.drawRoundRect(rectF, img.getWidth() / ratio, img.getWidth() / ratio, paint);
  paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
  let dst = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight()); //截取图片左上1/4的区域
  canvas.drawBitmap(bitmap, null, dst, paint);
  newImg = canvas.toImage();
  imageView.setImageBitmap(newImg.bitmap);
});
events.on("exit", function () {
  img.recycle();
  newImg && newImg.recycle();
});


名人名言


思路是最重要的, 其他的百度, bing, stackoverflow, github, 安卓文档, autojs文档, 最后才是群里问问
--- 牙叔教程


声明


部分内容来自网络
本教程仅用于学习, 禁止用于其他用途


相关文章
|
Windows
关于 Qt设置置顶窗口,透明部分显示黑色底色(已设置透明窗口) 的解决方法
关于 Qt设置置顶窗口,透明部分显示黑色底色(已设置透明窗口) 的解决方法
|
6月前
|
JavaScript
Elementplus淡入淡出效果,头部顶栏如何设置文字隐藏效果,默认图标如何收缩,icons如何通过类进行替换,侧边栏如何添加阴影,右边如何设置高度,侧边栏如何设置阴影,如何让icon与文字
Elementplus淡入淡出效果,头部顶栏如何设置文字隐藏效果,默认图标如何收缩,icons如何通过类进行替换,侧边栏如何添加阴影,右边如何设置高度,侧边栏如何设置阴影,如何让icon与文字
qrc-标签和按钮、调色板加载图片
qrc-标签和按钮、调色板加载图片
61 0
|
C++
duilib corner属性的贴图技巧——让图片自动贴到控件的的某一边或者一角并自适应控件的大小
转载请说明原出处,谢谢~~          Duilib给控件贴图功能可以附带多个属性,各个属性的配合可以达到许多效果。以下是duilib支持的所有贴图属性: 贴图描述:          Duilib的表现力丰富很大程度上得益于贴图描述的简单强大。
1833 0
|
JavaScript
Element-UI中Drawer抽屉去除标题自带黑色边框
Element-UI中Drawer抽屉去除标题自带黑色边框
|
前端开发 Android开发 数据格式
自定义圆形控件 RoundImageView
1、自定义圆形控件 RoundImageView package com.ronye.CustomView; import android.content.Context; import android.
1444 0
封装一个UILabel圆形边框显示进度
封装了一个UILabel并让它显示圆形的边框,UILabel上面显示百份比,而边框则用Animation绘制到整个圆占指定百分比的点。                                                                 这只是我个人想的继承一个UILabel实现的,用到两个CAShapeLayer,第一个Layer的作用是画出灰色的背影圆圈,第二个Layer位置放置在第一个Layer的上面,并设置为红色描绘颜色并描绘到插定的位置,之后实现相应的动画效果即可。
1067 0