Có thể tắt tính năng cuộn trên ViewPager không


138

Tôi có một ViewPagercái mà bắt đầu a View. Tôi muốn vô hiệu hóa cả cuộn của trình xem và các nút con trong giây lát trong khi kết quả tìm kiếm được trả về chế độ xem. Tôi đã gọi viewPager.setEnabled(false)nhưng điều này không vô hiệu hóa nó.

Bất cứ ai có ý tưởng?


Câu trả lời:


355

Một giải pháp đơn giản là tạo lớp con của riêng bạn ViewPagerprivate booleancờ , isPagingEnabled. Sau đó ghi đè lên onTouchEventonInterceptTouchEventphương thức. Nếu isPagingEnabledbằng đúng, gọi superphương thức, nếu không return.

public class CustomViewPager extends ViewPager {

    private boolean isPagingEnabled = true;

    public CustomViewPager(Context context) {
        super(context);
    }

    public CustomViewPager(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

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

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

    public void setPagingEnabled(boolean b) {
        this.isPagingEnabled = b;
    }
}

Sau đó, trong Layout.XMLtập tin của bạn thay thế bất kỳ <com.android.support.V4.ViewPager>thẻ bằng <com.yourpackage.CustomViewPager>thẻ.

Mã này đã được điều chỉnh từ bài viết trên blog này .


2
giải pháp tuyệt vời, hoạt động tốt. Nếu bạn muốn dừng vuốt như một con khỉ, bạn có thể ghi đè OnPageChangeListener bằng @Override void công khai onPageScrollStateChanged (trạng thái int cuối cùng) {switch (state) {case ViewPager.SCROLL_STATE_SettLING: mPager.setPaging phá vỡ; trường hợp ViewPager.SCROLL_STATE_IDLE: mPager.setPagingEnables (true); phá vỡ; } // noop}
Informatic0re

13
PS: Trong XML, sử dụng <yourpkgname.CustomViewPager ... thay vì <com.android, support.v4.ViewPager ...
thecr0w

để thêm một giải pháp tương tự khác, bạn có thể sử dụng thư viện có tên "JazzyViewPager": github.com/jfeinstein10/JazzyViewPager và chỉ cần gọi setPagingEnables (boolean)
nhà phát triển Android

Có thể dừng cuộn chỉ? tôi chỉ có thể cuộn sang trái
Saif Hamed

Vẫn có thể "cuộn" bằng cách lấy nét các yếu tố (nút, v.v.) trong các trang khi sử dụng bộ điều khiển trò chơi hoặc bàn phím chẳng hạn. Làm thế nào để vô hiệu hóa hoàn toàn? Tôi đoán đó là một loại sự kiện khác nên bị chặn ...
David Ferrand

34

Có một sửa chữa dễ dàng cho cái này:

Khi bạn muốn tắt chế độ xem cuộn, sau đó:

mViewPager.setOnTouchListener(new OnTouchListener() {

   public boolean onTouch(View arg0, MotionEvent arg1) {
      return true;
   }
}); 

Và khi bạn muốn kích hoạt lại thì:

mViewPager.setOnTouchListener(null);

Điều đó sẽ làm các thủ thuật.


46
Hầu như, nhưng không hoàn toàn. Việc chạm xuống vẫn xảy ra, vì vậy bạn có thể di chuyển các trang bằng cách thực hiện nhiều thao tác vuốt nhỏ.
Flynny75

@Akhil Sekharan Đã đối mặt với vấn đề chính xác những gì Flynny đang phải đối mặt khi sử dụng câu trả lời này .. nhưng may mắn thay không biết lỗi đó đột nhiên biến mất như thế nào .. :) và hoạt động như một cơ duyên !!
Zombie

Bạn có thể thực hiện rất nhiều thao tác vuốt nhỏ để bạn vẫn phải vượt qua boolean công khai trênInterceptTouchEvent (sự kiện MotionEvent) {đi theo câu trả lời của slatons
Ryan Heitner

28

Đây là biến thể trọng lượng nhẹ của câu trả lời của slayton:

public class DeactivatableViewPager extends ViewPager {
    public DeactivatableViewPager(Context context) {
        super(context);
    }

    public DeactivatableViewPager(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        return !isEnabled() || super.onTouchEvent(event);
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent event) {
        return isEnabled() && super.onInterceptTouchEvent(event);
    }
}

Với mã của tôi, bạn có thể vô hiệu hóa phân trang với setEnable().


Ghi đè onInterceptTouchEvent()sẽ ngăn các lượt xem con nhận đầu vào. Trong hầu hết các trường hợp, đây không phải là hành vi dự định.
Alex Semeniuk

19

Tôi tìm thấy một giải pháp đơn giản.

//disable swiping
mViewPager.beginFakeDrag();

//enable swiping
mViewPager.endFakeDrag();

Đây có phải là tất cả các mã bạn đã sử dụng? Điều này không làm việc cho tôi.
Jared Burrows

17
Không làm việc cho tôi. Vẫn có thể làm rất nhiều thao tác vuốt.
DYS

Mã này không đúng bcz Nó đang cuộn rất chậm như chế độ xem treo
Ghanshyam Nayma

Điều này có thể làm việc bởi may mắn. Cập nhật lên ViewPager có thể phá vỡ bản hack này.
Con trỏ Null

Nó vẫn đang kéo nhưng từng chút một (.
ekashking

14

Tôi đề nghị một cách khác để giải quyết vấn đề này. Ý tưởng đang bao bọc viewPager của bạn bằng scrollView, do đó khi scrollView này không thể cuộn được, viewPager của bạn cũng không thể cuộn được.

Đây là bố cục XML của tôi:

        <HorizontalScrollView
            android:id="@+id/horizontalScrollView"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:fillViewport="true" >

            <android.support.v4.view.ViewPager
                android:id="@+id/viewPager"
                android:layout_width="wrap_content"
                android:layout_height="match_parent" />

        </HorizontalScrollView>

Không cần mã.

Hoạt động tốt cho tôi.


1
Trong số tất cả những câu trả lời này, tôi cảm thấy điều này đơn giản và hoạt động tốt !!
SREE

OK ... NHƯNG khi bạn có một bản đồ là một trong những mảnh vỡ trong ViewPager thì ... đó là một vấn đề
ekashking

4

Để tắt tính năng vuốt

 mViewPager.beginFakeDrag();

Để bật vuốt

 mViewPager.endFakeDrag();

2
Di chuyển vẫn có thể, nó chỉ không thông thạo nữa. Điều này về cơ bản chỉ làm giảm chất lượng mà không giải quyết vấn đề.
Benjamin Basmaci

1
câu trả lời trùng lặp
Ricardo A.

3

Giải pháp tốt nhất phù hợp với tôi là:

public class DeactivatedViewPager extends ViewPager {

    public DeactivatedViewPager (Context context) {
        super(context);
    }

    public DeactivatedViewPager (Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    public boolean canScrollHorizontally(int direction) {
        return false;
    }
}

Sau đó, cuộn sẽ bị vô hiệu hóa bằng cách chạm và sau đó bạn vẫn có thể sử dụng setCurrentItemphương pháp để thay đổi trang.


Không biết tại sao, nhưng nó đơn giản là không hoạt động. Việc cuộn vẫn xảy ra.
Ricardo A.

1
Các canScrollHorizontally()phương pháp không có tác dụng trong kịch bản hiện hành. Nó thậm chí không được gọi khi vuốt xảy ra.
Alex Semeniuk

3

Đây là một câu trả lời trong Kotlin và androidX

import android.content.Context
import android.util.AttributeSet
import android.view.MotionEvent
import androidx.viewpager.widget.ViewPager

class DeactivatedViewPager @JvmOverloads constructor(
    context: Context, attrs: AttributeSet? = null
) : ViewPager(context, attrs) {

    var isPagingEnabled = true

    override fun onTouchEvent(ev: MotionEvent?): Boolean {
        return isPagingEnabled && super.onTouchEvent(ev)
    }

    override fun onInterceptTouchEvent(ev: MotionEvent?): Boolean {
        return isPagingEnabled && super.onInterceptTouchEvent(ev)
    }
}

2

Làm thế nào về điều này:
Tôi đã sử dụng CustomViewPager
và tiếp theo, ghi đè cuộn Phương thức
tôi đã kiểm tra chuyển động khi thực hiện nhiều thao tác vuốt nhỏ, nó không cuộn sang các trang khác.

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) {
            return super.onTouchEvent(event);
        }

        return false;
    }

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

        return false;
    }

