Android自定義控制項之實現全新的View

来源:http://www.cnblogs.com/JarvisHuang/archive/2016/06/01/5550165.html
-Advertisement-
Play Games

當原生控制項不符合需求,並且進行拓展或組合也無濟於事的時候,就需要自己來繪製一個控制項了。<! more 全新的View 通過源碼,我們可以看到所有的控制項都是通過繼承View類來實現的。所以,我們要創建全新的控制項,也是要通過繼承View來實現。 案例 案例同樣來自《Android群英傳》。 繪製圓弧文本 ...


當原生控制項不符合需求,並且進行拓展或組合也無濟於事的時候,就需要自己來繪製一個控制項了。

全新的View

通過源碼,我們可以看到所有的控制項都是通過繼承View類來實現的。所以,我們要創建全新的控制項,也是要通過繼承View來實現。

案例

案例同樣來自《Android群英傳》。

繪製圓弧文本

唯恐文字描述有誤,先放上效果圖看看效果
圓弧效果圖

public class CircleProgressView extends View {
    private int mMeasureHeigth;
    private int mMeasureWidth;

    private Paint mCirclePaint;
    private float mCircleXY;
    private float mRadius;

    private Paint mArcPaint;
    private RectF mArcRectF;
    private float mSweepAngle;
    private float mSweepValue = 66;

    private Paint mTextPaint;
    private String mShowText;
    private float mShowTextSize;
    public CircleProgressView(Context context, AttributeSet attrs,
            int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    public CircleProgressView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

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

    @Override
    protected void onMeasure(int widthMeasureSpec,
            int heightMeasureSpec) {
        mMeasureWidth = MeasureSpec.getSize(widthMeasureSpec);
        mMeasureHeigth = MeasureSpec.getSize(heightMeasureSpec);
        setMeasuredDimension(mMeasureWidth, mMeasureHeigth);
        initView();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        // 繪製圓
        canvas.drawCircle(mCircleXY, mCircleXY, mRadius, mCirclePaint);
        // 繪製弧線
        canvas.drawArc(mArcRectF, 270, mSweepAngle, false, mArcPaint);
        // 繪製文字
        canvas.drawText(mShowText, 0, mShowText.length(),
                mCircleXY, mCircleXY + (mShowTextSize / 4), mTextPaint);
    }

    private void initView() {
        float length = 0;
        if (mMeasureHeigth >= mMeasureWidth) {
            length = mMeasureWidth;
        } else {
            length = mMeasureHeigth;
        }

        mCircleXY = length / 2;
        mRadius = (float) (length * 0.5 / 2);
        mCirclePaint = new Paint();
        mCirclePaint.setAntiAlias(true);
        mCirclePaint.setColor(getResources().getColor(
                android.R.color.holo_blue_bright));

        mArcRectF = new RectF(
                (float) (length * 0.1),
                (float) (length * 0.1),
                (float) (length * 0.9),
                (float) (length * 0.9));
        mSweepAngle = (mSweepValue / 100f) * 360f;
        mArcPaint = new Paint();
        mArcPaint.setAntiAlias(true);
        mArcPaint.setColor(getResources().getColor(
                android.R.color.holo_blue_bright));
        mArcPaint.setStrokeWidth((float) (length * 0.1));
        mArcPaint.setStyle(Style.STROKE);

        mShowText = setShowText();
        mShowTextSize = setShowTextSize();
        mTextPaint = new Paint();
        mTextPaint.setTextSize(mShowTextSize);
        mTextPaint.setTextAlign(Paint.Align.CENTER);
        
    }

    private float setShowTextSize() {
        this.invalidate();
        return 50;
    }

    private String setShowText() {
        this.invalidate();
        return "ANDROID SKILL";
    }

    public void forceInvalidate() {
        this.invalidate();
    }

    public void setSweepValue(float sweepValue) {
        if (sweepValue != 0) {
            mSweepValue = sweepValue;
        } else {
            mSweepValue = 25;
        }
        this.invalidate();
    }
}

動態音頻條形圖

音頻條形圖效果圖

public class CustomView extends View {

