Android: कार्यक्षेत्र ViewPager [बंद]


130

वहाँ एक रास्ता बनाने के लिए है ViewPagerकि क्षैतिज स्क्रॉल नहीं करता है, लेकिन खड़ी है ?!


1
एक ऊर्ध्वाधर ViewPager का एक नया अनौपचारिक खुला स्रोत कार्यान्वयन है: घोषणा: plus.google.com/10777770404674344404096/posts/1FTJfrvnY8w कोड: github.com/LamacgaR/VerticalViewPager
Vasily Sochinsky

एंटोनी मर्ले द्वारा कार्यक्षेत्र दृश्य पेजर कार्यान्वयन: github.com/castorflex/VerticalViewPager
micnoy

19 सपोर्ट लाइब्रेरी पर आधारित एक नया कार्यान्वयन है: github.com/castorflex/VerticalViewPager
वासिली सोचिंस्की

यह समान नाम होने के बावजूद github.com/castorflex/VerticalViewPager जैसी नहीं है।
फ़्लिम

1
वहाँ नियंत्रण कहा जाता है ViewPager2 जांच डेमो के लिए यहां stackoverflow.com/a/54643817/7666442
नीलेश राठौड़

जवाबों:


227

वर्टिकल का भ्रम देने के लिए आप ViewPager.PageTransformer का उपयोग कर सकते हैं ViewPager। क्षैतिज ड्रैग के बजाय वर्टिकल के साथ स्क्रॉलिंग प्राप्त करने के लिए आपको ViewPagerडिफ़ॉल्ट टच ईवेंट्स को ओवरराइड करना होगा और MotionEventउन्हें संभालने से पहले एस के निर्देशांक को स्वैप करना होगा, जैसे:

/**
 * Uses a combination of a PageTransformer and swapping X & Y coordinates
 * of touch events to create the illusion of a vertically scrolling ViewPager. 
 * 
 * Requires API 11+
 * 
 */
public class VerticalViewPager extends ViewPager {

    public VerticalViewPager(Context context) {
        super(context);
        init();
    }

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

    private void init() {
        // The majority of the magic happens here
        setPageTransformer(true, new VerticalPageTransformer());
        // The easiest way to get rid of the overscroll drawing that happens on the left and right
        setOverScrollMode(OVER_SCROLL_NEVER);
    }

    private class VerticalPageTransformer implements ViewPager.PageTransformer {

        @Override
        public void transformPage(View view, float position) {

            if (position < -1) { // [-Infinity,-1)
                // This page is way off-screen to the left.
                view.setAlpha(0);

            } else if (position <= 1) { // [-1,1]
                view.setAlpha(1);

                // Counteract the default slide transition
                view.setTranslationX(view.getWidth() * -position);

                //set Y position to swipe in from top
                float yPosition = position * view.getHeight();
                view.setTranslationY(yPosition);

            } else { // (1,+Infinity]
                // This page is way off-screen to the right.
                view.setAlpha(0);
            }
        }
    }

    /**
     * Swaps the X and Y coordinates of your touch event.
     */
    private MotionEvent swapXY(MotionEvent ev) {
        float width = getWidth();
        float height = getHeight();

        float newX = (ev.getY() / height) * width;
        float newY = (ev.getX() / width) * height;

        ev.setLocation(newX, newY);

        return ev;
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev){
        boolean intercepted = super.onInterceptTouchEvent(swapXY(ev));
        swapXY(ev); // return touch coordinates to original reference frame for any child views
        return intercepted;
    }

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        return super.onTouchEvent(swapXY(ev));
    }

}

बेशक आप इन सेटिंग्स को ट्विस्ट कर सकते हैं क्योंकि आप फिट दिखते हैं। इस तरह देख रहे हैं:

वर्टिकल व्यू पेजर डेमो


3
@Der Golem इसके लिए लेआउट का उपयोग कैसे करें?
bhahah

सटीक सवाल क्या है? वैसे, मैंने जवाब पोस्ट नहीं किया, बस संदर्भित छवि को जोड़ा।
फैंटमैक्स

1
@ इस उदाहरण से मैं बाएं और दाएं स्वाइप पर कुछ कार्रवाई करना चाहता हूं। ऐसा कैसे करें
प्रभा

1
@ यह उम्मीद के मुताबिक काम करता है, संक्रमण लंबवत हो रहा है। लेकिन समस्या यह है कि मुझे संक्रमण करने के लिए दाएं / बाएं स्वाइप करना पड़ता है और ऊपर / नीचे स्वाइप करने पर कोई संक्रमण नहीं होता है।
करण खुराना

