2013-09-06 76 views
13

Tôi muốn tắt tính năng vuốt nhưng chỉ ở bên phải. Tôi tìm thấy giải pháp làm việc trong câu trả lời this. Thật không may, điều này sao chép toàn bộ nguồn ViewPager để đạt được mục tiêu. Có phương pháp nào kế thừa lớp hiện tại và không sao chép không?ViewPager tắt tính năng vuốt theo một hướng nhất định

+0

Bạn có bị ràng buộc sử dụng ViewPager vani không? – Shark

+0

Nếu có một lib có chứa một 'ViewPager' với hành vi này, tôi có thể sử dụng nó BTW. Lưu ý rằng tôi muốn tự động bật và tắt tính năng vuốt sang phải, không chỉ vô hiệu hóa tính năng này một cách tĩnh. – WonderCsabo

+0

Tôi cho rằng bạn có thể thử overTidingEouchEvent hoặc onInterceptTouchEvent và cố gắng lọc ra các sự kiện cảm ứng mà bạn không muốn nó phản hồi (và gọi siêu cho phần còn lại). – Karakuri

Trả lời

19

Tôi không chắc chắn đây là chính xác những gì bạn cần: Tôi cần một người xem cho trình hướng dẫn có trang tối đa mà người dùng không thể chuyển.

Cuối cùng, giải pháp nằm trong bộ điều hợp. tôi đã thay đổi số lượng của PagerAdapter và cách này khối người sử dụng từ đi qua các trang tối đa:

@Override 
public int getCount() { 
    return mProgress; //max page + 1 
} 

Khi người sử dụng tiến triển đến trang tiếp theo:

private void setWizardProgress(int progress) { 
    if(progress > mProgress) { 
     mProgress = progress; 
     mWizardPagerAdapter.notifyDataSetChanged(); 
    } 
} 

Bằng cách này khi người dùng đang ở trang tối đa anh ta không thể cuộn sang phải.

+1

Cảm ơn! Đây là một câu hỏi cũ, tôi đã giải quyết vấn đề này (thông qua việc giảm 'ViewPager' và sử dụng các hoạt ảnh' Fragment' để tôi có thể kiểm soát hoàn toàn luồng). Tôi nghĩ rằng bạn là một giải pháp tốt, vì vậy tôi chấp nhận nó. :) – WonderCsabo

-2

Bạn phải tạo lớp con ViewPager của riêng bạn và ghi đè lên các chức năng canScrollHorizontally

http://developer.android.com/reference/android/support/v4/view/ViewPager.html#canScrollHorizontally(int)

+3

Tôi chỉ cố gắng, canScrollHorizontally không bao giờ được gọi. : S – WonderCsabo

+0

Sau đó thử phương pháp canScroll, tôi sử dụng nó và nó được gọi là – viplezer

+0

không bao giờ được gọi là – Thomas

5

Bạn có thể thử như sau:

Bước 1: Tạo một lớp tùy chỉnh mới nói "CustomViewPager". Lớp kế thừa từ "ViewPager" và bao gồm phương thức tùy chỉnh mới được gọi là "setPagingEnabled" với mục đích bật/tắt tính năng vuốt, tùy theo yêu cầu.

Bước 2: Ghi đè hai phương thức: "onTouchEvent" và "onInterceptTouchEvent". Cả hai sẽ trả về "false" nếu phân trang được tắt hoàn toàn.

Bước 3: Thay thế "ViewPager" tag vào file layout với lớp tùy chỉnh:

<package_name.customviewpager 
    android:id="@+id/customViewPager" 
    android:layout_height="match_parent" 
    android:layout_width="match_parent" /> 

Bước 4: CustomViewPager.java

public class CustomViewPager extends ViewPager { 

private boolean enabled; 

public CustomViewPager(Context context, AttributeSet attrs) { 
    super(context, attrs); 
    this.enabled = true; 
} 

@Override 
public boolean onTouchEvent(MotionEvent event) { 
    if (this.enabled && detectSwipeToRight(event)) { 
     return super.onTouchEvent(event); 
    } 

    return false; 
} 

@Override 
public boolean onInterceptTouchEvent(MotionEvent event) { 
    if (this.enabled && detectSwipeToRight(event)) { 
     return super.onInterceptTouchEvent(event); 
    } 

    return false; 
} 

// To enable/disable swipe 
public void setPagingEnabled(boolean enabled) { 
    this.enabled = enabled; 
} 

// Detects the direction of swipe. Right or left. 
// Returns true if swipe is in right direction 
public boolean detectSwipeToRight(MotionEvent event){ 

int initialXValue = 0; // as we have to detect swipe to right 
final int SWIPE_THRESHOLD = 100; // detect swipe 
boolean result = false; 

     try {     
      float diffX = event.getX() - initialXValue; 

       if (Math.abs(diffX) > SWIPE_THRESHOLD) { 
        if (diffX > 0) { 
         // swipe from left to right detected ie.SwipeRight 
         result = false; 
        } else { 
         // swipe from right to left detected ie.SwipeLeft 
         result = true; 
        } 
       } 
      } 
     catch (Exception exception) { 
      exception.printStackTrace(); 
     } 
     return result; 
    } 
} 
+1

Cảm ơn! Vui lòng xem lại mã của bạn, nó không biên dịch! – WonderCsabo

