ViewPager में उंगली से स्वाइप करके पेजिंग को अक्षम कैसे करें लेकिन फिर भी प्रोग्रामेटिक रूप से स्वाइप करने में सक्षम हैं?


549

मेरे पास ViewPager है और इसके नीचे मेरे पास 10 बटन हैं। बटन पर क्लिक करके, उदाहरण के लिए # 4, पेजर तुरंत पेज # 4 पर जाता है mPager.setCurrentItem(3);। लेकिन, मैं क्षैतिज रूप से उंगली से स्वाइप करके पेजिंग को अक्षम करना चाहता हूं। इस प्रकार, पेजिंग किया जाता है केवल बटन पर क्लिक करके। तो, मैं उंगली से स्वाइप को कैसे निष्क्रिय कर सकता हूं?


पहली बार में ViewFlipper का उपयोग करने के बारे में कैसे ? यह आपको सिरदर्द से काफी हद तक बचाएगा।
एलेक्स सेमीनेक

जवाबों:


885

आपको उपवर्ग करने की आवश्यकता है ViewPageronTouchEventइसमें बहुत सारी अच्छी चीजें हैं जिन्हें आप बदलना नहीं चाहते हैं जैसे कि बच्चे के विचारों को छूने की अनुमति देना। onInterceptTouchEventवह है जो आप बदलना चाहते हैं। यदि आप कोड को ViewPagerदेखते हैं, तो आप टिप्पणी देखेंगे:

    /*
     * This method JUST determines whether we want to intercept the motion.
     * If we return true, onMotionEvent will be called and we do the actual
     * scrolling there.
     */

यहाँ एक पूर्ण समाधान है:

सबसे पहले, इस वर्ग को अपने srcफ़ोल्डर में जोड़ें :

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

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

    @Override
    public boolean onInterceptTouchEvent(MotionEvent event) {
        // Never allow swiping to switch between pages
        return false;
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        // Never allow swiping to switch between pages
        return false;
    }

    //down one is added for smooth scrolling

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

इसके बाद, नियमित के बजाय इस वर्ग का उपयोग करना सुनिश्चित करें ViewPager, जिसे आपने संभवतः निर्दिष्ट किया है android.support.v4.view.ViewPager। अपनी लेआउट फ़ाइल में, आप इसे कुछ इस तरह निर्दिष्ट करना चाहेंगे:

<com.yourcompany.NonSwipeableViewPager
    android:id="@+id/view_pager"
    android:layout_width="match_parent"
    android:layout_height="0dp"
    android:layout_weight="1" />

यह विशेष उदाहरण एक है LinearLayoutऔर पूरे स्क्रीन को उठाने के लिए है, यही कारण layout_weightहै कि 1 है और layout_height0dp है।

और setMyScroller();विधि चिकनी संक्रमण के लिए है


3
@louielouie एक साइड-नोट पर: क्या कोई विशेष कारण है, आपने पूर्ण-स्क्रीन प्रभाव को प्राप्त करने के लिए ऊँचाई पर ऊंचाई 0dp/ 1वजन समाधान क्यों चुना match_parent? क्या आप ऐसा करके प्रदर्शन सुधार प्राप्त करते हैं?
ubuntudroid

28
यह उत्तर कीबोर्ड लेफ्ट / राइट कीज़ का उपयोग करते समय पेज स्वाइपिंग को रोकता नहीं है (इसे एमुलेटर में आज़माएं)। स्पर्श उपकरणों के लिए समस्या नहीं हो सकती है लेकिन टीवी और लैपटॉप के साथ यह एक हो सकता है।
विन्सेन्ट मिमौन-प्रात

8
@MarvinLabs @Thorbear कीबोर्ड द्वारा पृष्ठ स्क्रॉल को अक्षम करने का सही तरीका ओवरराइड करना है executeKeyEvent()। यह वह विधि है जिसे तब कॉल करें allowScroll()// Never allow swiping by keyboard LEFT, RIGHT, TAB and SHIFT+TAB keys @Override public boolean executeKeyEvent(KeyEvent event) { return false; }
आक्रों

6
ठीक है, यह भी ऊर्ध्वाधर स्क्रॉल अक्षम करता है ... यह बुरा है, अगर आप सूची का उपयोग कर रहे हैं।
मई

5
मुझे उम्मीद है कि google सिर्फ एक तरीका प्रदान कर सकता है जिससे हम अपने इंटरफ़ेस मेथड को सप्लाई करें कि कैसे टच / स्वाइपिंग को हैंडल करें क्योंकि मेरा मानना ​​है कि यह चोट नहीं पहुंचाएगा?
नियॉन वारगे

