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




android-viewpager (11)

आपको ViewPager subclass करने की आवश्यकता है। ऑन टचएवेंट में बहुत अच्छी चीजें हैं जो आप बदलना नहीं चाहते हैं, जैसे बच्चे के विचार छूने की इजाजत देते हैं। 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" />

यह विशेष उदाहरण लीनियरलाउट में है और पूरी स्क्रीन लेने के लिए है, यही कारण है कि layout_weight 1 है और layout_height 0dp है।

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

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


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

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

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


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

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

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

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

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

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

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

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

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

सौभाग्य!


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

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

चूंकि गैलेक्सी टैब 4 10 जैसे कुछ डिवाइस इन बटनों को दिखाते हैं जहां अधिकांश डिवाइस उन्हें कभी नहीं दिखाते हैं:


यदि आप Xamarin में एंड्रॉइड के लिए इसे कार्यान्वित करना चाहते हैं, तो यहां सी #

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

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://.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>

यहां एक सरल समाधान का वर्णन किया गया है: फ़िम्मेम एंड्रॉइड (और गीथब नमूना - फोटो व्यू) में डिफ़ॉल्ट व्यूपेजर को बढ़ाकर ज़ूम करने योग्य छवि दृश्य को कार्यान्वित करना :

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

विशिष्ट पृष्ठ पर स्वाइप करने के लिए एक और आसान समाधान (इस उदाहरण में, पृष्ठ 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;
}

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

mViewPager.beginFakeDrag();

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

mViewPager.endFakeDrag();

onInterceptTouchEvent() और / या onInterceptTouchEvent() ओवरराइडिंग और सही से लौटने का प्रयास करें, जो पेजर पर टच इवेंट का उपभोग करेगा।


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




android-viewpager