首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Android 自定義 View 實戰:觸控跟隨移動的小球組件

     編輯:Java 相關知識

效果預覽

一個紅色小球,跟隨手指觸摸滑動在屏幕上自由移動,且不會超出屏幕邊界。

核心類:DrawCircle

public class DrawCircle extends View {
    private int circleX = 100; // 圓心初始 X
    private int circleY = 100; // 圓心初始 Y
    private static final int RADIUS = 20;
    private int screenWidth, screenHeight;

    public DrawCircle(Context context) {
        this(context, null);
    }

    public DrawCircle(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public DrawCircle(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context);
    }

    private void init(Context context) {
        WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
        screenWidth = wm.getDefaultDisplay().getWidth();
        screenHeight = wm.getDefaultDisplay().getHeight();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        Paint paint = new Paint();
        paint.setColor(Color.RED);
        paint.setAntiAlias(true); // 抗鋸齒
        canvas.drawCircle(circleX, circleY, RADIUS, paint);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
            case MotionEvent.ACTION_MOVE:
            case MotionEvent.ACTION_UP:
                // 更新圓心座標為觸點座標
                circleX = (int) event.getX();
                circleY = (int) event.getY();
                break;
        }

        // 邊界約束:保證整個圓在可見區域內
        if (circleX >= RADIUS && circleX <= screenWidth - RADIUS &&
            circleY >= RADIUS && circleY <= screenHeight - RADIUS - 90) { // 90 為狀態欄/導航欄預留
            invalidate(); // 觸發重繪
        }

        return true; // 消費事件,不再向父佈局傳遞
    }
}

兩種引用方式

XML 布局引用(推薦)

<RelativeLayout xmlns:android="https://schemas.android.com/apk/res/android"
    android:id="@+id/rl"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <com.example.customview.DrawCircle
        android:id="@+id/circle"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

</RelativeLayout>

代碼動態添加

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        RelativeLayout container = findViewById(R.id.rl);
        DrawCircle circle = new DrawCircle(this);
        container.addView(circle);
    }
}

關鍵技術點總結

知識點實現細節
自定義 View 三大構造器覆寫三個構造器,統一調用 init(),兼容 XML/代碼兩種創建方式
繪製流程onDraw(Canvas) 中創建 Paint、設置顏色/抗鋸齒、調用 canvas.drawCircle()
觸摸事件處理重寫 onTouchEvent,處理 DOWN/MOVE/UP 統一更新座標,返回 true 表示消費事件
邊界約束根據屏幕寬高與圓半徑計算合法範圍,超出不調用 invalidate()
性能優化Paint 對象可提升為成員變量避免重複創建;invalidate() 僅在合法區域調用

進階擴展方向

  • 物理引擎:引入 VelocityTracker + Scroller 實現拋擲慣性滑動
  • 多點觸控:處理 ACTION_POINTER_DOWN/UP 支持多手指
  • 圖片替換:canvas.drawBitmap() 替換圓形,做拖拽頭像/貼紙
  • 邊界彈性:超出邊界時用 OverScroller 實現 iOS 風格回彈

總結

自定義 View 核心三步走:構造器初始化 → onDraw 繪製 → onTouchEvent 交互。本例通過 50 行核心代碼實現了完整的觸控跟隨組件,是 Android 自定義 View 入門的最佳練手項目。

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