    public void setPagingEnabled(boolean enabled) {
        this.enabled = enabled;
    } 

    @Override
    public void scrollTo(int x, int y) {
       if(enabled) {
          super.scrollTo(x, y);
       }
    }
}

Tôi đã có một vấn đề là người xem vẫn đang thực hiện các thao tác vuốt nhỏ, nhưng việc ghi đè đã View.scrollTo(int x, int y)giải quyết vấn đề này cho tôi. Cảm ơn
Palm

Nó gây ra một số hành vi kỳ lạ trong một số trường hợp. Giống như đi đến khoảng trống và chỉ để lại một trang trống '-'
Ricardo A.

2

Trong trường hợp sử dụng ViewPager 2 alpha 2, đoạn mã dưới đây hoạt động

viewPager.isUserInputEnabled = false

Khả năng vô hiệu hóa đầu vào của người dùng (setUserInputEnables, isUserInputEnabled)

tham khảo điều này để biết thêm những thay đổi trong viewpager2 1.0.0-alpha02

Ngoài ra một số thay đổi đã được thực hiện phiên bản mới nhất ViewPager 2 alpha 4

định hướng và thuộc tính isUserScrollable không còn là một phần của SavingState

tham khảo điều này để biết thêm các thay đổi trong viewpager2 # 1.0.0-alpha04


