欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

android 自定義view實(shí)現(xiàn)彩虹進(jìn)度條功能

 更新時(shí)間:2024年06月21日 10:20:21   作者:cyy298  
實(shí)現(xiàn)一個(gè)彩虹色進(jìn)度條功能,不說明具體用途大家應(yīng)該能猜到,想找別人造的輪子,但是沒有合適的,所以決定自己實(shí)現(xiàn)一個(gè),下面小編通過實(shí)例代碼給大家分享android 自定義view實(shí)現(xiàn)彩虹進(jìn)度條功能,感興趣的朋友一起看看吧

實(shí)現(xiàn)一個(gè)彩虹色進(jìn)度條功能,不說明具體用途大家應(yīng)該能猜到。想找別人造的輪子,但是沒有合適的,所以決定自己實(shí)現(xiàn)一個(gè)。

相關(guān)知識(shí)

android 自定義view

LinearGradient 線性漸變

實(shí)現(xiàn)步驟

自定義view

自定義一個(gè)TmcView類繼承View

重寫兩個(gè)構(gòu)造方法。構(gòu)造方法一共有4個(gè),這里邊重寫兩個(gè)

重寫ongSizeChanged方法,用來獲取控件寬、高,來計(jì)算內(nèi)部組件尺寸。

重寫onDraw方法,里邊要描畫背景drawBackground,分段數(shù)據(jù)drawSection,和seekbar圖片drawImage。

import android.content.Context;
import android.graphics.Canvas;
import android.util.AttributeSet;
import android.view.View;
import androidx.annotation.Nullable;
import java.util.List;
public class TmcView extends View {
    public TmcView(Context context) {
        super(context);
    }
    public TmcView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }
    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
    }
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        drawBackground(canvas);
        drawSection(canvas);
        drawImage(canvas);
    }
    /**
     * 畫背景
     * @param canvas 畫布
     */
    private void drawBackground(Canvas canvas) {
    }
    /**
     * 畫分段數(shù)據(jù)
     * @param canvas 畫布
     */
    private void drawSection(Canvas canvas) {
    }
    /**
     * 畫圖片
     * @param canvas 畫布
     */
    private void drawImage(Canvas canvas) {
    }
    /**
     * 更新view
     * @param total 總長(zhǎng)度
     * @param rest 剩余長(zhǎng)度
     * @param sections 分段數(shù)據(jù)
     */
    public void updateView(int total, int rest, List<SectionData> sections){
    }

實(shí)現(xiàn)幾個(gè)重構(gòu)方法

標(biāo)注:

整體寬度為圖片寬度44px

背景條寬度30px,外邊距7px,圓角15px

帶顏色的條寬度20xp,外邊距5px,圓角15px

自定義view的坐標(biāo)軸是以view的左上角位置為原點(diǎn),向右為x軸正方向,向下為y軸正方向

在視圖中用RectF創(chuàng)建背景,和顏色條,并在onSizeChanged中設(shè)置尺寸

public class TmcView extends View {
    private final RectF backgroundRectF = new RectF();
    private final RectF colorRectF = new RectF();
    public TmcView(Context context) {
        super(context);
    }
    public TmcView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }
    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        //設(shè)置矩形 left top right bottom 左上右下點(diǎn)的值  按照標(biāo)注計(jì)算得出
        backgroundRectF.set(7, 0, 37, h);
        colorRectF.set(12, 5, 32, h-5);
    }
    ...
}

繪制背景條

實(shí)現(xiàn)drawBackground方法,畫背景需要一根畫筆Paint 為了避免重復(fù)創(chuàng)建,聲明為成員變量