2
@ ब्रेट मैं आपके समाधान का उपयोग कर रहा था। लेकिन अब मैं andorid पाई डिवाइसेस में स्वाइपिंग इश्यू प्राप्त कर रहा हूं। किसी एक ही मुद्दे का सामना कर रहा है?
जिषांत

20

कार्यक्षेत्र देखें

यहाँ अन्य जवाबों से लगता है कि उनके साथ कुछ समस्याएँ थीं। यहां तक ​​कि अनुशंसित ओपन सोर्स प्रोजेक्ट्स बग फिक्स के साथ हाल के पुल अनुरोधों को विलय नहीं कर रहे थे। तब मुझे VerticalViewPagerGoogle से पता चला कि उन्होंने कुछ डेस्कलॉक ऐप का इस्तेमाल किया था। मुझे विश्वास है कि Google के कार्यान्वयन का उपयोग यहां पर तैर रहे अन्य उत्तरों की तुलना में बहुत अधिक है। (Google का संस्करण वर्तमान टॉप-वोट किए गए उत्तर के समान है, लेकिन अधिक संपूर्ण है।)

पूर्ण उदाहरण

यह उदाहरण लगभग मेरे मूल ViewPager उदाहरण के समान है , VerticalViewPagerवर्ग का उपयोग करने के लिए कुछ मामूली परिवर्तनों के साथ ।

यहाँ छवि विवरण दर्ज करें

एक्सएमएल

मुख्य गतिविधि और प्रत्येक पृष्ठ (टुकड़ा) के लिए xml लेआउट जोड़ें। ध्यान दें कि हम VerticalViewPagerमानक के बजाय उपयोग करते हैं ViewPager। मैं नीचे उस के लिए कोड शामिल करूंगा।

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.example.verticalviewpager.MainActivity">

    <com.example.myapp.VerticalViewPager
        android:id="@+id/viewpager"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</RelativeLayout>

fragment_one.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
                android:layout_width="match_parent"
                android:layout_height="match_parent" >

    <TextView
        android:id="@+id/textview"
        android:textSize="30sp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true" />

</RelativeLayout>

कोड

कोड के लिए VerticalViewPagerमेरा नहीं है। यह Google स्रोत कोड से केवल एक छीन लिया गया संस्करण (टिप्पणियों के बिना) है। सबसे अद्यतित संस्करण के लिए इसे देखें। वहाँ की टिप्पणियाँ समझने के लिए भी सहायक होती हैं कि क्या हो रहा है।

VerticalViewPager.java

import android.support.v4.view.ViewPager;    

public class VerticalViewPager extends ViewPager {

    public VerticalViewPager(Context context) {
        this(context, null);
    }

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

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

    @Override
    public boolean canScrollVertically(int direction) {
        return super.canScrollHorizontally(direction);
    }

    private void init() {
        setPageTransformer(true, new VerticalPageTransformer());
        setOverScrollMode(View.OVER_SCROLL_NEVER);
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        final boolean toIntercept = super.onInterceptTouchEvent(flipXY(ev));
        flipXY(ev);
        return toIntercept;
    }

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        final boolean toHandle = super.onTouchEvent(flipXY(ev));
        flipXY(ev);
        return toHandle;
    }

    private MotionEvent flipXY(MotionEvent ev) {
        final float width = getWidth();
        final float height = getHeight();
        final float x = (ev.getY() / height) * width;
        final float y = (ev.getX() / width) * height;
        ev.setLocation(x, y);
        return ev;
    }

    private static final class VerticalPageTransformer implements ViewPager.PageTransformer {
        @Override
        public void transformPage(View view, float position) {
            final int pageWidth = view.getWidth();
            final int pageHeight = view.getHeight();
            if (position < -1) {
                view.setAlpha(0);
            } else if (position <= 1) {
                view.setAlpha(1);
                view.setTranslationX(pageWidth * -position);
                float yPosition = position * pageHeight;
                view.setTranslationY(yPosition);
            } else {
                view.setAlpha(0);
            }
        }
    }
}

MainActivity.java

मैंने केवल इसके VerticalViewPagerलिए अदला-बदली की ViewPager

import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;

public class MainActivity extends AppCompatActivity {

    static final int NUMBER_OF_PAGES = 2;