1

Lớp mới ViewPager2 từ androidx cho phép vô hiệu hóa cuộn với phương thức setUserInputEnabled (false)

private val pager: ViewPager2 by bindView(R.id.pager)

override fun onCreate(savedInstanceState: Bundle?) {
    pager.isUserInputEnabled = false
}

0

Câu trả lời của slayton hoạt động tốt. Nếu bạn muốn dừng vuốt như một con khỉ, bạn có thể ghi đè OnPageChangeListener bằng

@Override public void onPageScrollStateChanged(final int state) { 
        switch (state) { 
            case ViewPager.SCROLL_STATE_SETTLING: 
                mPager.setPagingEnabled(false); 
                break; 
            case ViewPager.SCROLL_STATE_IDLE: 
                mPager.setPagingEnabled(true); 
                break; 
        } 
    }

Vì vậy, bạn chỉ có thể vuốt cạnh nhau


1
Tôi không tìm thấy bất kỳ phương thức nào của ViewPager, chẳng hạn như setPagingEnables (giá trị boolean)
Rakesh Yadav

setPagingEnables (giá trị boolean) sẽ được tạo bởi bạn, vì không có phương thức nào để ghi đè.
Kharak

Không rõ setPagingEnabled()phương pháp này làm gì. Vui lòng bao gồm mã hoàn chỉnh.
Alex Semeniuk

0
import android.content.Context;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.animation.DecelerateInterpolator;
import android.widget.Scroller;
import java.lang.reflect.Field;

public class NonSwipeableViewPager extends ViewPager {

public NonSwipeableViewPager(Context context) {
    super(context);
}

public NonSwipeableViewPager(Context context, AttributeSet attrs) {
    super(context, attrs);
}

@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
    // stop swipe 
    return false;
}

@Override
public boolean onTouchEvent(MotionEvent event) {
    // stop switching pages
    return false;
}

private void setMyScroller() {
    try {
        Class<?> viewpager = ViewPager.class;
        Field scroller = viewpager.getDeclaredField("mScroller");
        scroller.setAccessible(true);
        scroller.set(this, new MyScroller(getContext()));
    } catch (Exception e) {
        e.printStackTrace();
    }
}

public class MyScroller extends Scroller {
    public MyScroller(Context context) {
        super(context, new DecelerateInterpolator());
    }

    @Override
    public void startScroll(int startX, int startY, int dx, int dy, int 
duration) {
        super.startScroll(startX, startY, dx, dy, 350 /*1 secs*/);
    }
}
}

Sau đó, trong tệp Layout.XML của bạn thay thế bất kỳ thẻ --- com.android.support.V4.ViewPager --- bằng --- com.yourpackage.NonSwipizableViewPager --- thẻ.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.