public class TmcView extends View {
    /*背景畫筆*/
    private final Paint backPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
    private final RectF backgroundRectF = new RectF();
    private final RectF colorRectF = new RectF();
    public TmcView(Context context) {
        super(context);
    }
    public TmcView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }
    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        //設(shè)置矩形 left top right bottom 左上右下點(diǎn)的值  按照標(biāo)注計(jì)算得出
        backgroundRectF.set(7, 0, 37, h);
        colorRectF.set(12, 5, 32, h-5);
    }
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        drawBackground(canvas);
        drawSection(canvas);
        drawImage(canvas);
    }
    /**
     * 畫背景
     * @param canvas 畫布
     */
    private void drawBackground(Canvas canvas) {
        backPaint.setStyle(Paint.Style.FILL);
        backPaint.setAntiAlias(true); //抗鋸齒
        backPaint.setColor(Color.parseColor("#FFFFFF"));
        //畫圓角矩形,15為圓角的角度
        canvas.drawRoundRect(backgroundRectF, 15, 15, backPaint);
    }
...
}

  布局中加入TmcView

<com.bigxuan.tesapp.view.TmcView
        android:id="@+id/tmc"
        android:layout_width="44px"
        android:layout_height="690px"
        android:layout_marginEnd="1230px"
        android:layout_marginBottom="100px"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        />

繪制顏色條

實(shí)現(xiàn)drawSection方法,這里要用到線性漸變LinearGradient

LinearGradient 簡(jiǎn)單說,指定每一段的顏色和位置百分比,就能實(shí)現(xiàn)每一段顯示不同顏色。

但它默認(rèn)是漸變色,要想不變就在每一段的開始和結(jié)束位置都設(shè)置相同的顏色。

再創(chuàng)建一個(gè)畫筆 Paint,畫顏色條

public class TmcView extends View {
    private final Paint backPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
    private final Paint colorPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
    private final RectF backgroundRectF = new RectF();
    private final RectF colorRectF = new RectF();
    public TmcView(Context context) {
        super(context);
    }
    public TmcView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }
    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        //設(shè)置矩形 left top right bottom 左上右下點(diǎn)的值  按照標(biāo)注計(jì)算得出
        backgroundRectF.set(7, 0, 37, h);
        colorRectF.set(12, 5, 32, h-5);
    }
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        drawBackground(canvas);
        drawSection(canvas);
        drawImage(canvas);
    }
    /**
     * 畫背景
     * @param canvas 畫布
     */
    private void drawBackground(Canvas canvas) {
        backPaint.setStyle(Paint.Style.FILL);
        backPaint.setAntiAlias(true); //抗鋸齒
        backPaint.setColor(Color.parseColor("#FFFFFF"));
        //畫圓角矩形,15為圓角的角度
        canvas.drawRoundRect(backgroundRectF, 15, 15, backPaint);
    }
    /**
     * 畫分段數(shù)據(jù)
     * @param canvas 畫布
     */
    private void drawSection(Canvas canvas) {
        int[] colorArray = {
                Color.parseColor("#FF0000"), Color.parseColor("#FF0000"),
                Color.parseColor("#00FF00"), Color.parseColor("#00FF00"),
                Color.parseColor("#0000FF"), Color.parseColor("#0000FF")
        };
        float[] positionArray = {
                0f, 0.2f,
                0.2f, 0.6f,
                0.6f, 1f
        };
        colorPaint.setStyle(Paint.Style.FILL);
        colorPaint.setAntiAlias(true);
        //指定漸變色方向x軸方向不變,沿y方向漸變,漸變范圍為 顏色條高度
        colorPaint.setShader(new LinearGradient(0, 0, 0, colorRectF.bottom, colorArray, positionArray, Shader.TileMode.REPEAT));
        canvas.drawRoundRect(colorRectF,15, 15, colorPaint);
    }
    ...
}

繪制進(jìn)度圖片

app加入圖片資源,根據(jù)資源id獲取bitmap對(duì)象,繪制。

需要注意的是,坐標(biāo)軸的頂點(diǎn)在左上角,繪制圖片時(shí)也是以圖片左上頂點(diǎn)位置做定位,圖片位置是view的高度減掉圖片的高度,才能顯示在正確位置。