    MyAdapter mAdapter;
    VerticalViewPager mPager;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mAdapter = new MyAdapter(getSupportFragmentManager());
        mPager = findViewById(R.id.viewpager);
        mPager.setAdapter(mAdapter);
    }

    public static class MyAdapter extends FragmentPagerAdapter {
        public MyAdapter(FragmentManager fm) {
            super(fm);
        }

        @Override
        public int getCount() {
            return NUMBER_OF_PAGES;
        }

        @Override
        public Fragment getItem(int position) {

            switch (position) {
                case 0:
                    return FragmentOne.newInstance(0, Color.WHITE);
                case 1:
                    // return a different Fragment class here
                    // if you want want a completely different layout
                    return FragmentOne.newInstance(1, Color.CYAN);
                default:
                    return null;
            }
        }
    }

    public static class FragmentOne extends Fragment {

        private static final String MY_NUM_KEY = "num";
        private static final String MY_COLOR_KEY = "color";

        private int mNum;
        private int mColor;

        // You can modify the parameters to pass in whatever you want
        static FragmentOne newInstance(int num, int color) {
            FragmentOne f = new FragmentOne();
            Bundle args = new Bundle();
            args.putInt(MY_NUM_KEY, num);
            args.putInt(MY_COLOR_KEY, color);
            f.setArguments(args);
            return f;
        }

        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            mNum = getArguments() != null ? getArguments().getInt(MY_NUM_KEY) : 0;
            mColor = getArguments() != null ? getArguments().getInt(MY_COLOR_KEY) : Color.BLACK;
        }

        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                                 Bundle savedInstanceState) {
            View v = inflater.inflate(R.layout.fragment_one, container, false);
            v.setBackgroundColor(mColor);
            TextView textView = v.findViewById(R.id.textview);
            textView.setText("Page " + mNum);
            return v;
        }
    }
}

ख़त्म होना

आपको ऐप चलाने में सक्षम होना चाहिए और ऊपर दिए गए एनीमेशन में परिणाम देखना चाहिए।

यह सभी देखें


3
कोड ठीक ठीक जा रहा है, बस 1 छोटी मदद की जरूरत है। वर्तमान कोड में हमें अगला पृष्ठ प्राप्त करने के लिए नीचे से ऊपर तक स्वाइप करना होगा, लेकिन मैं चाहता हूं कि छोटे स्वाइप को भी अगला पृष्ठ मिलना चाहिए।
AMIT

20

मेरे पास एक समाधान है जो मेरे लिए दो चरणों में काम करता है।

  1. onInstantiateItem()की PagerAdapter, दृश्य बनाते हैं और -90 से यह बारी बारी से:

    view.setRotation(-90f)

    यदि आप उपयोग कर रहे हैं FragmentPagerAdapter, तो:

    objFragment.getView().setRotation(-90)
  2. ViewPager90 डिग्री से घुमाएँ दृश्य:

    objViewPager.setRotation(90)

कम से कम मेरी आवश्यकता के लिए एक आकर्षण की तरह काम करता है।


4
यह समाधान काम करता है, लेकिन आपको अभी भी क्षैतिज रूप से स्वाइप करना पड़ता है जबकि दृश्यदर्शी अब लंबवत स्क्रॉल करता है
leochab

@Kulai मुझे स्पष्ट नहीं है कि आप यहाँ क्या कर सकते हैं कृपया मेरी समझ के अनुसार थोड़ा सा समझा सकते हैं, हमारे पास सार्वजनिक वस्तु तात्कालिकता है (ViewGroup कंटेनर, int स्थिति) यहाँ हमें कंटेनर करने की आवश्यकता है ।सेटेशन (-90f);
वरुण

1
ऐसा करना एक आकर्षण की तरह काम करता है! Althoug का दृश्य ऊपर और नीचे के भाग में कट जाता है, और मैं यह पता नहीं लगा सकता कि: - /
Nivaldo Bondança

2
यह एक वर्ग छवि के लिए ठीक से काम करता है और आयताकार के लिए नहीं। आयत के घूमने पर आयाम गलत हो जाते हैं।
कुलैय्या

1
मुझे यकीन नहीं है कि इस उत्तर को किसने वोट दिया। यह वर्टिकल व्यूपेजर नहीं है, यह 90 डिग्री घुमाए गए व्यूपेजर है, इशारा और संक्रमण ठीक इसके विपरीत है। और यह
बिलकुल

14

किसी ऐसे व्यक्ति के लिए, जो ऊर्ध्वाधर व्यूपेजर को क्षैतिज के अंदर काम करने के तरीके से जूझ रहा है, बस निम्नलिखित चीजें करें:

