牙叔教程 简单易懂
效果展示
环境
手机: 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文档, 最后才是群里问问
--- 牙叔教程
声明
部分内容来自网络
本教程仅用于学习, 禁止用于其他用途