    private int mRectCount;
    private Paint mPaint;
    private int mRectHeight;
    private int offset = 5;
    private int mWidth;
    private double mRandom;
    private int mRectWidth;
    public CustomView(Context context) {
        super(context);
        initView();
    }
    public CustomView(Context context, AttributeSet attrs) {
        super(context, attrs);
        initView();
    }
    public CustomView(Context context, AttributeSet attrs,
            int defStyleAttr) {
        super(context, attrs,defStyleAttr);
        initView();
    }
    private void initView() {
        mPaint = new Paint();
        mPaint.setColor(Color.BLUE);
        mPaint.setStyle(Paint.Style.FILL);
        mRectCount = 12;        
    }
    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        mWidth = getWidth();
        mRectHeight = getHeight();
        mRectWidth = (int)(mWidth * 0.6 / mRectCount);
        LinearGradient mLinearGradient = new LinearGradient(
                0,
                0,
                mRectWidth,
                mRectHeight,
                Color.RED,
                Color.BLUE,
                Shader.TileMode.CLAMP
                );  
        mPaint.setShader(mLinearGradient);
    }
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        for (int i = 0; i < mRectCount; i++) {
            mRandom = Math.random();
            //每個條形的高
            float currentHeight = (float) (mRectHeight * mRandom);
            canvas.drawRect(
                    (float) (mWidth * 0.4 / 2 + mRectWidth * i + offset),
                    currentHeight,
                    (float) (mWidth * 0.4 / 2 + mRectWidth * (i + 1)),
                    mRectHeight,
                    mPaint);
        }
        //延遲重繪
        postInvalidateDelayed(300);

    }
}

自己創建的控制項用法與原生控制項大同小異,可進行參照。

更多文章也可關註我的靜態博客,更新相對會優先些傳送門


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 做過的大大小小的 .NET Web 項目如下: (1)售樓系統產品 「Role: Team Member」 (2)中弘合同管理系統 「Role: Team Member」 (3)Gammon Portal 金門建築內部門戶 「Role: Team Leader」 (4)Hopewell Portal ...
  • 詳細的圖文可以到我的百度經驗去查看:http://jingyan.baidu.com/article/cd4c2979eda109756e6e60de.html 首先是註冊頁面的佈局: ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 2 ...
  • 本文主要介紹android中如何在外部存儲讀寫數據 sd卡的路徑 sdcard:2.3之前的sd卡路徑 mnt/sdcard:4.3之前的sd卡路徑 storage/sdcard:4.3之後的sd卡路徑 打開file explorer 可以看到sdcard是個空的文件夾,因為這個文件夾是個快捷方式, ...
  • 摘自知乎http://www.zhihu.com/question/20326729 來源:知乎著作權歸作者所有。商業轉載請聯繫作者獲得授權,非商業轉載請註明出處。 首先如果你小團隊或者個人開發,當然可以用Xcode,如果大公司跨部門審核調整各種,還是有個快速的原型。 如你要求,可交互。包括常用的A ...
  • 效果圖 1. 導入 .aar 2. fragment_line_chart.xml ...
  • 最近看視頻瞭解了一下應用程式的啟動原理,這裡就做一個博客和大家分享一下,相互討論,如果有什麼補充或不同的意見可以提出來! 1、程式入口 眾所周知,一個應用程式的入口一般是一個 main 函數,iOS也不例外,在工程的 Supporting Files 文件夾中你可以找到main.m,他就是程式的入口 ...
  • cordova plugin add org.apache.cordova.vibration cordova plugin add https://github.com/katzer/cordova-plugin-local-notifications cordova plugin add cor ...
  • MVP是從MVC演變過來的。M即Model層負責提供數據,V即View層負責顯示,P指Presenter層負責邏輯處理。在MVP中View不直接使用Model,它們通過Presenter來通信,它們之間的交互都在Presenter內部進行。實現了View和Model的耦合。<! more 在MVP中 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...