कार्यक्षेत्र देखें

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

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

    private void init() {
        setPageTransformer(true, new VerticalPageTransformer());
        setOverScrollMode(OVER_SCROLL_NEVER);
    }

    private class VerticalPageTransformer implements ViewPager.PageTransformer {

        @Override
        public void transformPage(View view, float position) {

            if (position < -1) {
                view.setAlpha(0);
            } else if (position <= 1) {
                view.setAlpha(1);

                view.setTranslationX(view.getWidth() * -position);

                float yPosition = position * view.getHeight();
                view.setTranslationY(yPosition);
            } else {
                view.setAlpha(0);
            }
        }
    }

    private MotionEvent swapXY(MotionEvent ev) {
        float width = getWidth();
        float height = getHeight();

        float newX = (ev.getY() / height) * width;
        float newY = (ev.getX() / width) * height;

        ev.setLocation(newX, newY);

        return ev;
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        boolean intercepted = super.onInterceptTouchEvent(swapXY(ev));
        swapXY(ev);
        return intercepted;
    }

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        return super.onTouchEvent(swapXY(ev));
    }

}

क्षैतिज दृश्यदर्शी

public class HorizontalViewPager extends ViewPager {
    private GestureDetector xScrollDetector;

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

    public HorizontalViewPager(Context context, AttributeSet attrs) {
        super(context, attrs);
        xScrollDetector = new GestureDetector(getContext(), new XScrollDetector());
    }

    class XScrollDetector extends GestureDetector.SimpleOnGestureListener {
        @Override
        public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
            return Math.abs(distanceX) > Math.abs(distanceY);
        }
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        if (xScrollDetector.onTouchEvent(ev)) {
            super.onInterceptTouchEvent(ev);
            return true;
        }

        return super.onInterceptTouchEvent(ev);
    }

}

मैं इस क्षैतिज और ऊर्ध्वाधर दृश्य पेजर को अपने विचार से कैसे जोड़ सकता हूं?
user1810931

ट्यूटोरियल के साथ शुरू करो - vogella.com/tutorials/AndroidCustomViews/article.html
गोताखोर

मैं अपने दृष्टिकोण में उपरोक्त क्षैतिज और ऊर्ध्वाधर दृश्य पेजर कक्षाओं को कैसे लागू करूं? कोड स्निपेट मदद करता है
user1810931

ViewPager पहले से ही देखने वाला है, मुझे समझ नहीं आ रहा है कि आप इसके बारे में क्या पूछ रहे हैं।
डाइवर्स

मैं "मटेरियल कैलेंडर व्यू" नामक एक लाइब्रेरी का उपयोग कर रहा हूं ( github.com/prolificinteractive/material-calendarview ) और इसमें पहले से ही क्षैतिज व्यूपेजर है और मैं इसमें वर्टिकल व्यूपेजर जोड़ना चाहता हूं।
14:18 बजे उपयोगकर्ता 1810931

8

इस उत्तर को थोड़ा विस्तार देने से मुझे अपनी आवश्यकता को प्राप्त करने में मदद मिली (वर्टिकल व्यू पेजर को चेतन करने के लिए जैसा कि इनशॉर्ट्स में है - समाचार 60 साल में )

public class VerticalViewPager extends ViewPager {

public VerticalViewPager(Context context) {
    super(context);
    init();
}

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

private void init() {
    // The majority of the magic happens here
    setPageTransformer(true, new VerticalPageTransformer());
    // The easiest way to get rid of the overscroll drawing that happens on the left and right
    setOverScrollMode(OVER_SCROLL_NEVER);
}

private class VerticalPageTransformer implements ViewPager.PageTransformer {
 private static final float MIN_SCALE = 0.75f;
    @Override
    public void transformPage(View view, float position) {

        if (position < -1) { // [-Infinity,-1)
            // This page is way off-screen to the left.
            view.setAlpha(0);

        }  else if (position <= 0) { // [-1,0]
            // Use the default slide transition when moving to the left page
            view.setAlpha(1);
            // Counteract the default slide transition
            view.setTranslationX(view.getWidth() * -position);

            //set Y position to swipe in from top
            float yPosition = position * view.getHeight();
            view.setTranslationY(yPosition);
            view.setScaleX(1);
            view.setScaleY(1);

        } else if (position <= 1) { // [0,1]
            view.setAlpha(1);

            // Counteract the default slide transition
            view.setTranslationX(view.getWidth() * -position);


            // Scale the page down (between MIN_SCALE and 1)
            float scaleFactor = MIN_SCALE
                    + (1 - MIN_SCALE) * (1 - Math.abs(position));
            view.setScaleX(scaleFactor);
            view.setScaleY(scaleFactor);

        } else { // (1,+Infinity]
            // This page is way off-screen to the right.
            view.setAlpha(0);
        }

    }

}

/**
 * Swaps the X and Y coordinates of your touch event.
 */
private MotionEvent swapXY(MotionEvent ev) {
    float width = getWidth();
    float height = getHeight();

    float newX = (ev.getY() / height) * width;
    float newY = (ev.getX() / width) * height;

    ev.setLocation(newX, newY);

    return ev;
}

@Override
public boolean onInterceptTouchEvent(MotionEvent ev){
    boolean intercepted = super.onInterceptTouchEvent(swapXY(ev));
    swapXY(ev); // return touch coordinates to original reference frame for any child views
    return intercepted;
}

@Override
public boolean onTouchEvent(MotionEvent ev) {
    return super.onTouchEvent(swapXY(ev));
}
}