466

इसका अधिक सामान्य विस्तार ViewPagerएक SetPagingEnabledतरीका बनाना होगा ताकि हम फ्लाई पर पेजिंग को सक्षम और अक्षम कर सकें। स्वाइपिंग को सक्षम / अक्षम करने के लिए, बस दो तरीकों से आगे बढ़ें: onTouchEventऔर onInterceptTouchEvent। यदि पेजिंग अक्षम किया गया था तो दोनों "झूठे" वापस आ जाएंगे।

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

फिर XML में बिल्ट-इन व्यूपेजर के बजाय इसे चुनें

<mypackage.CustomViewPager 
    android:id="@+id/myViewPager" 
    android:layout_height="match_parent" 
    android:layout_width="match_parent" />

आपको केवल setPagingEnabledविधि को कॉल करने की आवश्यकता है falseऔर उपयोगकर्ता पेजेट करने के लिए स्वाइप नहीं कर पाएंगे।


3
पूरी तरह से एक दृश्य के लिए काम करता है जिसमें कई साक्षात्कार होते हैं जहां कोई क्षैतिज स्क्रॉलिंग का उपयोग करता है (जैसे। AChartEngine चार्ट)। मेरे खंडन में, मैं अपनी गतिविधि के लिए कॉलबैक का उपयोग करता हूं जो यह बताता है कि उपयोगकर्ता ने छुआ (ACTION_MOVE) चार्ट को छोड़ दिया है या इसे छोड़ दिया है (ACTION_CANCEL)। आपका बहुत बहुत धन्यवाद!
राइपर

32
आप अपने को आसान बनाने में कर सकते हैं onTouchEventऔर onInterceptTouchEventसाथ तरीकोंreturn enabled && super.onTouchEvent(event);
nbarraille

2
@nbarraille यह सिर्फ स्टाइल की बात है। जो भी शैली आपके लिए अधिक पठनीय प्रतीत होती है, आप उसका उपयोग कर सकते हैं।
राजुल

7
मैं "सक्षम" से "swipePageChangeEnabled" या ऐसा कुछ करने के लिए फ़ील्ड का नाम बदलने की भी सिफारिश करूंगा। कोड लिखने के एक महीने बाद आपको शायद ही याद होगा कि "सक्षम" का क्या मतलब है, खासकर जब आपकी कक्षा को "CustomViewPager" कहा जाता है, जहां यह स्पष्ट नहीं है कि अनुकूलन क्या है। यह भी शैली की बात है, लेकिन शैली मायने रखती है अगर आप असमर्थित परियोजना के साथ समाप्त नहीं करना चाहते हैं, तो इसे ठीक करने की तुलना में पूरी तरह से फिर से लिखना आसान है।
बाइटफू

3
मैं कहां से कॉल कर सकता हूं ._।
Ntikki

107

सबसे आसान तरीका है setOnTouchListenerऔर बदले trueके लिए ViewPager

mPager.setOnTouchListener(new OnTouchListener()
    {           
        @Override
        public boolean onTouch(View v, MotionEvent event)
        {
            return true;
        }
    });

53
कभी-कभी काम नहीं करता है। मैं एक FragmentPagerAdapter और कई Fragment के साथ एक ViewPager का उपयोग कर रहा हूं। OnTouchListener को पेजर में सेट करने के बाद, अगर मैं बाईं ओर भागता हूं, तो UI अभी भी थोड़ा सा बाएं ओर जाएगा।
क्रिस .Zou

16
यह काम करता है जब आप pager.setCurrentItem(pager.getCurrentItem());लौटने से पहले जोड़ते हैं true
dng

1
इसने मेरे लिए पहले काम किया था। पता नहीं क्यों यह अब अच्छी तरह से काम नहीं करता है।
एंड्रॉइड डेवलपर

लगता है मेरे लिए काम करता है। public int getItemPosition(Object object) { return POSITION_NONE; }मेरे एडेप्टर में कुछ लेआउट ग्लिच को हल करने के लिए , जो पृष्ठों के मनोरंजन को मजबूर करता है और शायद अन्य समस्याओं को भी हल करता है।
आर-होल्ड

6
यह एक आंशिक रूप से काम करने वाला समाधान है। क्षैतिज स्वाइप्स को कुछ अजीब तरीके से संभाला जाता है। मैं एक ViewPager के हिस्से के रूप में एक ड्रैग एन ड्रॉप ग्रिडव्यू के साथ इसका परीक्षण किया। इस समाधान का उपयोग करते समय, बाएं से दाएं और दाएं से बाएं तरफ खींचना विफल हो जाता है। व्यक्तिगत रूप से मुझे राजुल का दृष्टिकोण सबसे अच्छा लगता है।
टोन स्नोई

