首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

Android 自定義 View 入門指南:從繼承 View 到 onDraw 實戰

     編輯:程式設計綜合問答

核心步驟總覽

  1. 建立類別繼承 View(或 SurfaceView、TextureView)
  2. 實現構造函數(至少含 Context、Context, AttributeSet 兩個)
  3. 重寫 onMeasure(int, int) — 計算自身期望尺寸(可選,若不需自適應可跳過)
  4. 重寫 onDraw(Canvas) — **核心繪製邏輯**,建立 Paint、繪製圖形/文字/圖片
  5. (可選)重寫 onTouchEvent、onSizeChanged 等交互/生命週期方法
  6. 在 XML 或代碼中使用

最小可行範例:繪製一個帶邊框的圓

public class CircleView extends View {
    private final Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);

    public CircleView(Context context) { this(context, null); }
    public CircleView(Context context, AttributeSet attrs) { this(context, attrs, 0); }
    public CircleView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(attrs);
    }

    private void init(AttributeSet attrs) {
        paint.setStyle(Paint.Style.STROKE);
        paint.setStrokeWidth(dp2px(4));
        paint.setColor(Color.parseColor(\"#FF5722\")); // 深橙
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int desired = dp2px(100); // 預期 100dp 正方形
        int width = resolveSize(desired, widthMeasureSpec);
        int height = resolveSize(desired, heightMeasureSpec);
        setMeasuredDimension(width, height);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        int cx = getWidth() / 2;
        int cy = getHeight() / 2;
        int radius = Math.min(cx, cy) - paint.getStrokeWidth() / 2;
        canvas.drawCircle(cx, cy, radius, paint);
    }

    private int dp2px(int dp) {
        return (int) (dp * getResources().getDisplayMetrics().density + 0.5f);
    }
}

XML 使用

<com.example.customview.CircleView
    android:layout_width=\"wrap_content\"
    android:layout_height=\"wrap_content\"
    android:layout_gravity=\"center\" />

進階學習路徑

階段重點實作建議
入門Canvas 基礎繪製、Paint 設定、座標系畫時鐘、進度環、波浪球
進階Path/Region 複雜形狀、Shader 漸變、Bitmap 圖片處理、矩陣變換貝茲曲線簽名板、圖片濾鏡、摺疊動畫
高階自定義屬性、屬性動畫、硬體加速、SurfaceView 雙緩衝、OpenGL ES 互操作高性能圖表庫、遊戲引擎基礎渲染器

常見坑與避雷指南

  • 在 onDraw 中 new 物件 → 導致頻繁 GC 卡頓。**解決**:構造函數/初始化時建立 Paint、Path、RectF 等可複用物件。
  • 忽略 padding → 繪製區域被壓縮。**解決**:getPaddingLeft() 等計算實際繪製矩形。
  • onMeasure 不處理 MeasureSpec 模式 → 與父佈局協商失敗。**解決**:使用 resolveSize() 或自行解析 MeasureSpec.getMode/Size。
  • 觸摸事件未消費 → onTouchEvent 返回 false 導致父視圖攔截。**解決**:處理完返回 true。

推薦資源

總結

**自定義 View = 繼承 View + 構造函數 + onMeasure + onDraw**。先從簡單圖形入手,理解 Canvas 座標與 Paint 狀態,再逐步引入屬性動畫、觸摸交互、硬體加速。HenCoder 系列教程是公認最系統的中文進階資源。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved