2010-08-24 26 views
7

Tôi khá mới phát triển ứng dụng Android và tôi đã chơi xung quanh bằng cử chỉ vuốt bằng cách sử dụng SimpleOnGestureListener của Android và một ViewFlipper. Có 3 trẻ em của ViewFlipper, và mỗi là một ScrollView. Tất cả chúng đều được điền động khi Activity tải và sau đó chúng không thay đổi. ScrollView là nơi các SimpleOnGestureListeners được đính kèm.Chế độ xem cuộn không trượt khi quá ngắn để cuộn

Dưới đây là cách bố trí Tôi đang sử dụng:
+ ViewFlipper
++ scrollview (x3, một cho mỗi trang, mỗi với những điều sau :)
+++ LinearLayout (dọc)
++++ TextView
++++ TableLayout (động dân cư w/TableRows)
++++ Xem

tôi đã mở rộng phương pháp onFling với mã hướng dẫn chung bạn có thể tìm thấy ở bất cứ đâu trên mạng, và nó hoạt động tuyệt vời - trừ khi một trong những ScrollViews không chứa đủ nội dung để quét l.

Tôi đã thu hẹp sự cố xuống để chạm vào phát hiện bằng cách ghi đè và gọi siêu trên mọi phương thức của SimpleOnGestureListener để thêm bản in vào nhật ký.

Khi tôi vuốt trên trang cuộn, tôi nhận được nội dung đầy đủ "trong onClick" "trên onScroll" "trong onFling" vv Trên trang quá ngắn để cuộn, tôi nhận được "in onClick" "trong onShowPress "" trên onLongPress ", và đó là chỉ khi tôi chạm vào nội dung trong vòng con của scrollview quá ngắn - nếu tôi chạm vào nơi khác, tôi hoàn toàn không nhận được sự kiện nào.

Ý tưởng về những gì sai hoặc cách phát hiện cử chỉ vuốt dù ScrollView có lớn đến mức nào?

EDIT: Tôi đã xác định rằng khi tôi chạy ứng dụng này trên trình giả lập Android 2.2, trái với trình giả lập Android 2.1u1 DroidX tôi đã sử dụng, nó biến mất. Điều này có thể tái sản xuất trên nhiều môi trường.


Tôi có một số thông tin chi tiết hơn về điều này; có vẻ như onInterceptTouchEvent không được gọi cho mọi sự kiện chuyển động khi một scrollview được chứa trong một flipper (hoặc một WorkspaceView).

Đặc biệt, hành vi tôi thấy trong khi sửa đổi một lớp nhằm khắc phục vấn đề này rất giống nhau (nó không phải là duy nhất để chèo) là như sau - lưu ý rằng đây là Android 2.1 chỉ:

Nếu scrollview đủ dài để cuộn, sự kiện chuyển động ACTION_DOWN được cuộn bởi ScrollView và mọi sự kiện ACTION_MOVE tiếp theo đều trải qua onInterceptTouchEvent của trình kéo, nơi nó bị chặn và xử lý một cách thích hợp. Trong Android 2.2, hành vi này xảy ra bất kể độ dài cuộn.

Quay lại 2.1: Nếu cuộn không đủ dài để cuộn, sự kiện chuyển động ACTION_DOWN là không phải bị cuộn bởi chế độ xem cuộn, mà thay vào đó quay trở lại onTouchEvent của trình kéo. Tất cả các sự kiện ACTION_MOVE tiếp theo của cùng một cử chỉ bỏ qua hàm onInterceptTouchEvent và chuyển thẳng đến hàm onTouchEvent!

Cách tôi giải quyết vấn đề này là lấy chức năng tôi có trong onTouchEvent cho các sự kiện ACTION_MOVE và tái cấu trúc nó thành phương pháp riêng của nó. Bằng cách này, tôi có thể có onTouchEvent gọi onInterceptTouchEvent theo sau bởi chức năng đó nếu nó phát hiện rằng sự kiện trước đó đã bị hủy bỏ.

case MotionEvent.ACTION_MOVE: 

       if (touchState == TOUCH_STATE_SCROLLING) { 
        handleScrollMove(ev); 
       } else { 
    //    Log.d("workspace","caught a move touch event but not scrolling"); 
        //NOTE: We will never hit this case in Android 2.2. This is to fix a 2.1 bug. 
        //We need to do the work of interceptTouchEvent here because we don't intercept the move 
        //on children who don't scroll. 

        Log.d("workspace","handling move from onTouch"); 

        if(onInterceptTouchEvent(ev) && touchState == TOUCH_STATE_SCROLLING){ 
         handleScrollMove(ev); 
        } 

       } 

       break; 

Đây là từ WorkspaceView.java (một biến thể của Workspace.java của Android, tìm thấy tại dự án Andro-quan điểm trên google mã, và bây giờ ở đây: Horizontal "tab"ish scroll between views). Trong trường hợp chúng tôi nhận được sự kiện di chuyển và chúng tôi đang cuộn (điều này chỉ xảy ra nếu chúng tôi đã chọn cố ý chặn nó - tức là nó được đặt trong chức năng chặn, vì vậy chúng tôi đã thực hiện chức năng chặn), chúng tôi thực hiện hành vi di chuyển mà chúng ta mong muốn. Nếu chúng ta nhận được một sự kiện di chuyển ở đây và chúng ta không cuộn, thì chúng ta gửi sự kiện trở lại thông qua onIntercept, và sau đó xem liệu chúng ta có được thiết lập để cuộn hay không. Nếu vậy, chúng tôi thực hiện hành động.

Nó không thanh lịch, nhưng nó hoạt động!

Trả lời

7

tôi cần thiết để tạo ra một lớp mới mà mở rộng scrollview, và sử dụng này:.

@Override 
public boolean onTouchEvent(MotionEvent event) { 
    super.onTouchEvent(event); 
    return gestureDetector.onTouchEvent(event); 
} 

@Override 
public boolean dispatchTouchEvent(MotionEvent ev){ 
    gestureDetector.onTouchEvent(ev); 
    super.dispatchTouchEvent(ev); 
    return true; 
} 

Tôi không biết tại sao, nhưng nếu tôi cố gắng trả lại bất cứ điều gì nhưng đúng trong dispatchTouchEvent (điều hợp lý sẽ là

return (gestureDetector.onTouchEvent(ev) || super.dispatchTouchEvent(ev)); 

nếu tôi hiểu đúng), nó không hoạt động, và điều này có tác dụng.

1

Thử đặt android:fillViewport="true" trong bố cục xml của bạn cho từng số ScrollView s. Mà nói với các ScrollView là lớn như quan điểm nó chứa trong

+0

Nó được đặt như vậy trên tất cả các trẻ em. Tôi thậm chí đã sao chép trực tiếp và dán xml tại http://www.curious-creature.org/2010/08/15/scrollviews-handy-trick/?utm_source=feedburner&utm_medium=feed&utm_campaign=Feed:+PlanetAndroidCom+(Planet+Android) và đã thử nó như một đứa trẻ xem. Sau khi một số fiddling tôi quản lý để làm cho họ tất cả điền vào các viewport. Nhưng không may mắn về cuộc gọi lại ngay cả khi họ đã làm. Cho đến nay, không có scrollbar = no onFling. –

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