2013-10-02 19 views
7

Tôi đã ghi đè ScrollView để chuyển MotionEvent s đến số GestureDetector để phát hiện các sự kiện chạy trên ScrollView. Tôi cần để có thể phát hiện khi di chuyển dừng lại. Điều này không trùng khớp với sự kiện MotionEvent.ACTION_UP vì sự kiện này thường xảy ra khi bắt đầu cử chỉ thoát, sau đó là một loạt các cuộc gọi onScrollChanged() trên ScrollView.Phát hiện kết thúc của fling trên ScrollView

Vì vậy, về cơ bản những gì chúng ta đang đối phó với ở đây là sự kiện sau đây:

  1. onFling
  2. onScrollChanged, onScrollChanged, onScrollChanged, ..., onScrollChanged

Không có callback cho khi sự kiện onScrollChanged được thực hiện bắn. Tôi đã nghĩ đến việc đăng một thông điệp lên hàng đợi sự kiện bằng cách sử dụng Handler trong khi onFling và chờ đợi cho Runnable thực thi để báo hiệu kết thúc của fling, tiếc là nó cháy sau cuộc gọi onScrollChanged đầu tiên.

Bất kỳ ý tưởng nào khác?

+0

Vâng, như tôi đã đề cập trong câu hỏi của tôi rằng cách tiếp cận không hoạt động. –

+0

Bạn đã xem/thử câu trả lời của tôi chưa? –

Trả lời

15

Tôi đã kết hợp một vài câu trả lời từ here để xây dựng trình nghe làm việc giống như cách AbsListView thực hiện. Đó là những gì bạn mô tả, và nó hoạt động tốt trong thử nghiệm của tôi.

Lưu ý: bạn chỉ cần ghi đè ScrollView.fling(int velocityY) thay vì sử dụng số GestureDetector của riêng mình.

import android.content.Context; 
import android.util.AttributeSet; 
import android.widget.ScrollView; 

public class CustomScrollView extends ScrollView { 

    private static final int DELAY_MILLIS = 100; 

    public interface OnFlingListener { 
     public void onFlingStarted(); 
     public void onFlingStopped(); 
    } 

    private OnFlingListener mFlingListener; 
    private Runnable mScrollChecker; 
    private int mPreviousPosition; 

    public CustomScrollView(Context context) { 
     this(context, null, 0); 
    } 

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

    public CustomScrollView(Context context, AttributeSet attrs, int defStyle) { 
     super(context, attrs, defStyle); 

     mScrollChecker = new Runnable() { 
      @Override 
      public void run() { 
       int position = getScrollY(); 
       if (mPreviousPosition - position == 0) { 
        mFlingListener.onFlingStopped(); 
        removeCallbacks(mScrollChecker); 
       } else { 
        mPreviousPosition = getScrollY(); 
        postDelayed(mScrollChecker, DELAY_MILLIS); 
       } 
      } 
     }; 
    } 

    @Override 
    public void fling(int velocityY) { 
     super.fling(velocityY); 

     if (mFlingListener != null) { 
      mFlingListener.onFlingStarted(); 
      post(mScrollChecker); 
     } 
    } 

    public OnFlingListener getOnFlingListener() { 
     return mFlingListener; 
    } 

    public void setOnFlingListener(OnFlingListener mOnFlingListener) { 
     this.mFlingListener = mOnFlingListener; 
    } 

} 
+0

Tôi chưa thử điều này, nhưng các thông báo liên tục trên chuỗi giao diện người dùng có thể là vấn đề hiệu suất không? –

+1

Xem xét điều này tương tự như cách thực hiện với 'Scroller' trong' AbsListView', tôi nghĩ bạn sẽ ổn. Họ thực sự cập nhật mỗi 40ms. Kiểm tra 'AbsListView.FlingRunnable' –

Các vấn đề liên quan