मुझे उम्मीद है कि यह किसी और के लिए उपयोगी हो सकता है।


1
MIN_SCALE के लिए आदर्श मूल्य?
दिव्येंदुज

क्या आपको तेज़ी से स्वाइप करने की समस्या नहीं मिली, संक्रमण सुचारू नहीं है
प्रणीत

पृथ्वी पर कोई क्यों तेजी से स्वाइप करेगा?
अमृत ​​बिदरी

स्पष्ट करने के लिए बस एक टिप्पणी: यह समाधान एनीमेशन को इस तरह से बदलता है कि नया पृष्ठ नीचे से नहीं आता है, बल्कि पुराने पृष्ठ के पीछे से आता है। इसलिए मूल रूप से आपके पास एक-दूसरे के बगल में बिछाने वाले पृष्ठ नहीं हैं, बल्कि एक-दूसरे के शीर्ष पर, पृष्ठों का एक डेक है। इसलिए, यह समाधान नहीं हो सकता है कि मूल प्रश्न क्या करने की कोशिश कर रहा है।
बेंजामिन बासमासी

4

कुछ ओपन सोर्स प्रोजेक्ट हैं जो ऐसा करने का दावा करते हैं। वे यहाँ हैं:

इन्हें उनके लेखकों द्वारा पदावनत किया गया है:

एक और बात:

  • ऐप से Android स्रोत में एक फ़ाइल का नाम VerticalViewPager.java भी है deskclock, लेकिन यह आधिकारिक तौर पर समर्थित नहीं लगता क्योंकि मुझे इसके लिए दस्तावेज़ नहीं मिले।

3

इसे देखें: https://github.com/JakeWharton/Android-DirectionalViewPager

या निम्नलिखित प्रश्न आपकी मदद कर सकते हैं: कार्यक्षेत्र 'पेज के साथ ग्रिड' या 'व्यूपेजर'


2
कुछ ध्यान में रखना यह है कि DirectionalViewPagerकाफी समय से अपडेट नहीं किया गया है और इसलिए ViewPagerसमर्थन लाइब्रेरी में कुछ नई सुविधाओं की कमी है ; यानी setPageMargin(int)। आम तौर पर यह काम करना चाहिए। और यदि नहीं, तो स्रोत कोड को हड़पने ViewPagerऔर सभी x / y और चौड़ाई / ऊंचाई तर्क को स्वैप करने के लिए बहुत मुश्किल नहीं है ।
एमएच।

मैं पहले से ही इस पर विचार कर चुका हूं DirectionalViewPager, जैसा कि एमएच ने कहा, यह अपडेट नहीं है (इसके डेवलपर इसे डीप्रेक्टेड मानते हैं) !! यह अविश्वसनीय है कि एंड्रॉइड डेवलपर्स ने समुदाय को एक ऊर्ध्वाधर नहीं प्रदान किया है ViewPager, लेकिन केवल क्षितिज। मैं एंड्रॉइड के लिए नया हूं, अपना वर्टिकल ViewPagerस्वैपिंग एक्स / वाई विकसित करना मेरे लिए इतना आसान नहीं है .. मैं पहले से निर्मित समाधान पसंद करूंगा .. वैसे भी, धन्यवाद
user1709805

2
नमस्ते, क्या आप ऊर्ध्वाधर दृश्यदर्शी करने में कामयाब रहे ?? thansk
पॉल

3

डिवाइस के डिस्प्ले के आयताकार होने के बाद से निर्देशांक (X, Y) को (Y, X) में सही ढंग से बदलने के लिए @Brett और @ Salman666 से जवाबों पर सिर्फ एक सुधार :

