最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

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

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

相關(guān)知識

android 自定義view

LinearGradient 線性漸變

實現(xiàn)步驟

自定義view

自定義一個TmcView類繼承View

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

重寫ongSizeChanged方法,用來獲取控件寬、高,來計算內(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 總長度
     * @param rest 剩余長度
     * @param sections 分段數(shù)據(jù)
     */
    public void updateView(int total, int rest, List<SectionData> sections){
    }

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

標(biāo)注:

整體寬度為圖片寬度44px

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

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

自定義view的坐標(biāo)軸是以view的左上角位置為原點,向右為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 左上右下點的值  按照標(biāo)注計算得出
        backgroundRectF.set(7, 0, 37, h);
        colorRectF.set(12, 5, 32, h-5);
    }
    ...
}

繪制背景條

實現(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 左上右下點的值  按照標(biāo)注計算得出
        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"
        />

繪制顏色條

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

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

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

再創(chuàng)建一個畫筆 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 左上右下點的值  按照標(biāo)注計算得出
        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對象,繪制。

需要注意的是,坐標(biāo)軸的頂點在左上角,繪制圖片時也是以圖片左上頂點位置做定位,圖片位置是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 左上右下點的值  按照標(biāo)注計算得出
        backgroundRectF.set(7, 0, 37, h);
        colorRectF.set(12, 5, 32, h-5);
        imgPos = h - 44; // 設(shè)置一個初始位置
    }
    @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

定義一個圖片有效的運動距離為view高度減掉圖片高度,函數(shù)參數(shù)為總距離和剩余距離,計算百分比后乘以有效運動距離得出圖片描畫位置。最后調(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;
    /*圖片有效的運動距離*/
    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 左上右下點的值  按照標(biāo)注計算得出
        backgroundRectF.set(7, 0, 37, h);
        colorRectF.set(12, 5, 32, h-5);
        imgValidHeight = h - 44;
        imgPos = h - 44; // 設(shè)置一個初始位置
    }
    @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 總長度
     * @param rest 剩余長度
     * @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方法還有第三個參數(shù),是用來傳出顏色條不同段的顏色和百分比數(shù)據(jù)的。根據(jù)此數(shù)據(jù)來更新顏色條。這里需要根據(jù)業(yè)務(wù)不同自己實現(xiàn),我這里就不寫了。

總結(jié)

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

相關(guān)文章

  • Android TV 焦點框移動的實現(xiàn)方法

    Android TV 焦點框移動的實現(xiàn)方法

    本篇文章主要介紹了Android TV 焦點框移動的實現(xiàn)方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-06-06
  • Android項目遷移到AndroidX的方法步驟

    Android項目遷移到AndroidX的方法步驟

    這篇文章主要介紹了Android項目遷移到AndroidX的方法步驟,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-12-12
  • Android實現(xiàn)文字消除效果

    Android實現(xiàn)文字消除效果

    由于項目和語音識別相關(guān),有時候人在不經(jīng)意間交流的無效音頻會被識別出來,并展示于界面,為了美觀,客戶要求我們將這些無效的識別文本用一個從右到左的動畫給清除,于是便有了下述的技術(shù)實現(xiàn)。感興趣的朋友可以參考下
    2021-06-06
  • Android開發(fā)中Google為什么不讓用Handler的runWithScissors()

    Android開發(fā)中Google為什么不讓用Handler的runWithScissors()

    這篇文章主要介紹了Android開發(fā)中Google為什么不讓用Handler的runWithScissors(),本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-09-09
  • Android仿微信朋友圈實現(xiàn)滾動條下拉反彈效果

    Android仿微信朋友圈實現(xiàn)滾動條下拉反彈效果

    這篇文章主要為大家介紹了Android仿微信朋友圈實現(xiàn)滾動條下拉反彈效果,感興趣的小伙伴們可以參考一下
    2016-01-01
  • Android Handler中的休眠喚醒實現(xiàn)詳解

    Android Handler中的休眠喚醒實現(xiàn)詳解

    這篇文章主要為大家介紹了Android Handler中的休眠喚醒實現(xiàn)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-01-01
  • Flutter開發(fā)技巧RadialGradient中radius計算詳解

    Flutter開發(fā)技巧RadialGradient中radius計算詳解

    這篇文章主要為大家介紹了Flutter小技巧RadialGradient?中?radius?的計算詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-01-01
  • Android圖片上傳實現(xiàn)預(yù)覽效果

    Android圖片上傳實現(xiàn)預(yù)覽效果

    這篇文章主要介紹了Android圖片上傳實現(xiàn)預(yù)覽效果的相關(guān)資料,需要的朋友可以參考下
    2016-01-01
  • Android 應(yīng)用APP加入聊天功能

    Android 應(yīng)用APP加入聊天功能

    本文主要給大家介紹的是如何一步步的實現(xiàn)Android應(yīng)用APP中加入聊天功能,十分的細(xì)致全面,有相同需求的小伙伴快來參考下吧。
    2015-03-03
  • android界面布局之實現(xiàn)文本塊布局效果示例

    android界面布局之實現(xiàn)文本塊布局效果示例

    這篇文章主要介紹了android實現(xiàn)文本塊布局效果示例,需要的朋友可以參考下
    2014-04-04

最新評論

武胜县| 澳门| 东山县| 平果县| 临夏市| 青龙| 裕民县| 曲阳县| 南雄市| 荥经县| 台东市| 耿马| 井冈山市| 广河县| 商都县| 厦门市| 东阳市| 醴陵市| 偃师市| 衢州市| 曲沃县| 盐山县| 长宁区| 海晏县| 屯门区| 晋中市| 抚松县| 桃园县| 阳山县| 万年县| 淳安县| 凌源市| 棋牌| 香港| 朝阳县| 托里县| 新蔡县| 三亚市| 抚州市| 喀喇沁旗| 盐山县|