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

Android如何用Canvas畫一個(gè)真正能跑的跑馬燈

 更新時(shí)間:2025年11月29日 14:14:32   作者:計(jì)蒙不吃魚  
網(wǎng)上的很多的教程都是通過更改TextView的屬性進(jìn)行跑馬燈的設(shè)計(jì),這樣做有很多的缺點(diǎn),下面這篇文章主要介紹了Android如何用Canvas畫一個(gè)真正能跑的跑馬燈,需要的朋友可以參考下

前言

以前自學(xué),都是用幀動(dòng)畫來實(shí)現(xiàn)跑馬燈,這幾天常失眠,晚上學(xué)東西也學(xué)不進(jìn),所以用Canvas寫個(gè)小Demo,這么無聊的應(yīng)該只有我一個(gè)了吧,廢話不多說,下面上內(nèi)容。

老規(guī)矩,最后有源碼

效果圖如下:

上代碼前先介紹下手機(jī)坐標(biāo)系,如下圖

然后是繪制草圖,如下:

大概思路為,開一個(gè)耗時(shí)線程使彩色背景旋轉(zhuǎn),來達(dá)到跑馬燈的效果。

核心:

1.計(jì)算出View寬高,矩形寬高,從而算出矩形的坐標(biāo)點(diǎn)。

int canvasWidth = canvas.getWidth();       //畫布寬度
        int canvasHeight = canvas.getHeight();     //畫布高度
        int canvansMax= (int) Math.sqrt(Math.pow(canvasWidth/2,2)+Math.pow(canvasHeight/2,2))+1; //正方形寬高的一半

2.繪制背景,跑馬燈,幕布

//開始繪制底層背景
        p.setColor(Color.WHITE);
        RectF oval2 = new RectF(0, 0, canvasWidth, canvasHeight);// 設(shè)置個(gè)新的長方形,掃描測量
        canvas.drawRect(oval2,p);
        //開始繪制跑馬燈
        Paint p1=new Paint(p);
        Shader mShader = new LinearGradient(canvasWidth/2-canvansMax,canvasHeight/2-canvansMax , 2*canvansMax, 2*canvansMax,
                new int[] { Color.RED, Color.GREEN,Color.CYAN,Color.MAGENTA,Color.GRAY,Color.BLUE,Color.YELLOW,Color.RED, Color.GREEN,Color.CYAN,Color.MAGENTA,Color.GRAY,Color.BLUE,Color.YELLOW}, null, Shader.TileMode.REPEAT); 
        p1.setShader(mShader);
        RectF oval = new RectF(canvasWidth/2-canvansMax,canvasHeight/2-canvansMax , 2*canvansMax, 2*canvansMax);// 設(shè)置個(gè)新的長方形
        canvas.drawRect(oval,p1);
        //繪制幕布
        Paint p2=new Paint();
        p2.setColor(Color.BLACK);
        RectF oval3 = new RectF(30, 30, canvasWidth-30, canvasHeight-30);// 設(shè)置個(gè)新的長方形,掃描測量
        canvas.drawRect(oval3,p2);

3.找到旋轉(zhuǎn)的依靠,并開啟一個(gè)耗時(shí)任務(wù)。

private Calendar mCalendar; // 時(shí)間對象
    public static final int START_CLOCK = 1000;// 開啟時(shí)鐘的標(biāo)識
    Handler mHandler = new Handler() {
        public void handleMessage(android.os.Message msg) {
            switch (msg.what) {
                case DrawView.START_CLOCK:
                    mCalendar = mCalendar.getInstance();
                    invalidate();
                    sendEmptyMessageDelayed(DrawView.START_CLOCK, 10);
                    break;
                case DrawView.STOP_CLOCK:
                    break;
                default:
                    break;
            }
        }
    };

4.設(shè)置彩色正方形旋轉(zhuǎn)

canvas.rotate(sec*100,canvasWidth/2,canvasHeight/2);

5.將幕布按照彩色正方形反向旋轉(zhuǎn)(不設(shè)置則跟著正方形一起旋轉(zhuǎn));