...

/**
 * Swaps the X and Y coordinates of your touch event
 */
@Override
public boolean onTouchEvent(MotionEvent ev) {
    return super.onTouchEvent(swapXY(ev));
}

@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
    return super.onInterceptTouchEvent(swapXY(ev));
}

private MotionEvent swapXY(MotionEvent ev) {

    //Get display dimensions
    float displayWidth=this.getWidth();
    float displayHeight=this.getHeight();

    //Get current touch position
    float posX=ev.getX();
    float posY=ev.getY();

    //Transform (X,Y) into (Y,X) taking display dimensions into account
    float newPosX=(posY/displayHeight)*displayWidth;
    float newPosY=(1-posX/displayWidth)*displayHeight;

    //swap the x and y coords of the touch event
    ev.setLocation(newPosX, newPosY);

    return ev;
}

...

हालाँकि, टचस्क्रीन रिस्पॉन्सिबिलिटी को बेहतर बनाने के लिए अभी भी कुछ किया जाना चाहिए। यह समस्या उस समस्या से संबंधित हो सकती है, जिसमें @msdark ने @ Salman666 के उत्तर पर टिप्पणी की हो।


मैं हमेशा वापस लौट कर कुछ सुधार है trueमें onInterceptTouchEventऔर मैं भी कुंजी बाइंडिंग संशोधित कर लिया है, ताकि एक DPAD यह उत्तर प्रदेश / नीचे के साथ स्क्रॉल से चलाता है का उपयोग कर के बजाय छोड़ दिया / सही: gist.github.com/zevektor/fbacf4f4f6c39fd6e409
Vektor88

@ Vektor88 हमेशा सच लौटने से आंतरिक घटनाओं को स्पर्श घटनाओं को प्राप्त करने से रोका जा सकेगा। सबसे अच्छा समाधान ब्रेट उत्तर के रूप में है ..
मोहम्मद ज़कराल्लाह

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

public class VerticalViewPager extends ViewPager {

    public VerticalViewPager(Context context) {
        super(context);
        init();
    }


    public VerticalViewPager(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }
    private void init() {

        setPageTransformer(true, new VerticalPageTransformer());

        setOverScrollMode(OVER_SCROLL_NEVER);
    }

    private class VerticalPageTransformer implements PageTransformer {

        @Override
        public void transformPage(View view, float position) {
            int pageWidth = view.getWidth();
            int pageHeight = view.getHeight();

            if (position < -1) {

                view.setAlpha(0);

            } else if (position <= 1) {
                view.setAlpha(1);


                view.setTranslationX(pageWidth * -position);


                float yPosition = position * pageHeight;
                view.setTranslationY(yPosition);

            } else {

                view.setAlpha(0);
            }
        }
    }
        @Override
    public boolean onTouchEvent(MotionEvent ev) {

        ev.setLocation(ev.getY(), ev.getX());

        return super.onTouchEvent(ev);
    }
    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        ev.setLocation(ev.getY(), ev.getX());
        return super.onInterceptTouchEvent(ev);
    }
}

1
यह बहुत अच्छा काम करता है, लेकिन मैं तत्वों या बाईं / ज़ोर से मारना घटनाओं पर टचवेंट खो देता हूं ...
matiasfha

0

एंड्रॉइड स्रोत में वास्तव में पहले से ही एक है । मैंने इसे बेहतर काम करने के लिए संशोधित किया है:

package com.crnlgcs.sdk.widgets;



import android.content.Context;
import android.support.v4.view.ViewConfigurationCompat;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.ViewParent;

public class VerticalViewPager extends ViewPager {
    private static final String TAG = "VerticalViewPager";
    private static final boolean DEBUG = true;

    private float mLastMotionX;
    private float mLastMotionY;
    private float mTouchSlop;
    private boolean mVerticalDrag;
    private boolean mHorizontalDrag;

    // Vertical transit page transformer
    private final ViewPager.PageTransformer mPageTransformer = new ViewPager.PageTransformer() {
        @Override
        public void transformPage(View view, float position) {
            final int pageWidth = view.getWidth();
            final int pageHeight = view.getHeight();
            if (position < -1) {
                // This page is way off-screen to the left.
                view.setAlpha(0);
            } else if (position <= 1) {
                view.setAlpha(1);
                // Counteract the default slide transition
                view.setTranslationX(pageWidth * -position);
                // set Y position to swipe in from top
                float yPosition = position * pageHeight;
                view.setTranslationY(yPosition);
            } else {
                // This page is way off-screen to the right.
                view.setAlpha(0);
            }
        }
    };