58

इसे शैलीगत घोषित करने के लिए बेहतर है, ताकि आप इसकी संपत्ति को xml से बदल सकें:

private boolean swipeable;

public MyViewPager(Context context, AttributeSet attrs) {
    super(context, attrs);
    TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.MyViewPager);
    try {
        swipeable = a.getBoolean(R.styleable.MyViewPager_swipeable, true);
    } finally {
        a.recycle();
    }
}

@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
    return swipeable ? super.onInterceptTouchEvent(event) : false;
}

@Override
public boolean onTouchEvent(MotionEvent event) {
    return swipeable ? super.onTouchEvent(event) : false;
}

और आपके मूल्यों / attr.xml में:

<declare-styleable name="MyViewPager">
  <attr name="swipeable" format="boolean" />
</declare-styleable>

ताकि आप इसका उपयोग अपने लेआउट xml में कर सकें:

<mypackage.MyViewPager
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/viewPager"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    app:swipeable="false" />

बेशक, आप अभी भी प्राप्त / सेट संपत्ति कर सकते हैं।


58

केवल ओवरराइड करना onTouchEventऔर onInterceptTouchEventउस स्थिति में पर्याप्त नहीं है जब आपके पास ViewPager खुद ही किसी अन्य ViewPager के अंदर हो। चाइल्ड व्यूपेजर अभिभावक व्यू पेजर से क्षैतिज स्क्रॉल टच ईवेंट चोरी करेगा जब तक कि वह अपने पहले / अंतिम पृष्ठ पर तैनात न हो।

इस सेटअप को ठीक से काम करने के लिए आपको canScrollHorizontallyविधि को भी ओवरराइड करना होगा ।

देखें LockableViewPagerनीचे कार्यान्वयन।

public class LockableViewPager extends ViewPager {

    private boolean swipeLocked;

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

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

    public boolean getSwipeLocked() {
        return swipeLocked;
    }

    public void setSwipeLocked(boolean swipeLocked) {
        this.swipeLocked = swipeLocked;
    }

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

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

    @Override
    public boolean canScrollHorizontally(int direction) {
        return !swipeLocked && super.canScrollHorizontally(direction);
    }

}

3
धन्यवाद, यह दूसरे ViewPager के अंदर एक ViewPager पर बहुत अच्छी तरह से काम करता है।
फर्नांडी बारी

1
यह मेरे लिए काम करता है, एक ViewPager के लिए दूसरे ViewPager के अंदर भी। उस मामले में मेरे लिए सही समाधान काम नहीं आया।
राफेल रुइज मुनोज

टैब में उपयोग किए जाने पर एनीमेशन भी बंद हो जाता है।
ऋषभ श्रीवास्तव

अगर मैं इसे निष्क्रिय कर देता हूं और मान लेता हूं कि मैं इसे सक्षम करना चाहता हूं तो मुझे सेटस्विप्लॉकड (झूठा) कॉल करने की घटना कहां मिल सकती है?
रवि यादव

57

अब हमें रिवाज बनाने की कोई जरूरत नहीं है ViewPager

ViewPager2 Android में उपलब्ध एक नया नाम दृश्य

ऊर्ध्वाधर अभिविन्यास समर्थन

  • ViewPager2पारंपरिक क्षैतिज पेजिंग के अलावा ऊर्ध्वाधर पेजिंग का समर्थन करता है। आप ViewPager2इसकी android:orientationविशेषता सेट करके किसी तत्व के लिए वर्टिकल पेजिंग को सक्षम कर सकते हैं

XML का उपयोग करना

<androidx.viewpager2.widget.ViewPager2
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/pager"
    android:orientation="vertical" />

कोड का उपयोग करना

viewpager2उपयोग में स्वाइप को अक्षम करने के लिए

viewPager2.setUserInputEnabled(false);

viewpager2उपयोग में स्वाइपिंग को सक्षम करने के लिए

viewPager2.setUserInputEnabled(true);

अधिक जानकारी के लिए इसे देखें

अपडेट करें


3
यह बहुत अच्छा है, लेकिन अभी भी अधूरा लगता है। मैंने इसे 5 अलग-अलग अंशों के साथ आज़माया है और पृष्ठों के बीच स्विच करने के बाद टुकड़ों में से एक खो गया था, अर्थात दृश्य को न तो पुनर्स्थापित किया गया था और न ही फिर से फुलाया गया था
Toochka

