เป็นไปได้หรือไม่ที่จะปิดการใช้งานการเลื่อนบน ViewPager


138

ฉันมีViewPagerที่ instantiates Viewฉันต้องการปิดใช้งานทั้งการเลื่อนดูเพจเจอร์และปุ่มลูกศรชั่วขณะในขณะที่ผลการค้นหากลับสู่มุมมอง ฉันกำลังโทรviewPager.setEnabled(false)แต่นี่ไม่ได้ปิดการใช้งาน

ใครมีความคิดเห็นบ้าง


คำตอบ:


355

ทางออกที่ง่ายคือการสร้างคลาสย่อยของคุณเองViewPagerซึ่งมีprivate booleanธง, isPagingEnabled. จากนั้นแทนที่onTouchEventและonInterceptTouchEventวิธีการ ถ้าisPagingEnabledเท่ากับจริงเรียกวิธีการอย่างอื่นsuperreturn

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;
    }
}

จากนั้นในLayout.XMLไฟล์ของคุณจะแทนที่<com.android.support.V4.ViewPager>แท็กด้วย<com.yourpackage.CustomViewPager>แท็ก

รหัสนี้ดัดแปลงจากโพสต์บล็อกนี้


2
วิธีการแก้ปัญหา greate ทำงานได้ดี หากคุณต้องการหยุดการปัดเหมือนลิงคุณสามารถแทนที่ OnPageChangeListener ด้วย @Override โมฆะสาธารณะ onPageScrollStateChanged (สถานะ int สุดท้าย) {switch (state) {case ViewPager.SCROLL_STATE_SETTLING: mPager.setPagingEnabled (false); หยุดพัก; กรณี ViewPager.SCROLL_STATE_IDLE: mPager.setPagingEnabled (จริง); หยุดพัก; } // noop}
Informatic0re

13
PS: ใน XML ใช้ <yourpkgname.CustomViewPager ... แทน <com.android, support.v4.ViewPager ...
thecr0w

เพื่อเพิ่มโซลูชันอื่นที่คล้ายกันคุณสามารถใช้ไลบรารีชื่อ "JazzyViewPager": github.com/jfeinstein10/JazzyViewPagerและเพียงแค่เรียก setPagingEnabled (บูลีน)
นักพัฒนา Android

เป็นไปได้หรือไม่ที่จะหยุดเลื่อนเท่านั้น? ฉันสามารถเลื่อนไปทางซ้ายเท่านั้น
Saif Hamed

มันยังคงเป็นไปได้ที่ "เลื่อน" โดยเน้นองค์ประกอบ (ปุ่ม ฯลฯ ) ในหน้าเมื่อใช้ตัวควบคุมเกมหรือแป้นพิมพ์เป็นต้น วิธีการปิดการใช้งานที่สมบูรณ์? ฉันเดาว่าเป็นอีกประเภทหนึ่งของเหตุการณ์ที่ควรถูกสกัดกั้น ...
เดวิดเฟอร์แร

34

มีการแก้ไขที่ง่ายสำหรับอันนี้:

เมื่อคุณต้องการปิดการใช้งานการเลื่อนดูวิวเพจ:

mViewPager.setOnTouchListener(new OnTouchListener() {

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

และเมื่อคุณต้องการเปิดใช้งานใหม่อีกครั้ง:

mViewPager.setOnTouchListener(null);

นั่นจะเป็นการหลอกลวง


46
เกือบ แต่ไม่มาก การแตะลงยังคงเกิดขึ้นเพื่อให้คุณสามารถย้ายหน้าเว็บได้ด้วยการปัดนิ้วเล็ก ๆ
Flynny75

@Akhil Sekharan ประสบปัญหาตรงที่ Flynny กำลังเผชิญเมื่อใช้คำตอบนี้ .. แต่โชคดีที่ไม่รู้ว่าข้อผิดพลาดนั้นหายไปทันที .. :) และทำงานเหมือนมีเสน่ห์ !!
Zombie

คุณสามารถทำ swipes ขนาดเล็กจำนวนมากได้ดังนั้นคุณยังคงต้องใช้บูลีนสาธารณะใน InterceptTouchEvent (เหตุการณ์ MotionEvent) {ขี่ตามคำตอบสลาฟ
Ryan Heitner

28

นี่คือตัวแปรน้ำหนักเบาของคำตอบของ 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);
    }
}

setEnable()ด้วยรหัสของฉันคุณสามารถปิดเพจด้วย


การแทนที่จะonInterceptTouchEvent()ป้องกันไม่ให้มุมมองเด็กรับอินพุต ในกรณีส่วนใหญ่นี่ไม่ใช่พฤติกรรมที่ตั้งใจ
Alex Semeniuk

19

ฉันพบทางออกที่ง่าย

//disable swiping
mViewPager.beginFakeDrag();

//enable swiping
mViewPager.endFakeDrag();

นี่คือรหัสทั้งหมดที่คุณใช้หรือไม่ มันไม่ทำงานสำหรับฉัน
Jared Burrows

17
ไม่ได้ผลสำหรับฉัน ยังคงสามารถทำ swipes ขนาดเล็กจำนวนมากได้
DYS

รหัสนี้ไม่ถูกต้อง bcz มันเลื่อนช้ามากเหมือนแขวนดู
Ghanshyam Nayma