    public VerticalViewPager(Context context) {
        super(context, null);
    }

    public VerticalViewPager(Context context, AttributeSet attrs) {
        super(context, attrs);
        final ViewConfiguration configuration = ViewConfiguration.get(context);
        mTouchSlop = ViewConfigurationCompat.getScaledPagingTouchSlop(configuration);
        init();
    }

    private void init() {
        // Make page transit vertical
        setPageTransformer(true, mPageTransformer);
        // Get rid of the overscroll drawing that happens on the left and right (the ripple)
        setOverScrollMode(View.OVER_SCROLL_NEVER);
    }

    @Override
    public boolean onTouchEvent(MotionEvent ev) {

        final float x = ev.getX();
        final float y = ev.getY();

        if (DEBUG) Log.v(TAG, "onTouchEvent " + x + ", " + y);

        switch (ev.getAction()) {
            case MotionEvent.ACTION_DOWN: {
                mLastMotionX = x;
                mLastMotionY = y;
                if (!super.onTouchEvent(ev))
                    return false;
                return verticalDrag(ev);
            }
            case MotionEvent.ACTION_MOVE: {
                final float xDiff = Math.abs(x - mLastMotionX);
                final float yDiff = Math.abs(y - mLastMotionY);
                if (!mHorizontalDrag && !mVerticalDrag) {
                    if (xDiff > mTouchSlop && xDiff > yDiff) { // Swiping left and right
                        mHorizontalDrag = true;
                    } else if (yDiff > mTouchSlop && yDiff > xDiff) { //Swiping up and down
                        mVerticalDrag = true;
                    }
                }
                if (mHorizontalDrag) {
                    return super.onTouchEvent(ev);
                } else if (mVerticalDrag) {
                    return verticalDrag(ev);
                }
            }
            case MotionEvent.ACTION_UP: {
                if (mHorizontalDrag) {
                    mHorizontalDrag = false;
                    return super.onTouchEvent(ev);
                }
                if (mVerticalDrag) {
                    mVerticalDrag = false;
                    return verticalDrag(ev);
                }
            }
        }
        // Set both flags to false in case user lifted finger in the parent view pager
        mHorizontalDrag = false;
        mVerticalDrag = false;

        return false;
    }


    private boolean verticalDrag(MotionEvent ev) {
        final float x = ev.getX();
        final float y = ev.getY();
        ev.setLocation(y, x);
        return super.onTouchEvent(ev);
    }
}

यह ठीक से काम नहीं कर रहा है .. यहां तक ​​कि एंड्रॉइड स्रोत संस्करण भी नहीं करता है .. इसकी गड़बड़ और केवल दाएं / बाएं इशारों के लिए काम करता है .. यदि आप ऊपर / नीचे करते हैं तो यह स्क्रॉल नहीं करता है .. कम से कम मेरे लिए ..
मोहम्मद ज़ेकरल्लाह

0

वर्तमान में अधिक सक्रिय भंडार lsjwzh / RecyclerViewPager है

  • अंतिम प्रतिबद्ध 12 अगस्त 2016, 16 योगदानकर्ता, 1840 सितारे
  • पर आधारित RecyclerView

0

यह एक अनुलंब स्क्रॉल दृश्य कार्यान्वयन है। RecyclerView और ListView के साथ अच्छी तरह से काम करता है। guochong / VerticalViewPager

ViewPager.PageTransformer का उपयोग ViewPager स्क्रॉल को लंबवत बनाने के लिए करें, और स्क्रॉल संघर्ष से निपटने के लिए View.OnTouchListener भी प्रदान करें।

/**
 * 1.dispatch ACTION_DOWN,ACTION_UP,ACTION_CANCEL to child<br>
 * 2.hack ACTION_MOVE
 *
 * @param v
 * @param e
 * @return
 */
