2011-01-13 28 views
10

Tôi có Hoạt động chứa ViewFlipper. ViewFlipper bao gồm 2 bố cục, cả hai đều chỉ là ListView.Sự cố khi phát hiện cử chỉ trên ListView

Vì vậy, ý tưởng ở đây là tôi có hai danh sách và để điều hướng từ danh sách này sang danh sách khác, tôi sẽ sử dụng vuốt ngang.

Tôi làm việc đó. Tuy nhiên, những gì bao giờ danh sách mục ngón tay của bạn là trên khi swipe bắt đầu thực hiện, mục đó cũng sẽ được dài nhấp.

Đây là mã có liên quan tôi có:

public class MyActivity extends Activity implements OnItemClickListener, OnClickListener { 

    private static final int SWIPE_MIN_DISTANCE = 120; 
    private static final int SWIPE_MAX_OFF_PATH = 250; 
    private static final int SWIPE_THRESHOLD_VELOCITY = 200; 

    private GestureDetector mGestureDetector; 
    View.OnTouchListener mGestureListener; 

    class MyGestureDetector extends SimpleOnGestureListener { 
     @Override 
     public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { 
      try { 
       if (Math.abs(e1.getY() - e2.getY()) > SWIPE_MAX_OFF_PATH) 
        return false; 
       // right to left swipe 
       if(e1.getX() - e2.getX() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) { 
        if (mCurrentScreen != SCREEN_SECONDLIST) { 
         mCurrentScreen = SCREEN_SECONDLIST; 
         mFlipper.setInAnimation(inFromRightAnimation()); 
         mFlipper.setOutAnimation(outToLeftAnimation()); 
         mFlipper.showNext(); 
         updateNavigationBar(); 
        } 
       } 
       else if (e2.getX() - e1.getX() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) { 
        if (mCurrentScreen != SCREEN_FIRSTLIST) { 
         mCurrentScreen = SCREEN_FIRSTLIST; 
         mFlipper.setInAnimation(inFromLeftAnimation()); 
         mFlipper.setOutAnimation(outToRightAnimation()); 
         mFlipper.showPrevious(); 
         updateNavigationBar(); 
        } 
       } 
      } catch (Exception e) { 
       // nothing 
      } 
      return true; 
     } 
    } 

    @Override 
    public boolean onTouchEvent(MotionEvent event) { 
     if (mGestureDetector.onTouchEvent(event)) 
      return true; 
     else 
      return false; 
    } 





    ViewFlipper mFlipper; 

    private int mCurrentScreen = SCREEN_FIRSTLIST; 

    private ListView mList1; 
    private ListView mList2; 

    /** Called when the activity is first created. */ 
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 

     requestWindowFeature(Window.FEATURE_NO_TITLE); 
     setContentView(R.layout.layout_flipper); 

     mFlipper = (ViewFlipper) findViewById(R.id.flipper); 

     mGestureDetector = new GestureDetector(new MyGestureDetector()); 
     mGestureListener = new View.OnTouchListener() { 
      public boolean onTouch(View v, MotionEvent event) { 
       if (mGestureDetector.onTouchEvent(event)) { 
        return true; 
       } 
       return false; 
      } 
     }; 

     // set up List1 screen 

     mList1List = (ListView)findViewById(R.id.list1); 
     mList1List.setOnItemClickListener(this); 
     mList1List.setOnTouchListener(mGestureListener); 

     // set up List2 screen 
     mList2List = (ListView)findViewById(R.id.list2); 
     mList2List.setOnItemClickListener(this); 
     mList2List.setOnTouchListener(mGestureListener); 

    } 

    … 
} 

Nếu tôi thay đổi "return true;" tuyên bố từ GestureDetector để "trả về false", tôi không nhận được nhấp chuột dài. Thật không may, tôi nhận được các nhấp chuột thông thường.

Có ai biết cách tôi có thể giải quyết vấn đề này không?

Trả lời

7

Chỉ cần để ném vào một câu trả lời hoàn toàn khác với một cách tiếp cận hoàn toàn khác nhau ...

Tôi đã thực hiện một cái nhìn tùy chỉnh được gọi SwipeView, đó là mã nguồn mở etc etc blah blah blah. Nó sẽ cho phép bạn làm những gì bạn muốn làm đơn giản như đi:

mSwipeView.addChild(myList1); 
mSwipeView.addChild(myList2); 

Bạn sẽ không cần phải mess về với dò cử chỉ hay bất cứ điều gì, và swipe nên theo ngón tay của bạn khi bạn làm điều đó .. .

(Điều này giống như một quảng cáo khủng khiếp khủng khiếp, xin vui lòng tha cho tôi.Đó là một ngày dài;)

Có một số liên kết tuyệt vời:

http://jasonfry.co.uk/?id=23

http://jasonfry.co.uk/?id=24

http://jasonfry.co.uk/?id=28

+0

Điều này tương tự như một thành phần mà tôi đã phát triển gần đây, ngoại trừ việc tôi thêm chế độ xem tái chế vào mỏ và được hỗ trợ bởi một listAdapter. Về cơ bản, tôi kanged một loạt các ListView mã và đính kèm nó vào một tùy chỉnh cử chỉ hướng HorizontalScrollView như bạn đã làm. – jfelectron

+0

Vâng, tôi cũng đang làm việc để thêm vào SwipeView! Ngoài ra, tôi chỉ (nghĩa đen chỉ, khoảng 2 phút trước) nhận thấy rằng có một lỗi với ListViews trên một SwipeView. Bây giờ tôi đã sửa lỗi và cập nhật git repo. https://github.com/fry15/uk.co.jasonfry.android.tools – jsonfry