canvas.rotate(-sec*100,canvasWidth/2,canvasHeight/2);

源碼如下:1.完整java文件

public class MarqueeView extends View {
    private Calendar mCalendar; // 時(shí)間對象
    public static final int START_CLOCK = 1000;// 開啟時(shí)鐘的標(biāo)識
    Handler mHandler = new Handler() {
        public void handleMessage(android.os.Message msg) {
            switch (msg.what) {
                case DrawView.START_CLOCK:
                    mCalendar = mCalendar.getInstance();
                    invalidate();
                    sendEmptyMessageDelayed(DrawView.START_CLOCK, 10);
                    break;
                case DrawView.STOP_CLOCK:
                    break;
                default:
                    break;
            }
        }
    };

    public MarqueeView(Context context) {
        super(context);
    }

    public MarqueeView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        mCalendar = mCalendar.getInstance();
        if (mCalendar == null) {
            mCalendar = mCalendar.getInstance();
        }
        mHandler.sendEmptyMessage(START_CLOCK);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        drawAxis(canvas);
    }

    //繪制
    private void drawAxis(Canvas canvas){
        Paint p=new Paint();
        int canvasWidth = canvas.getWidth();       //畫布寬度
        int canvasHeight = canvas.getHeight();     //畫布高度
        int canvansMax= (int) Math.sqrt(Math.pow(canvasWidth/2,2)+Math.pow(canvasHeight/2,2))+1; //正方形寬高的一半
        int sec = mCalendar.get(Calendar.SECOND);//得到當(dāng)前秒數(shù)
        //開始繪制底層背景
        p.setColor(Color.WHITE);
        RectF oval2 = new RectF(0, 0, canvasWidth, canvasHeight);// 設(shè)置個(gè)新的長方形,掃描測量
        canvas.drawRect(oval2,p);
        canvas.rotate(sec*100,canvasWidth/2,canvasHeight/2);
        //開始繪制跑馬燈
        Paint p1=new Paint(p);
        Shader mShader = new LinearGradient(canvasWidth/2-canvansMax,canvasHeight/2-canvansMax , 2*canvansMax, 2*canvansMax,
                new int[] { Color.RED, Color.GREEN,Color.CYAN,Color.MAGENTA,Color.GRAY,Color.BLUE,Color.YELLOW,Color.RED, Color.GREEN,Color.CYAN,Color.MAGENTA,Color.GRAY,Color.BLUE,Color.YELLOW}, null, Shader.TileMode.REPEAT);
        p1.setShader(mShader);
        RectF oval = new RectF(canvasWidth/2-canvansMax,canvasHeight/2-canvansMax , 2*canvansMax, 2*canvansMax);// 設(shè)置個(gè)新的長方形,掃描測量
        canvas.drawRect(oval,p1);
        //繪制幕布
        Paint p2=new Paint();
        canvas.rotate(-sec*100,canvasWidth/2,canvasHeight/2);
        p2.setColor(Color.BLACK);
        RectF oval3 = new RectF(30, 30, canvasWidth-30, canvasHeight-30);// 設(shè)置個(gè)新的長方形,掃描測量
        canvas.drawRect(oval3,p2);


    }
}

2.xml中調(diào)用

<com................MarqueeView
    android:layout_width="match_parent"
    android:layout_height="match_parent"/>

總結(jié) 

