在Android开发的过程中有时候涉及到显示用户头像,不少APP上的用户头像都是显示的圆形,但是图片都是一般矩形,想要实现这种效果,使用原生的控件怕是比较难,可能会有两种想法,一种是把图片通过Bitmap进行处理,一种是自定义一个显示圆形头像的控件。如果每一张图片都用Bitmap处理,会造成资源浪费,自定义控件更简单一些。本来想偷个懒,百度里查了好久,没有找到我想要的方案,没办法,还是自力更生吧。如图:作图没考虑白色和背景灰白色不太明显,具体应用可自行调整。
values文件夹里随便选一个资源文件打开,或者新建一个attr.xml的文件,在
然后java重写ImageView代码:
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.RectF;
import android.util.AttributeSet;
import androidx.annotation.Nullable;
public class OvalfullProgress extends androidx.appcompat.widget.AppCompatImageView {
private Context context;
private Paint p;
private boolean ispro;
private int progress=0;
private int framecolor;
public OvalfullProgress(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
this.context=context;
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.OvalfullProgress);
progress=typedArray.getInt(R.styleable.OvalfullProgress_progress,0);
framecolor=typedArray.getColor(R.styleable.OvalfullProgress_framecolor,Color.WHITE);
ispro=typedArray.getBoolean(R.styleable.OvalfullProgress_isprogress,false);
typedArray.recycle();
init();
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
}
public void init(){
p = new Paint();
p.setAntiAlias(true);
// Shader shader=new BitmapShader(BitmapFactory.decodeResource(this.getResources(),R.drawable.app_icon),Shader.TileMode.REPEAT,Shader.TileMode.REPEAT);
// p.setShader(shader);//这里是用来填充不规则图形的方法,未用到
}
@SuppressWarnings("Duplicates")
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
p.setColor(framecolor);
p.setStrokeWidth(2);
p.setStrokeCap(Paint.Cap.ROUND);
Path path=new Path();
//这里设置路径的填充效果
//EVEN_ODD
//WINDING (默认值)
//INVERSE_EVEN_ODD
//INVERSE_WINDING
path.setFillType(Path.FillType.EVEN_ODD);
path.moveTo(0,0);
path.lineTo(canvas.getWidth(),0);
path.lineTo(canvas.getWidth(),canvas.getHeight());
path.lineTo(0,canvas.getHeight());
path.lineTo(0,0);
RectF f;
float cw=canvas.getWidth();
float ch=canvas.getHeight();
if(cw>ch){
f=new RectF(cw/2-ch/2,0,ch/2+cw/2,ch);
}else{
f=new RectF(0,ch/2-cw/2,cw,ch/2+cw/2);
}
path.addOval(f,Path.Direction.CW);
canvas.drawPath(path,p);
if(ispro==true){
int h1= (int) (ch-(ch*progress/100));
canvas.drawRect(0,0,cw,h1,p);
}
}
public void setProgress(int pro){
this.progress=pro;
if(progress>100) {
progress=100;
}else if(progress<0){
progress=0;
}
invalidate();
}
}
然后使用很简单,layout文件里
<包名.OvalfullProgress android:id="@+id/jindu" android:layout_width="200dp" android:layout_height="200dp" android:layout_below="@+id/center_a" android:layout_centerInParent="true" android:src="@color/blue" app:framecolor="@color/white" app:isprogress="true" />
android:src="@color/blue"放置展示图片
app:isprogress="true"头像框设置false或者不设置默认false,进度条设置true
app:framecolor="@color/white"边框颜色
这里给出操作进度条的方法,java调用代码:
OvalfullProgress jindu;jindu=findViewById(R.id.jindu); new CountDownTimer(10000, 100) { @Override public void onTick(long millisUntilFinished) { jindu.setProgress((int) (100-millisUntilFinished/100)); } @Override public void onFinish() { Toast.makeText(DrawPanel.this,"加载完成",Toast.LENGTH_SHORT).show(); } }.start();