圓形頭像的7種顯示方法

牙叔教程 簡單易懂

效果展示

效果.png

環(huán)境

手機: 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的大小實際上依然是矩形,并且設置的圖片實際上也是矩形的,只是圓形以外的區(qū)域是透明色。

如果根據(jù)view大小來生成對應的陰影,就會出現(xiàn)很奇怪的效果,(一個看起來圓形的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種: 繪制控件時, 將顯示區(qū)域裁剪為一個圓形,

使用setBackgroundDrawable給控件設置背景, 在draw事件發(fā)生時, 裁剪畫板為圓形即可,
重寫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的區(qū)域
      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時, 加入空圖片作為實例參數(shù),
然后繪制圓形, 再設置圖層疊加模式為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的區(qū)域
  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文檔, 最后才是群里問問
--- 牙叔教程

聲明

部分內容來自網絡
本教程僅用于學習, 禁止用于其他用途

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容