public class TmcView extends View {
    private Context context;
    private final Paint backPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
    private final Paint colorPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
    private final RectF backgroundRectF = new RectF();
    private final RectF colorRectF = new RectF();
    /*圖片資源id*/
    private int imgResId;
    /*圖片位置*/
    private int imgPos;
    public TmcView(Context context) {
        super(context);
    }
    public TmcView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        this.context = context;
        this.imgResId = R.drawable.icon_seekbar_day;
    }
    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        //設(shè)置矩形 left top right bottom 左上右下點(diǎn)的值  按照標(biāo)注計(jì)算得出
        backgroundRectF.set(7, 0, 37, h);
        colorRectF.set(12, 5, 32, h-5);
        imgPos = h - 44; // 設(shè)置一個(gè)初始位置
    }
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        drawBackground(canvas);
        drawSection(canvas);
        drawImage(canvas);
    }
    /**
     * 畫背景
     * @param canvas 畫布
     */
    private void drawBackground(Canvas canvas) {
        backPaint.setStyle(Paint.Style.FILL);
        backPaint.setAntiAlias(true); //抗鋸齒
        backPaint.setColor(Color.parseColor("#FFFFFF"));
        //畫圓角矩形,15為圓角的角度
        canvas.drawRoundRect(backgroundRectF, 15, 15, backPaint);
    }
    /**
     * 畫分段數(shù)據(jù)
     * @param canvas 畫布
     */
    private void drawSection(Canvas canvas) {
        int[] colorArray = {
                Color.parseColor("#FF0000"), Color.parseColor("#FF0000"),
                Color.parseColor("#00FF00"), Color.parseColor("#00FF00"),
                Color.parseColor("#0000FF"), Color.parseColor("#0000FF")
        };
        float[] positionArray = {
                0f, 0.2f,
                0.2f, 0.6f,
                0.6f, 1f
        };
        colorPaint.setStyle(Paint.Style.FILL);
        colorPaint.setAntiAlias(true);
        //指定漸變色方向x軸方向不變,沿y方向漸變,漸變范圍為 顏色條高度
        colorPaint.setShader(new LinearGradient(0, 0, 0, colorRectF.bottom, colorArray, positionArray, Shader.TileMode.REPEAT));
        canvas.drawRoundRect(colorRectF,15, 15, colorPaint);
    }
    /**
     * 畫圖片
     * @param canvas 畫布
     */
    private void drawImage(Canvas canvas) {
        Bitmap bitmap = initBitmap(imgResId);
        canvas.save();
        canvas.translate(0, 0);
        canvas.drawBitmap(bitmap, 0, imgPos, null);
        canvas.restore();
    }
    /**
     * 通過資源id 創(chuàng)建bitmap
     * @param resId 資源id
     * @return
     */
    private Bitmap initBitmap(int resId) {
        Bitmap originalBmp = BitmapFactory.decodeResource(context.getResources(), resId);
        return Bitmap.createScaledBitmap(originalBmp, 44, 44, true);
    }
...
}

公共方法

暴露方法用來更新進(jìn)度updateView

