เป็นไปได้หรือไม่ที่จะปิดการใช้งานการเลื่อนบน 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.