@Toochka कि मेरे लिए यह ठीक काम कर रहा है तुम यहाँ से नमूना काम कर कोड प्राप्त कर सकते हैं यह सुनकर दुख हुआ stackoverflow.com/a/54643817/7666442 यदि संभव हो तो अपने कोड साझा करें
नीलेश राठौड़

1
मैं सफलतापूर्वक इस विधि का उपयोग करके ViewPager2 पर स्वाइपिंग को अक्षम कर सकता हूं
voghDev

1
@voghDev को यह सुनकर खुशी हुई
नीलेश राठौड़

1
@PhaniRithvij कृपया इस उत्तर की जाँच करें stackoverflow.com/a/54643817/7666442 मैंने सभी विवरण जोड़े हैं कि कैसे उपयोग viewpager2करेंRecyclerView.Adapter
नीलेश राठौड़

35

यदि आप ViewPager से विस्तार कर रहे हैं, तो आपकोexecuteKeyEvent @araks द्वारा पहले बताए अनुसार ओवरराइड भी करना होगा

@Override
public boolean executeKeyEvent(KeyEvent event)
{
    return isPagingEnabled ? super.executeKeyEvent(event) : false;
}

क्योंकि गैलेक्सी टैब 4 10 'जैसे कुछ उपकरण इन बटनों को दिखाते हैं जहाँ अधिकांश उपकरण उन्हें कभी नहीं दिखाते हैं:

कीबोर्ड बटन


50
सैमसंग हमेशा एंड्रॉइड देवों के लिए चीजों को खराब कर रहा है।
टोब्स्को 42

2
@ toobsco42 सैमसंग इस उदाहरण में अकेला नहीं है। SwiftKey (लोकप्रिय कीबोर्ड ऐप) उपयोगकर्ताओं को अपने कीबोर्ड पर तीर लगाने की अनुमति देता है।
सूफियान

1
यदि आप अपने पेजर को पेजिंग करने से कीबोर्ड / ट्रैकरबॉल का उपयोग करना चाहते हैं, तो यह भी ठीक है।
se22as

28

स्वाइप को अक्षम करने के लिए

mViewPager.beginFakeDrag();

स्वाइप सक्षम करने के लिए

mViewPager.endFakeDrag();

22
यह एक अच्छा समाधान नहीं है क्योंकि यह मेरे ऐप में कम से कम आंदोलन की अनुमति देता है।
कोरस

मेरे लिए ठीक काम करता है। प्रदान किए गए अन्य समाधानों की तुलना में नुकसान क्या हैं?
userM1433372

13

मुझे एक विशिष्ट पृष्ठ पर स्वाइपिंग को अक्षम करना होगा, और इसे एक अच्छा रबर-बैंड एनीमेशन देना होगा, यहां बताया गया है:

    mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {

        @Override
        public void onPageScrolled(int position, float positionOffset,
                                   int positionOffsetPixels) {
            if (position == MANDATORY_PAGE_LOCATION && positionOffset > 0.5) {
                mViewPager.setCurrentItem(MANDATORY_PAGE_LOCATION, true);
            }
        }

यह तब तक इंतजार करता है जब तक कि अगला पृष्ठ आंशिक रूप से दिखाई न दे। अगले पृष्ठ के लिए एक कोड onPageSelectedनिष्पादित किया जाएगा। यहां तक ​​कि अगला पेज भी स्विच हो जाएगा। तो, इस कोड की जरूरत नहीं है।
कूलमाइंड

13

मुझे पता है कि यह पोस्ट करने में देर हो सकती है लेकिन यहाँ एक छोटी सी हैक आपके परिणाम को प्राप्त करने के लिए है;)

बस अपने व्यूअर के नीचे एक डमी दृश्य जोड़ें :

<android.support.v4.view.ViewPager
     android:layout_width="match_parent"
     android:layout_height="match_parent">
</android.support.v4.view.ViewPager>

<RelativeLayout
     android:id="@+id/dummyView"
     android:layout_width="match_parent"
     android:layout_height="match_parent">
</RelativeLayout>

फिर OnClickListenerअपने को जोड़ें RelativeLayout

dummyView = (RelativeLayout) findViewById(R.id.dummyView);

dummyView.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
         //Just leave this empty
    }
});

लेआउट, उनके प्लेसमेंट और उनके व्यवहार के साथ थोड़ा सा रचनात्मक बनें और आप बिल्कुल कुछ भी करने का एक तरीका खोजना सीखेंगे जिसकी आप कल्पना करते हैं :)