定義一個(gè)圖片有效的運(yùn)動(dòng)距離為view高度減掉圖片高度,函數(shù)參數(shù)為總距離和剩余距離,計(jì)算百分比后乘以有效運(yùn)動(dòng)距離得出圖片描畫位置。最后調(diào)用invalidate方法刷新view

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.LinearGradient;
import android.graphics.Paint;
import android.graphics.RectF;
import android.graphics.Shader;
import android.util.AttributeSet;
import android.view.View;
import androidx.annotation.Nullable;
import com.navinfo.tesapp.R;
import java.util.List;
public class TmcView extends View {
    private Context context;
    private final Paint backPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
    private final Paint colorPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
    private final RectF backgroundRectF = new RectF();
    private final RectF colorRectF = new RectF();
    /*圖片資源id*/
    private int imgResId;
    /*圖片位置*/
    private int imgPos;
    /*圖片有效的運(yùn)動(dòng)距離*/
    private int imgValidHeight;
    public TmcView(Context context) {
        super(context);
    }
    public TmcView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        this.context = context;
        this.imgResId = R.drawable.icon_seekbar_day;
    }
    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        //設(shè)置矩形 left top right bottom 左上右下點(diǎn)的值  按照標(biāo)注計(jì)算得出
        backgroundRectF.set(7, 0, 37, h);
        colorRectF.set(12, 5, 32, h-5);
        imgValidHeight = h - 44;
        imgPos = h - 44; // 設(shè)置一個(gè)初始位置
    }
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        drawBackground(canvas);
        drawSection(canvas);
        drawImage(canvas);
    }
    /**
     * 畫背景
     * @param canvas 畫布
     */
    private void drawBackground(Canvas canvas) {
        backPaint.setStyle(Paint.Style.FILL);
        backPaint.setAntiAlias(true); //抗鋸齒
        backPaint.setColor(Color.parseColor("#FFFFFF"));
        //畫圓角矩形,15為圓角的角度
        canvas.drawRoundRect(backgroundRectF, 15, 15, backPaint);
    }
    /**
     * 畫分段數(shù)據(jù)
     * @param canvas 畫布
     */
    private void drawSection(Canvas canvas) {
        int[] colorArray = {
                Color.parseColor("#FF0000"), Color.parseColor("#FF0000"),
                Color.parseColor("#00FF00"), Color.parseColor("#00FF00"),
                Color.parseColor("#0000FF"), Color.parseColor("#0000FF")
        };
        float[] positionArray = {
                0f, 0.2f,
                0.2f, 0.6f,
                0.6f, 1f
        };
        colorPaint.setStyle(Paint.Style.FILL);
        colorPaint.setAntiAlias(true);
        //指定漸變色方向x軸方向不變,沿y方向漸變,漸變范圍為 顏色條高度
        colorPaint.setShader(new LinearGradient(0, 0, 0, colorRectF.bottom, colorArray, positionArray, Shader.TileMode.REPEAT));
        canvas.drawRoundRect(colorRectF,15, 15, colorPaint);
    }
    /**
     * 畫圖片
     * @param canvas 畫布
     */
    private void drawImage(Canvas canvas) {
        Bitmap bitmap = initBitmap(imgResId);
        canvas.save();
        canvas.translate(0, 0);
        canvas.drawBitmap(bitmap, 0, imgPos, null);
        canvas.restore();
    }
    /**
     *
     * @param resId
     * @return
     */
    private Bitmap initBitmap(int resId) {
        Bitmap originalBmp = BitmapFactory.decodeResource(context.getResources(), resId);
        return Bitmap.createScaledBitmap(originalBmp, 44, 44, true);
    }
    /**
     * 更新view
     * @param total 總長(zhǎng)度
     * @param rest 剩余長(zhǎng)度
     * @param sections 分段數(shù)據(jù)
     */
    public void updateView(int total, int rest, List<SectionData> sections){
        float percent = (1f * rest) / total;
        //防止溢出
        if(percent < 0){
            return;
        }
        imgPos = (int)(percent * imgValidHeight);
        invalidate();
    }
}

updateView方法還有第三個(gè)參數(shù),是用來傳出顏色條不同段的顏色和百分比數(shù)據(jù)的。根據(jù)此數(shù)據(jù)來更新顏色條。這里需要根據(jù)業(yè)務(wù)不同自己實(shí)現(xiàn),我這里就不寫了。

總結(jié)

        大家可能看出來了,這個(gè)視圖是用來展示導(dǎo)航中不同路段交通情況和當(dāng)前車輛進(jìn)度用的。自定義view中可以在構(gòu)造方法中獲取一些自定義屬性,像背景條和顏色條的邊距、圓角這些都可以定義到xml中,因?yàn)橹贿m配一種屏幕尺寸所以也沒有做多尺寸適配。以前也沒有做過,這次記錄下來。

相關(guān)文章

最新評(píng)論