You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android自定义双进度条View触摸位置精度问题求助

Hey there! Let's work through this touch precision issue with your dual-progress custom View— I’ve dealt with similar wonky touch recognition problems before, so here’s what I’d check and fix step by step:

1. Fix Coordinate Conversion Logic

Most touch precision bugs stem from incorrect coordinate math. If you’re using MotionEvent.getX()/getY() directly without accounting for padding or the View’s usable area, you’ll get skewed progress calculations.

Adjust your touch coordinates to the View’s internal usable space first:

float touchX = event.getX() - getPaddingLeft();
float usableWidth = getWidth() - getPaddingLeft() - getPaddingRight();
float progressRatio = touchX / usableWidth;
// Clamp the ratio to 0-1 to avoid out-of-bounds progress
progressRatio = Math.max(0f, Math.min(1f, progressRatio));

This ensures even touches near the View’s edges map to valid progress values.

2. Add Touch Throttling for Jitter

System touch events can have tiny, unwanted jitters (especially during swipes). Adding a small threshold filters out these noise events and makes your interaction feel smoother:

private float lastTouchX;
private int minTouchThreshold;

@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
    super.onSizeChanged(w, h, oldw, oldh);
    // Convert 2dp to pixels for device-agnostic threshold
    minTouchThreshold = (int) TypedValue.applyDimension(
        TypedValue.COMPLEX_UNIT_DIP, 
        2, 
        getResources().getDisplayMetrics()
    );
}

@Override
public boolean onTouchEvent(MotionEvent event) {
    switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
            lastTouchX = event.getX();
            return true; // Claim the touch event to receive subsequent updates
        case MotionEvent.ACTION_MOVE:
            float deltaX = Math.abs(event.getX() - lastTouchX);
            if (deltaX >= minTouchThreshold) {
                updatePlaybackProgress(event.getX());
                lastTouchX = event.getX();
            }
            return true;
        // Handle ACTION_UP/ACTION_CANCEL as needed
    }
    return super.onTouchEvent(event);
}
3. Validate Touch Region

Sometimes touches are ignored because they fall outside the View’s intended interactive area (e.g., tapping too far above/below the progress bar). Add a check to ensure the touch is within your progress bar’s bounds:

@Override
public boolean onTouchEvent(MotionEvent event) {
    float touchY = event.getY();
    float usableHeight = getHeight() - getPaddingTop() - getPaddingBottom();
    
    // Reject touches outside the vertical bounds of the progress bar
    if (touchY < getPaddingTop() || touchY > getPaddingTop() + usableHeight) {
        return super.onTouchEvent(event);
    }
    
    // Proceed with horizontal touch logic...
}
4. Sync Red Dot Position with Touch Logic

If your progress indicator (red dot) isn’t aligning with touch positions, make sure its calculation uses the exact same math as your touch-to-progress conversion:

// Calculate red dot X position
float redDotX = getPaddingLeft() + (currentPlaybackProgress / maxProgress) * usableWidth;

// Calculate progress from touch (same variables!)
float playbackProgress = (touchX / usableWidth) * maxProgress;

Mismatched logic here is the #1 cause of "red dot is in the wrong place" bugs.

5. Hardware Acceleration (Last Resort)

In rare cases, hardware acceleration can skew touch coordinate precision for custom-drawn Views. If all else fails, disable it for your View:

<!-- In your layout -->
<com.yourpackage.DualProgressView
    android:id="@+id/dual_progress"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:hardwareAccelerated="false" />

Or in code:

setLayerType(View.LAYER_TYPE_SOFTWARE, null);

Note: This can hurt drawing performance, so only use it if the above fixes don’t work.

内容的提问来源于stack exchange,提问作者Basti

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 06:59:37