到此這篇關(guān)于Android如何用Canvas畫一個(gè)真正能跑的跑馬燈的文章就介紹到這了,更多相關(guān)Android用Canvas畫跑馬燈內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Android利用ContentProvider初始化組件的踩坑記錄

    Android利用ContentProvider初始化組件的踩坑記錄

    做Android SDK開發(fā)的時(shí)候,一般我們會將初始化的方法封裝,然后讓調(diào)用SDK的開發(fā)者在Application的onCreate方法中進(jìn)行初始化,下面這篇文章主要給大家介紹了關(guān)于Android利用ContentProvider初始化組件的踩坑記錄,需要的朋友可以參考下
    2022-04-04
  • Android實(shí)現(xiàn)地理定位功能

    Android實(shí)現(xiàn)地理定位功能

    這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)地理定位功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-10-10
  • 如何從外部瀏覽開啟Android App

    如何從外部瀏覽開啟Android App

    從瀏覽器中點(diǎn)擊某個(gè)按鈕,如果手機(jī)上裝有相應(yīng)的app,則直接開啟app,并且到相對的頁面。如果沒有裝該app,則會到相應(yīng)的下載app的界面。這樣的功能怎么實(shí)現(xiàn)呢,本文帶著大家來看看如何實(shí)現(xiàn)。
    2021-06-06
  • Android ProgressDialog使用總結(jié)

    Android ProgressDialog使用總結(jié)

    ProgressDialog 繼承自AlertDialog,AlertDialog繼承自Dialog,實(shí)現(xiàn)DialogInterface接口,本文給大家介紹Android ProgressDialog使用總結(jié)的相關(guān)知識,需要的朋友通過此文一起學(xué)習(xí)吧
    2016-01-01
  • Android getActivity()為空的問題解決辦法

    Android getActivity()為空的問題解決辦法

    這篇文章主要介紹了Android getActivity()為空的問題解決辦法的相關(guān)資料,導(dǎo)致apk空指針崩潰問題,很嚴(yán)重的問題,為了解決這問題,上網(wǎng)搜索了很多資料,需要的朋友可以參考下
    2017-07-07
  • Android 讀取資源文件實(shí)例詳解

    Android 讀取資源文件實(shí)例詳解

    這篇文章主要介紹了Android 讀取資源文件實(shí)例詳解的相關(guān)資料,需要的朋友可以參考下
    2017-06-06
  • Android TextView 去掉自適應(yīng)默認(rèn)的fontpadding的實(shí)現(xiàn)方法

    Android TextView 去掉自適應(yīng)默認(rèn)的fontpadding的實(shí)現(xiàn)方法

    這篇文章主要介紹了Android TextView 去掉自適應(yīng)默認(rèn)的fontpadding的實(shí)現(xiàn)方法的相關(guān)資料,希望通過本文大家能夠掌握這部分內(nèi)容,需要的朋友可以參考下
    2017-09-09
  • 通過Jetpack Compose實(shí)現(xiàn)雙擊點(diǎn)贊動(dòng)畫效果

    通過Jetpack Compose實(shí)現(xiàn)雙擊點(diǎn)贊動(dòng)畫效果

    這篇文章主要介紹了如何利用Jetpack Compose實(shí)現(xiàn)雙擊點(diǎn)贊動(dòng)畫效果,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2022-01-01
  • Android編程實(shí)現(xiàn)自定義toast示例

    Android編程實(shí)現(xiàn)自定義toast示例

    這篇文章主要介紹了Android編程實(shí)現(xiàn)自定義toast,結(jié)合簡單實(shí)例形式分析了自定義布局toast核心實(shí)現(xiàn)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2017-01-01
  • Android頭像上傳功能的實(shí)現(xiàn)代碼(獲取頭像加剪切)

    Android頭像上傳功能的實(shí)現(xiàn)代碼(獲取頭像加剪切)

    最近在做一個(gè)頭像上傳的項(xiàng)目,下面小編給大家分享Android頭像上傳功能的實(shí)現(xiàn)代碼,需要的的朋友參考下吧
    2017-08-08

最新評論

陈巴尔虎旗| 鄂伦春自治旗| 湘潭县| 法库县| 昌黎县| 宜君县| 南岸区| 靖江市| 佛学| 启东市| 时尚| 阜南县| 义马市| 罗甸县| 类乌齐县| 乐清市| 石楼县| 临安市| 西峡县| 深圳市| 天等县| 来宾市| 福贡县| 万山特区| 什邡市| 永丰县| 泌阳县| 安吉县| 竹溪县| 高清| 永善县| 永定县| 青田县| 鹰潭市| 大关县| 芦溪县| 遵义市| 承德县| 中方县| 博野县| 江津市|