+3

jfelectron là của bạn trên GIThub? –

0

[EDIT] Cào rằng, hoàn toàn sai.

Tôi nghĩ bạn sẽ phải cập nhật phần này và phát hiện xem bạn đã di chuyển sang trái hay sang phải và trả về true nếu bạn ở trạng thái vuốt. Hoặc ít nhất đó là nơi tôi sẽ nhìn đầu tiên.

mGestureListener = new View.OnTouchListener() { 
      public boolean onTouch(View v, MotionEvent event) { 
       if (mGestureDetector.onTouchEvent(event)) { 
        return true; 
       } 
       return false; 
      } 
     }; 

Tiếp tục ví dụ xấu của tôi, xin lỗi.

Trong onTouch tôi tin rằng bạn có thể kiểm tra event.getAction() và xác định xem một nhấp chuột dài đã xảy ra chưa. Nếu nó có, và của bạn trong một chuyển động flinging, sau đó trở lại đúng như để nắm bắt các nhấp chuột dài.

Sợ đây là đề xuất nhiều hơn câu trả lời cuối cùng.

Bạn cũng có thể kiểm tra phương pháp khác trên [phương pháp] mà bạn có thể ghi đè từ SimpleOnGestureListener. Chỉ cần chọn và

@Override 
public void onLongPress(MotionEvent e) { 
    // TODO Auto-generated method stub 
    super.onLongPress(e); 
} 

có thể là thứ bạn có thể thử nghiệm.

+0

Đó là những gì đang xảy ra. Hoặc là ví dụ của bạn những gì EDIT của bạn có ý định làm mất hiệu lực? – Andrew

+0

Xin lỗi, đây là một ví dụ khủng khiếp, đang khắc phục một vấn đề khác. Sẽ cố gắng và giải thích tốt hơn sau này. – Emile

1

Vì bạn đang sử dụng GestureDetector, điều cần làm là triển khai SimpleGestureDetector.onLongPress(MotionEvent e) để xử lý các nhấp chuột dài. Tuy nhiên, bạn không thể biết danh sách được nhấn lâu từ đó, vì vậy bạn cần nhớ nó từ số onItemLongClick() bình thường.

class MyGestureDetector extends SimpleOnGestureListener { 
    ... 
    @Override public void onLongPress(MotionEvent e) { 
     if (longClickedItem != -1) { 
      Toast.makeText(MainActivity.this, "Long click!", Toast.LENGTH_LONG).show(); 
     }   
    } 
} 

int longClickedItem = -1; 

@Override 
public boolean onItemLongClick(AdapterView<?> list, View view, int position, long id) { 
    longClickedItem = position; 
    return true; 
} 

@Override 
public boolean onTouchEvent(MotionEvent event) { 

    // Reset longclick item if new touch is starting 
    if (event.getAction()==MotionEvent.ACTION_DOWN) { 
     longClickedItem = -1; 
    } 

    if (mGestureDetector.onTouchEvent(event)) 
     return true; 
    else 
     return false; 
} 

Tôi đã thử nghiệm điều này và dường như hoạt động tốt.

+0

Cảm ơn bạn đã trả lời. Tôi sẽ cho nó nó một cơ hội. Tôi nên lưu ý rằng trong khi một báo chí dài là những gì đang được kích hoạt và là những gì tôi đã lưu ý, những gì tôi thực sự muốn xảy ra là không có cử chỉ bị rò rỉ nếu ai đó đang swiping. Có một số vấn đề khác, đặc biệt là với các điện thoại Android có thể thực hiện các hoạt ảnh cuối cùng của danh sách iPhone và những thứ như vậy. Vấn đề thực sự ở đây là swiping đang gửi các cử chỉ khác vào danh sách; và tôi không biết cách ngăn chặn điều đó. – Andrew

+0

Tôi vừa thử điều này và nó ngăn không cho nhấp chuột dài thực hiện khi tôi vuốt, mặc dù mục mà ngón tay của bạn bắt nguồn trên không làm nổi bật màu vàng; do đó, một số cử chỉ rõ ràng bị rò rỉ vào danh sách – Andrew

+0

Hãy thử gọi list.cancelLongPress() nếu máy dò cử chỉ trả về đúng ... –

1

Go bạn gestureDetector của bạn và thiết lập

mGestureDetector.setIsLongpressEnabled(false); 

Điều này sẽ ngăn chặn sự kiện báo chí dài bị phát hiện.

0

Tôi đã phát triển thành phần tùy chỉnh bắt nguồn từ horizontalScrollView thực hiện việc này. Tôi có listViews là chế độ xem con và vuốt mà không cần nhấn lâu. Nó được hỗ trợ bởi listAdapter, có thể là bất cứ thứ gì bạn muốn (ArrayAdapter, CursorAdapter ...) Nó nạp tối đa ba khung nhìn con và sau đó lật, chỉ hoán đổi chúng ở hai bên. Hầu hết điều này được kanged từ ListView và cần phải được refactored. Cách của nó quá dài để gửi trực tiếp tại đây.

http://pastie.org/1480091

0

Remove bạn getListView().setOnItemLongClickListener

Thêm vào bạn lớp MyGestureDetector:

public void onLongPress(MotionEvent e) { 
    final int position = getListView().pointToPosition((int) e.getX(), 
      (int) e.getY()); 
    // what you want do 
    super.onLongPress(e); 
} 
Các vấn đề liên quan