天天看點

Android開發自定義圓形頭像框以及圓形進度條完

在Android開發的過程中有時候涉及到顯示使用者頭像,不少APP上的使用者頭像都是顯示的圓形,但是圖檔都是一般矩形,想要實作這種效果,使用原生的控件怕是比較難,可能會有兩種想法,一種是把圖檔通過Bitmap進行處理,一種是自定義一個顯示圓形頭像的控件。如果每一張圖檔都用Bitmap處理,會造成資源浪費,自定義控件更簡單一些。本來想偷個懶,百度裡查了好久,沒有找到我想要的方案,沒辦法,還是自力更生吧。如圖:作圖沒考慮白色和背景灰白色不太明顯,具體應用可自行調整。

頭像框

Android開發自定義圓形頭像框以及圓形進度條完

                                           進度條

Android開發自定義圓形頭像框以及圓形進度條完

具體思路:

重寫ImageView控件,在表面畫一個充滿的矩形,然後中間挖去一個空心圓,這樣就把圖檔隻顯出一個圓形。我這裡把圓形頭像框以及圓形進度條整合到一起友善使用。

話不多說上幹貨。

values檔案夾裡随便選一個資源檔案打開,或者建立一個attr.xml的檔案,在<resources> </resources>中間加入如下代碼

<declare-styleable name="OvalfullProgress">
    <!--調試進度效果參數 -->
    <attr name="progress" format="integer"/>
    <!--邊框顔色-->
    <attr name="framecolor" format="reference"/>
    <!--頭像框false,進度條true-->
    <attr name="isprogress" format="boolean"/>
</declare-styleable>
           

然後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();
           

重點是調用  setProgress(int)方法,設定0~100.