+0

ya, tôi đã cập nhật bài đăng của mình. –

+3

Tôi đã thử câu trả lời cập nhật. 'diffX' luôn tích cực, vì vậy phương thức không bao giờ trả về' true'. – WonderCsabo

1
private float initialXValue; 
@Override 
public boolean onTouchEvent(MotionEvent event) { 
    if (this.mEnabled) { 
     return super.onTouchEvent(event); 
    } 
    if(event.getAction()==MotionEvent.ACTION_DOWN){ 
     initialXValue = event.getX(); 
    }else if(event.getAction()==MotionEvent.ACTION_MOVE){ 
     if(detectSwipeToRight(event)){ 
      System.out.println("right swipe detected"); 
     } 
    } 
    return true; 
} 

private boolean detectSwipeToRight(MotionEvent event) { 
    final int SWIPE_THRESHOLD = 100; // detect swipe 
    boolean result = false; 

    try { 
     float diffX = event.getX() - initialXValue; 
     if (Math.abs(diffX) > SWIPE_THRESHOLD) { 
      if (diffX < 0) { 
       // swipe from right to left detected ie.SwipeLeft 
       result = true; 
      } 
     } 
    } catch (Exception exception) { 
     exception.printStackTrace(); 
    } 
    return result; 
} 
+1

Điều này sẽ là một câu trả lời tốt hơn nhiều nếu bạn giải thích mã nhiều hơn một chút. – skrrgwasme

0

Bạn có thể sử dụng các phương pháp beginFakeDrag()endFakeDrag().

beginFakeDrag() khi bạn muốn tắt thao tác vuốt và endFakeDrag() nếu bạn muốn bật lại.

Như thế này: viewPager.beginFakeDrag();

+1

Không, sẽ không hoạt động ... Nó vẫn cuộn một chút ... – ichalos

13

đây đang làm việc lớp ViewPager với khả năng vô hiệu hóa bất kỳ phân trang hướng. Khám phá tất cả answer here.

public class CustomViewPager extends ViewPager { 
    private float initialXValue; 
    private SwipeDirection direction; 

    public CustomViewPager(Context context, AttributeSet attrs) { 
     super(context, attrs); 
     this.direction = SwipeDirection.all; 
    } 

    @Override 
    public boolean onTouchEvent(MotionEvent event) { 
     if (this.IsSwipeAllowed(event)) { 
      return super.onTouchEvent(event); 
     } 

     return false; 
    } 

    @Override 
    public boolean onInterceptTouchEvent(MotionEvent event) { 
     if (this.IsSwipeAllowed(event)) { 
      return super.onInterceptTouchEvent(event); 
     } 

     return false; 
    } 

    private boolean IsSwipeAllowed(MotionEvent event) { 
     if(this.direction == SwipeDirection.all) return true; 

     if(direction == SwipeDirection.none)//disable any swipe 
      return false; 

     if(event.getAction()==MotionEvent.ACTION_DOWN) { 
      initialXValue = event.getX(); 
      return true; 
     } 

     if(event.getAction()==MotionEvent.ACTION_MOVE) { 
      try { 
       float diffX = event.getX() - initialXValue; 
       if (diffX > 0 && direction == SwipeDirection.right) { 
        // swipe from left to right detected 
        return false; 
       }else if (diffX < 0 && direction == SwipeDirection.left) { 
        // swipe from right to left detected 
        return false; 
       } 
      } catch (Exception exception) { 
       exception.printStackTrace(); 
      } 
     } 

     return true; 
    } 

    public void setAllowedSwipeDirection(SwipeDirection direction) { 
     this.direction = direction; 
    } 
+0

Điều này thực sự hiệu quả. (Mặc dù kiểu dáng cú pháp rất xấu) – vedant1811

+0

@ vedant1811 điều gì tệ hại đến tôi? – lelloman

+0

@lelloman có thể có nghĩa là thiếu autoformat, IsSwipeAllowed với một chữ cái lớn đầu tiên, try-catch mà không có ngoại lệ được ném và cũng printStackTrace ở đó, và "này" ở những nơi không cần thiết (và các phương pháp overriden thực sự có thể được inlined). Nhưng câu trả lời là hữu ích anyway. – 0101100101

6

Một cách đơn giản khác là sử dụng setCurrentItem() để cuộn lại trang trình bày mong muốn nếu bạn nhấn vào một vị trí nhất định.Ví dụ, điều này sẽ chỉ cho phép chuyển tiếp swiping:

mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { 
    @Override 
    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {} 

    @Override 
    public void onPageSelected(int position) { 
     if(position < mProgress) { 
      mViewPager.setCurrentItem(mProgress, true); 
     } else { 
      mProgress = position; 
     } 
    } 

    @Override 
    public void onPageScrollStateChanged(int state) {} 
}); 

Hoặc nếu bạn muốn có một slide tối đa:

if(position > 4) { 
    mViewPager.setCurrentItem(4, true); 
} 

Giải pháp này sẽ về mặt kỹ thuật không hoàn toàn vô hiệu hóa các swipe, như bạn vẫn sẽ thấy một phần nhỏ của trang trình bày không được phép khi bạn thực hiện thao tác vuốt của mình. Nhưng đối với một số ứng dụng, điều này có thể được ưu tiên.