@Override
public boolean onTouch(View v, MotionEvent e) {
    Log.i(TAG, "onTouchEvent " + ", action " + e.getAction() + ", e.rawY " + e.getRawY() + ",lastMotionY " + lastMotionY + ",downY " + downY);
    switch (e.getAction()) {
        case MotionEvent.ACTION_DOWN:
            downY = e.getRawY();
            break;
        case MotionEvent.ACTION_MOVE:

            if (downY == Float.MIN_VALUE && lastMotionY == Float.MIN_VALUE) {
                //not start from MOTION_DOWN, the child dispatch this first motion
                downY = e.getRawY();
                break;
            }

            float diff = e.getRawY() - (lastMotionY == Float.MIN_VALUE ? downY : lastMotionY);
            lastMotionY = e.getRawY();
            diff = diff / 2; //slow down viewpager scroll
            Log.e(TAG, "scrollX " + dummyViewPager.getScrollX() + ",basescrollX " + dummyViewPager.getBaseScrollX());

            if (dummyViewPager.getScrollX() != dummyViewPager.getBaseScrollX()) {
                if (fakeDragVp(v, e, diff)) return true;
            } else {
                if (ViewCompat.canScrollVertically(v, (-diff) > 0 ? 1 : -1)) {
                    Log.e(TAG, "scroll vertically  " + diff + ", move.lastMotionY " + e.getY());
                    break;
                } else {
                    dummyViewPager.beginFakeDrag();
                    fakeDragVp(v, e, diff);
                    adjustDownMotion(v, e);
                    return true;
                }
            }

            break;
        case MotionEvent.ACTION_UP:
        case MotionEvent.ACTION_CANCEL:
            if (dummyViewPager.isFakeDragging()) {
                try {
                    dummyViewPager.endFakeDrag();
                } catch (Exception e1) {
                    Log.e(TAG, "", e1);
                }
            }
            reset();
            break;
    }

    return false;
}

StackOverflow में आपका स्वागत है और आपकी मदद के लिए धन्यवाद। आप कुछ कोड जोड़कर अपने उत्तर को और बेहतर बनाना चाहते हैं।
एलियास एमपी

0

यहां तक ​​कि मुझे X और Y को स्वैप करके ViewPager को वर्टिकल बनाने में भी यही समस्या आ रही थी। यह बिल्कुल भी सहज नहीं था।

ऐसा इसलिए है क्योंकि यह तभी काम करता था जब स्वाइप करने का कोण 7.125 डिग्री = आर्कटिक (1/8) से कम था जबकि इंटरसेप्ट और 14 डिग्री = आर्कटिक (1/4) स्पर्श करते समय; जब मूल स्वाइप क्षैतिज एक काम करता है, जब स्वाइप करने का कोण 26.565 डिग्री = आर्कटन (1/2) से कम होता है, जबकि इंटरसेप्ट और 45 डिग्री = आर्कटन (1) स्पर्श करते समय।

इसलिए मैंने एंड्रॉइड सपोर्ट-कोर-यूआई के कोड को कॉपी किया और वैल्यूज़ को वेरिएबल्स में स्थानांतरित कर दिया, जिसे मैंने प्रतिबिंब का उपयोग करके गुणा किया।

कृपया https://github.com/deepakmishra/verticalviewpager और VerticalViewPager पर https://github.com/deepakmishra/verticalviewpager/blob/master/app/src/main/java/com/viewpager/VerticalViewPager पर कोड और README देखें। ।जावा


0

बेहतर तरीका यह है कि व्यूपैगर को 90 डिग्री तक घुमाया जाए, और स्थान को समायोजित करने के लिए बाधा का उपयोग करें।


0

मैंने एक नया DirectionalViewPager बनाना शुरू किया, जो या तो लंबवत या क्षैतिज रूप से स्क्रॉल कर सकता है क्योंकि सभी समाधान जो मैंने यहां देखे हैं, वे दोष हैं:

  1. मौजूदा वर्टिकल व्यूपेजर कार्यान्वयन (कैस्टरफ़्लेक्स और लैम्बर्गा द्वारा)

    • वे बहुत पुराने समर्थन पुस्तकालय संस्करणों पर आधारित हैं।
  2. समन्वय की अदला-बदली के साथ परिवर्तन की चाल

    • ओवरक्रॉलर को अभी भी बाएं / दाएं किनारों से दिखाया गया है।
    • पृष्ठ फ़्लिंगिंग ठीक से काम नहीं करता है, क्योंकि यहां तक ​​कि निर्देशांक स्वैप के साथ, VelocityTracker.computeCurrentVelocityअभी भी एक्स अक्ष के साथ वेग की गणना करता है, शायद क्योंकि यह आंतरिक रूप से एक देशी कॉल का उपयोग करता है जो समन्वय स्वैप को अनदेखा करता है।
  3. रोटेशन देखें

    • हैक जो हर बच्चे को देखने की जरूरत है उसे भी घुमाया जाए।
    • यदि आप कुछ और के लिए निर्देशांक पढ़ना चाहते हैं तो आपको अक्ष को स्वैप करना होगा।
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.