सौभाग्य!


यदि आप ईवेंट को संभालने की आवश्यकता नहीं है, तो setClickableइसके बजाय एक आसान तरीका उपयोग किया जाता है । setOnClickListeneronClick
अराजकता

यह भी दृश्यदर्शी के भीतर स्पर्श को अवरुद्ध नहीं करेगा?
एंड्रॉइड डेवलपर

हाँ यह होगा। यह ओपी
@androiddeveloper

@RickGrimesTheCoder मुझे नहीं लगता कि आपने मेरे सवाल को समझा। मेरा मतलब है कि दर्शक के टुकड़े के भीतर के विचार। क्या वे अब भी अछूत होंगे?
Android डेवलपर

नहीं, वे तब से नहीं होंगे जब व्यूअर के पास एक क्लिक श्रोता होगा। यह केवल उन उदाहरणों के लिए उपयुक्त है जहां आपके पास अंशों के भीतर इंटरैक्टिव तत्व नहीं हैं। उदाहरण के लिए एक वेलकम व्यूगर जो अपने अंशों को गतिशील रूप से परिवर्तित करता है
@androiddeveloper

12

मैंने CustomViewPagerएक स्वाइप कंट्रोल के साथ लिखा :

public class ScrollableViewPager extends ViewPager {
    private boolean canScroll = true;
    public ScrollableViewPager(Context context) {
        super(context);
    }
    public ScrollableViewPager(Context context, AttributeSet attrs) {
        super(context, attrs);
    }
    public void setCanScroll(boolean canScroll) {
        this.canScroll = canScroll;
    }
    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        return canScroll && super.onTouchEvent(ev);
    }
    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        return canScroll && super.onInterceptTouchEvent(ev);
    }
}

यदि आप सेट canScrollकरते हैं true, तो इसके विपरीत ViewPager, उंगली से स्वाइप किया जा सकता है false

मैं अपने प्रोजेक्ट में इसका उपयोग करता हूं, और यह अब तक बहुत अच्छा काम करता है।


1
क्या होगा अगर मेरे पास ViewPager के अंदर एक बटन है और मुझे क्लिक चाहिए? यह समाधान देखने के लिए क्लिक किए जाने वाले
दृश्यपटल के

6

मैंने सफलता के साथ इस वर्ग का उपयोग किया। निष्पादन को ओवरराइड करने से कुछ उपकरणों में या एक्सेसिबिलिटी के लिए तीर का उपयोग करने से बचने के लिए आवश्यक है:

import android.content.Context;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.view.KeyEvent;
import android.view.MotionEvent;

public class ViewPagerNoSwipe extends ViewPager {
    /**
     * Is swipe enabled
     */
    private boolean enabled;

    public ViewPagerNoSwipe(Context context, AttributeSet attrs) {
        super(context, attrs);
        this.enabled = false; // By default swiping is disabled
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        return this.enabled ? super.onTouchEvent(event) : false;
    }

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

    @Override
    public boolean executeKeyEvent(KeyEvent event) {
        return this.enabled ? super.executeKeyEvent(event) : false;
    }

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

}

और xml में इसे इस तरह से कॉल करें:

<package.path.ViewPagerNoSwipe
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

यह काम करता हैं। केवल स्वाइप अक्षम है और टैब पर क्लिक करने से सक्षम है। एएस ने चेतावनी दी है कि यह performClick()विधि अधिक महत्वपूर्ण नहीं है।
कूलमाइंड

5

कोटलिन में, मेरे समाधान, उपरोक्त उत्तरों का संयोजन।

class CustomViewPager(context: Context, attrs: AttributeSet): ViewPager(context, attrs) {
    var swipeEnabled = false

    override fun onTouchEvent(ev: MotionEvent?): Boolean {
        return if (swipeEnabled) super.onTouchEvent(ev) else false
    }

    override fun onInterceptTouchEvent(ev: MotionEvent?): Boolean {
        return if (swipeEnabled) super.onInterceptTouchEvent(ev) else false
    }

    override fun executeKeyEvent(event: KeyEvent): Boolean {
        return if (swipeEnabled) super.executeKeyEvent(event) else false
    }
}

ओवरराइडिंग onInterceptTouchEvent()से इनपुट प्राप्त करने के लिए बच्चे के विचारों को रोका जा सकेगा। ज्यादातर मामलों में यह इच्छित व्यवहार नहीं है।
एलेक्स सेमीनेक