สิ่งนี้อาจทำงานได้ด้วยโชค การอัปเดตเป็น ViewPager อาจทำให้แฮ็คนี้เสียหาย
ตัวชี้ Null

มันยังคงลาก แต่ทีละน้อย (.
ekashking

14

ฉันแนะนำวิธีอื่นในการแก้ปัญหานี้ แนวคิดถูกห่อ viewPager ของคุณด้วย scrollView ดังนั้นเมื่อ scrollView นี้ไม่สามารถเลื่อนได้ viewPager ของคุณก็ไม่สามารถเลื่อนได้เช่นกัน

นี่คือเค้าโครง XML ของฉัน:

        <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>

ไม่จำเป็นต้องใช้รหัส

ทำงานได้ดีสำหรับฉัน


1
ในบรรดาคำตอบทั้งหมดนี้ฉันรู้สึกว่ามันง่ายและใช้งานได้ดี !!
SREE

ตกลง ... แต่เมื่อคุณมีแผนที่เป็นส่วนหนึ่งของ ViewPager ในตอนนั้น ... มันเป็นปัญหา
ekashking

4

หากต้องการปิดใช้งานการปัด

 mViewPager.beginFakeDrag();

เพื่อเปิดใช้งานการปัด

 mViewPager.endFakeDrag();

2
การเลื่อนยังคงเป็นไปได้ แต่ก็ไม่คล่องอีกต่อไป นี่เป็นเพียงแค่เลวลงคุณภาพโดยไม่ต้องแก้ปัญหา
Benjamin Basmaci

1
คำตอบซ้ำ
Ricardo A.

3

ทางออกที่ดีที่สุดสำหรับฉันคือ:

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;
    }
}

หลังจากนี้การเลื่อนจะถูกปิดใช้งานโดยการแตะแล้วคุณยังสามารถใช้setCurrentItemวิธีการเปลี่ยนหน้าได้


ไม่ทราบสาเหตุ แต่มันใช้งานไม่ได้ การเลื่อนยังคงเกิดขึ้น
Ricardo A.

1
canScrollHorizontally()วิธีไม่มีผลในสถานการณ์ปัจจุบัน มันไม่ได้ถูกเรียกแม้แต่เมื่อมีการกวาดนิ้ว
Alex Semeniuk

3

นี่คือคำตอบใน Kotlin และ 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

เกี่ยวกับสิ่งนี้:
ฉันใช้CustomViewPager
และถัดไป, แทนที่เมธอด scrollTo
ฉันตรวจสอบการเคลื่อนไหวเมื่อทำการ swipes ขนาดเล็กจำนวนมากมันไม่ได้เลื่อนไปที่หน้าอื่น

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);
       }
    }
}

ฉันมีปัญหาที่วิวเวอร์เพจเจอร์ยังคงทำ swipes เล็ก ๆ น้อย ๆ แต่การเอาชนะนั้น View.scrollTo(int x, int y)แก้ไขปัญหานี้ให้ฉันได้ ขอบคุณ
Palm

มันทำให้เกิดพฤติกรรมแปลก ๆ ในบางกรณี เช่นเดียวกับการเป็นโมฆะและปล่อยให้หน้าว่าง '-'
Ricardo A.

2

ในกรณีของฉันในการใช้ ViewPager 2 อัลฟา 2 ตัวอย่างด้านล่างทำงาน

viewPager.isUserInputEnabled = false

ความสามารถในการปิดใช้งานการป้อนข้อมูลผู้ใช้ (setUserInputEnabled, isUserInputEnabled)

อ้างถึงสิ่งนี้สำหรับการเปลี่ยนแปลงเพิ่มเติมในviewpager2 1.0.0-alpha02

นอกจากนี้ยังมีการเปลี่ยนแปลงบางอย่างที่ทำในเวอร์ชันล่าสุด ViewPager 2 อัลฟา 4

การวางแนวและแอตทริบิวต์ isUserScrollable ไม่ได้เป็นส่วนหนึ่งของ SavedState อีกต่อไป

อ้างถึงสิ่งนี้สำหรับการเปลี่ยนแปลงเพิ่มเติมในviewpager2 # 1.0.0-alpha04


1

คลาสใหม่ ViewPager2 จาก androidx อนุญาตให้ปิดการเลื่อนด้วยเมธอด setUserInputEnabled (false)

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

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

0

คำตอบของ slayton ทำงานได้ดี หากคุณต้องการหยุดรูดเหมือนลิงคุณสามารถแทนที่ OnPageChangeListener ด้วย

@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; 
        } 
    }

ดังนั้นคุณสามารถปัดนิ้วเข้าหากันเท่านั้น


1
ฉันไม่พบวิธีการใด ๆ ของ ViewPager เช่น setPagingEnabled (ค่าบูลีน)
Rakesh Yadav

setPagingEnabled (ค่าบูลีน) จะถูกสร้างขึ้นโดยคุณ becoz ไม่มีวิธีดังกล่าวเพื่อแทนที่
Kharak

ไม่ชัดเจนว่าsetPagingEnabled()วิธีการนี้ทำอะไร กรุณาใส่รหัสที่สมบูรณ์
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*/);
    }
}
}

จากนั้นในไฟล์ Layout.XML ของคุณจะแทนที่ --- แท็ก --- com.android.support.V4.ViewPager --- ด้วย --- com.yourpackage.NonSwipeableViewPager ---

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.