मैं प्रत्येक टुकड़े के बच्चे के विचारों के साथ बातचीत करने में सक्षम था। निश्चित नहीं है कि आप किसका जिक्र कर रहे हैं।
जेफ़ पडगेट

5

कोटलिन में, हम ViewPager वर्ग को विरासत में मिली एक कस्टम विजेट बनाकर और स्वाइप व्यवहार को नियंत्रित करने के लिए एक ध्वज मूल्य जोड़कर इसे हल कर सकते हैं।

NoSwipePager.kt

class NoSwipePager(context: Context, attrs: AttributeSet) : ViewPager(context, attrs) {

    var pagingEnabled: Boolean = false

    override fun onTouchEvent(event: MotionEvent): Boolean {
        return if (this.pagingEnabled) {
            super.onTouchEvent(event)
        } else false
    }

    override fun onInterceptTouchEvent(event: MotionEvent): Boolean {
        return if (this.pagingEnabled) {
            super.onInterceptTouchEvent(event)
        } else false
    }
}

Xml में

<your.package.NoSwipePager
    android:id="@+id/view_pager"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_below="@id/tab_layout" />

प्रोग्रामिंग स्वाइप अक्षम करें। अगर kotlin-android-extensionsplugin build.gradle में लगाया जाता है , तो नीचे कोड लिखकर स्वाइप को अक्षम किया जा सकता है।

view_pager.pagingEnabled = false

अन्यथा हम नीचे कोड का उपयोग करके स्वाइप को अक्षम कर सकते हैं:

val viewPager : ViewPager = findViewById(R.id.view_pager)
viewPager.pagingEnabled = false

ओवरराइडिंग onInterceptTouchEvent()से इनपुट प्राप्त करने के लिए बच्चे के विचारों को रोका जा सकेगा। ज्यादातर मामलों में यह है नहीं अभिप्रेत व्यवहार।
एलेक्स सेमेनिएक

@AlexSemeniuk क्या आपने इसे लागू करने के बाद कोई समस्या देखी है? मैंने कुछ कार्यों के लिए पुनर्नवीनीकरण दृश्य वस्तुओं पर स्वाइपिंग को सक्षम किया था और यह ठीक काम कर रहा है। इसलिए कार्यान्वयन मेरे मामले में ठीक काम कर रहा है।
सागर चापागैन

सागर चपागैन: या बेशक, मैंने किया। मेरे प्रत्येक पृष्ठ में कस्टम दृश्य हैं, जो विभिन्न तरीकों से छूता है (स्क्रॉलिंग, ड्रैगिंग, सिंगल और लॉन्ग टैप सहित)। super.onInterceptTouchEvent(event)इन दृश्यों में कॉलिंग के परिणाम नहीं मिलने से कोई इनपुट नहीं मिलता है (जो कि onInterceptTouchEventविधि का प्रलेखित उद्देश्य है )।
एलेक्स सेमीनेक

यदि ऐसा है तो आपको बच्चे के टुकड़े का उपयोग करना चाहिए और बैकस्ट को बनाए रखना चाहिए।
सागर चापागैन

यह वर्तमान प्रश्न के लिए कैसे प्रासंगिक है? टुकड़े कुछ कंटेनरों (जो अंदर रखा जाता है दृश्य ) और अपने स्वयं के लेआउट में शामिल है दृश्य । कोई फर्क नहीं पड़ता कि मेरे पास ViewPager के अंदर क्या सामग्री है, मैं अभी भी इस तथ्य से निपट रहा हूं कि ओवरराइडिंग onInterceptTouchEvent()विधि इसे (सामग्री) इनपुट प्राप्त करने से रोकती है।
एलेक्स सेमीनेक

4

OverInterceptTouchEvent () और / या onTouchEvent () दोनों में से ओवरराइड करने और वापस लौटने की कोशिश करें , जो पेजर पर स्पर्श घटनाओं का उपभोग करेगा।


1
वह trueस्पर्श घटना को नियंत्रित करने के लिए वापस जाना नहीं चाहता है ?
22 मई को एडथर्थर्ड

1

विशिष्ट पृष्ठ पर स्वाइपिंग अक्षम करने का एक और आसान उपाय (इस उदाहरण में, पृष्ठ 2):

int PAGE = 2;
viewPager.setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
        if (viewPager.getCurrentItem() == PAGE) {
                viewPager.setCurrentItem(PAGE-1, false);
                viewPager.setCurrentItem(PAGE, false);
                return  true;
        }
        return false;
}

1
This worked for me

viewPager.setOnTouchListener(new View.OnTouchListener() {
                                         @Override
                                         public boolean onTouch(View v, MotionEvent event) {
                                             if (viewPager.getCurrentItem() == 0) {
                                                 viewPager.setCurrentItem(-1, false);
                                                 return true;
                                             }
                                             else if (viewPager.getCurrentItem() == 1) {
                                                 viewPager.setCurrentItem(1, false);
                                                 return true;
                                             }
                                             else if (viewPager.getCurrentItem() == 2) {
                                                 viewPager.setCurrentItem(2, false);
                                                 return true;
                                             }
                                             return true;
                                         }
                                     });

1

आप के साथ एक छवि गैलरी लिखते हैं ImageViewऔर ViewPager, कि समर्थन करता है ज़ूम और पैन, एक सरल उपाय यहाँ वर्णित देखें: Phimpme एंड्रॉयड में डिफ़ॉल्ट ViewPager विस्तार से एक zoomable imageView को लागू करने के लिए (और Github नमूना - PhotoView )। यह समाधान ViewPagerअकेले काम नहीं करता है ।

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

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

    @Override
    public boolean onInterceptTouchEvent(MotionEvent event) {
        try {
            return super.onInterceptTouchEvent(event);
        } catch (IllegalArgumentException e) {
            return false;
        }
    }
}

0

यदि आप Xamarin में Android के लिए समान लागू करना चाहते हैं, तो यहां C # का अनुवाद है

मैंने " स्क्रॉलएनेबल्ड " विशेषता का नाम चुना । क्योंकि iOS सिर्फ एक्सैट नामकरण का उपयोग करता है। तो, आपके पास दोनों प्लेटफार्मों में समान नामकरण है, यह डेवलपर्स के लिए आसान बनाता है।

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using Android.Support.V4.View;
using Android.Util;

namespace YourNameSpace.ViewPackage {

    // Need to disable swiping for ViewPager, if user performs Pre DSA and the dsa is not completed yet
    // http://stackoverflow.com/questions/9650265/how-do-disable-paging-by-swiping-with-finger-in-viewpager-but-still-be-able-to-s
    public class CustomViewPager: ViewPager {
        public bool ScrollEnabled;

        public CustomViewPager(Context context, IAttributeSet attrs) : base(context, attrs) {
            this.ScrollEnabled = true;
        }

        public override bool OnTouchEvent(MotionEvent e) {
            if (this.ScrollEnabled) {
                return base.OnTouchEvent(e);
            }
            return false;
        }

        public override bool OnInterceptTouchEvent(MotionEvent e) {
            if (this.ScrollEnabled) {
                return base.OnInterceptTouchEvent(e);
            }
            return false;
        }

        // For ViewPager inside another ViewPager
        public override bool CanScrollHorizontally(int direction) {
            return this.ScrollEnabled && base.CanScrollHorizontally(direction);
        }

        // Some devices like the Galaxy Tab 4 10' show swipe buttons where most devices never show them
        // So, you could still swipe through the ViewPager with your keyboard keys
        public override bool ExecuteKeyEvent(KeyEvent evt) {
            return this.ScrollEnabled ? base.ExecuteKeyEvent(evt) : false;
        }
    }
}

.Axml फ़ाइल में:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
  <YourNameSpace.ViewPackage.CustomViewPager
      android:id="@+id/pager"
      android:layout_width="match_parent"
      android:layout_height="wrap_content"
      android:background="@android:color/white"
      android:layout_alignParentTop="true" />
</LinearLayout>

0

उपरोक्त कोड में से कोई भी सुचारू रूप से काम नहीं कर रहा है। मैंने यह कोशिश की

<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/pager"
                        android:layout_width="match_parent"
                        android:layout_height="match_parent" />
                </HorizontalScrollView>

0

यहाँ मेरा कार्यान्वयन है
कि यदि आप स्वाइप एनीमेशन को निष्क्रिय करना चाहते हैं तो आप बाईं और दाईं ओर स्वाइपलिस्ट का उपयोग कर सकते हैं और फिर भी उंगली से स्क्रॉल करना चाहते हैं लेकिन बिना एनीमेशन के

1-ओवरराइड Viewpagerविधि onInterceptTouchEventऔरonTouchEvent

2- अपना खुद का बनाएं GestureDetector

3- स्वाइप जेस्चर का पता लगाएं और इस्तेमाल करें setCurrentItem(item, false)

ViewPager

public class ViewPagerNoSwipe extends ViewPager {
    private final GestureDetector gestureDetector;
    private OnSwipeListener mOnSwipeListener;

    public void setOnSwipeListener(OnSwipeListener onSwipeListener) {
        mOnSwipeListener = onSwipeListener;
    }

    public ViewPagerNoSwipe(@NonNull Context context) {
        super(context);
        gestureDetector = new GestureDetector(context, new GestureListener());

    }

    public ViewPagerNoSwipe(@NonNull Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        gestureDetector = new GestureDetector(context, new GestureListener());


    }

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        return true;
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        gestureDetector.onTouchEvent(ev);
        return false;
    }

    public class GestureListener extends GestureDetector.SimpleOnGestureListener {

        private static final int SWIPE_THRESHOLD = 100;
        private static final int SWIPE_VELOCITY_THRESHOLD = 100;

        @Override
        public boolean onDown(MotionEvent e) {
            return true;
        }

        @Override
        public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
            boolean result = false;
            try {
                float diffY = e2.getY() - e1.getY();
                float diffX = e2.getX() - e1.getX();
                if (Math.abs(diffX) > Math.abs(diffY)) {
                    if (Math.abs(diffX) > SWIPE_THRESHOLD && Math.abs(velocityX) > SWIPE_VELOCITY_THRESHOLD) {
                        if (diffX > 0) {
                            if(mOnSwipeListener!=null)
                            mOnSwipeListener.onSwipeRight();
                        } else {
                            if(mOnSwipeListener!=null)
                                mOnSwipeListener.onSwipeLeft();
                        }
                        result = true;
                    }
                } else if (Math.abs(diffY) > SWIPE_THRESHOLD && Math.abs(velocityY) > SWIPE_VELOCITY_THRESHOLD) {
                    if (diffY > 0) {
                        if(mOnSwipeListener!=null)
                            mOnSwipeListener.onSwipeBottom();
                    } else {
                        if(mOnSwipeListener!=null)
                            mOnSwipeListener.onSwipeTop();
                    }
                    result = true;
                }
            } catch (Exception exception) {
                exception.printStackTrace();
            }
            return result;
        }
    }

    public interface OnSwipeListener {

         void onSwipeRight();

        void onSwipeLeft();

        void onSwipeTop();

        void onSwipeBottom();
    }
}

जब आप ViewPager सेट कर रहे हैं swipeListener सेट करें

postsPager.setOnSwipeListener(new ViewPagerNoSwipe.OnSwipeListener() {
            @Override
            public void onSwipeRight() {

              postsPager.setCurrentItem(postsPager.getCurrentItem() + 1,false);

            }

            @Override
            public void onSwipeLeft() {

            postsPager.setCurrentItem(postsPager.getCurrentItem() - 1, false);

            }
             ...
           }

0

मैंने बस व्यूपेजर को थोड़ा अनुकूलित किया है और आसानी से स्वाइप करना अक्षम कर दिया है।

public class CustomViewPager extends ViewPager {

private boolean swipeLocked;

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

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

public boolean getSwipeLocked() {
    return swipeLocked;
}

public void setSwipeLocked(boolean swipeLocked) {
    this.swipeLocked = swipeLocked;
}

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

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

@Override
public boolean canScrollHorizontally(int direction) {
    return !swipeLocked && super.canScrollHorizontally(direction);
}
}

0

यदि आप ViewPager2 का उपयोग कर रहे हैं, तो आपको बस उपयोग करना है:

viewpager.setUserInputEnabled(false);

से डॉक्स :

स्क्रॉल किए गए उपयोगकर्ता को सक्षम या अक्षम करें। इसमें टच इनपुट (स्क्रॉल और फ्लिंग जेस्चर) और एक्सेसिबिलिटी इनपुट शामिल हैं। कीबोर्ड इनपुट को अक्षम करना अभी तक समर्थित नहीं है। जब उपयोगकर्ता ने स्क्रॉल करना शुरू किया है तो वह अक्षम है, प्रोग्राममैटिक स्क्रॉल सेट के माध्यम से चलता है। यह अभी भी काम करता है। डिफ़ॉल्ट रूप से, उपयोगकर्ता द्वारा शुरू की गई स्क्रॉलिंग सक्षम है।

आभार: https://stackoverflow.com/a/61685871/9026710


-1
shareViewPager?.setOnTouchListener(object :View.OnTouchListener{
            override fun onTouch(v: View?, event: MotionEvent?): Boolean {
                for (PAGE in 0..shareViewPager.adapter!!.count){
                    if (shareViewPager.currentItem==PAGE){
                        shareViewPager.setCurrentItem(PAGE-1,false)
                        shareViewPager.setCurrentItem(PAGE,false)
                    }}
                return true
            }

        })
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.