Circular scrolling with View Pager
Asked Answered
F

3

10

We have a requirement for sycing rotating wheel with sliding images. I have used ViewPager for it but after 360 degree rotation

I have to start scrolling ViewPager from X = 0. Is there any ViewPager which starts from first page after scrolled to last position?

I use setScrollX for scrolling ViewPager which also introduce glitches in rotating animation.

Fionnula answered 23/4, 2018 at 19:45 Comment(14)
There is nothing natively supported in viewpager that supports this, I believe there are libraries that can do this but you might still see "glitches" as they have to either mimic the first/last scroll or they create a large number of pages in the viewpager so that it looks like it is infiniteStpeter
Any idea how to implement this? We have to scroll it with Wheel like menu.Fionnula
May be github.com/TobiasBuchholz/CircularViewPager can help.Honeyman
It is based on the same technique every other library is using. I have to link it with the wheel. When I scroll it with the wheel movement, fragments do not load correctly, or don't even load at all.Fionnula
Have you considered InfiniteViewPager?Vapor
Yes. Nothing worksFionnula
You have to control animation with rotatable view. InfiniteViewPager works well standalone. There are InfiniteViewPager with indicator too. Search how to control animation. Your ViewPager rotator handle must pass movement in correct ratioChalky
Even with custom scroller ViewPager introduce glitches which effects the wheel to.Fionnula
You can use github.com/antonyt/InfiniteViewPager as suggested by @azizbekian. Additionally, set addOnPageChangeListener on ViewPager and in onPageScrolled play with positionOffset or positionOffsetPixels as input to rotating wheel animation.Surcharge
Thanks for answer @Anurag. I have to scroll view pager by getting angles from Wheel. The library you are pointing to stops populating fragments when it is scrolled programatically.Fionnula
@mallaudin Could, you post a simple project at github with the setup that you have?Surcharge
Yes sure. I am doing this in a while.Fionnula
@AnuragSingh I have added a link in the question. Please check.Fionnula
check image size first.Ablepsia
C
1

Forget about ViewPager it's expensive, views is everything. You need three inflated views let's say v1,v2,v3

I work with your provide git sample project, replace your HorizontalPaging with xml

<RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="300dp"
        android:id="@+id/scroller"
        app:layout_constraintEnd_toEndOf="parent"
        android:fillViewport="true"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent">


        <ImageView
            android:id="@+id/v1"
            android:layout_width="match_parent"
            android:layout_height="300dp"
            android:contentDescription="@null"
            android:src="@drawable/slider_topup" />

        <ImageView
            android:id="@+id/v2"
            android:layout_width="match_parent"
            android:layout_height="300dp"
            android:contentDescription="@null"
            android:src="@drawable/slider_balance" />

        <ImageView
            android:id="@+id/v3"
            android:layout_width="match_parent"
            android:layout_height="300dp"
            android:contentDescription="@null"
            android:src="@drawable/slider_bundles" />

    </RelativeLayout>

and add code to your onCreate

final View v1 = findViewById(R.id.v1);
        final View v2 = findViewById(R.id.v2);
        final View v3 = findViewById(R.id.v3);

        //set initial state keep it sync with wheel at start
        v1.setX(0);
        v2.setX(screenSize);
        v3.setX(2*screenSize);

        circle.setOnAngleChangeListener(new NowCircle.OnAngleChangeListener() {
            @Override
            public void onAngleChange(float delta) {
                float v1x = v1.getX() + (oneDegree * delta);
                float v2x = v2.getX() + (oneDegree * delta);
                float v3x = v3.getX() + (oneDegree * delta);

                Log.d("dd","delta:"+delta+", v1x:"+v1x+", v2x:"+v2x +", v3x:"+v3x);

                v1.setX(v1x);
                v2.setX(v2x);
                v3.setX(v3x);

                if(delta > 0){

                    if (v1x >= 0 && v1x <= screenSize) {
                        v3.setX(-screenSize+v1x);
                        //update data here
                    }else if (v3x >= 0  && v3x <= screenSize){
                        v2.setX(-screenSize+v3x);
                        //update data here
                    }else {
                        v1.setX(-screenSize+v2x);
                        //update data here
                    }
                }else {
                    if (v3x <= 0 && v3x >= -screenSize) {
                        v1.setX(screenSize+v3x);
                        //update data here
                    }else if(v1x <= 0 && v1x >= -screenSize){
                        v2.setX(screenSize+v1x);
                        //update data here
                    }else {
                        v3.setX(screenSize+v2x);
                        //update data here
                    }
                }
            }
        });

animation is achieved, working fine.

enter image description here

You need to improve this and bind data with your custom views and create one separate manage class. I put my time into this. you know :)

Chalky answered 26/4, 2018 at 10:20 Comment(4)
These menus are dynamic we fetch them from server.Fionnula
You can do that, fetch it from server and update both views, reset it's x keep array dataPosition along.Chalky
Ok. Let me check.Fionnula
You need to improve wheel animation and smooth value trigger, I'm working to make it more useful, add me on repo I will send you commit git user Qamar4PChalky
Z
3

It'd be simpler just to write a custom View for this. The layout seems simple (just a bunch of images) and ViewPager has a big overhead for simple things like this. With a custom view you can also deal with scrolling yourself via touch listeners.

Zacynthus answered 26/4, 2018 at 7:45 Comment(1)
Yes. I am thinking about it as I have already tried everything. It works with view pager but animation is not smooth.Fionnula
F
1

If you want to acheive something like your design then i suggest you to use ArcLayoutManager Library, I have used this library alongwith recycler View to get Arc Like menu.

Ferne answered 26/4, 2018 at 7:41 Comment(0)
C
1

Forget about ViewPager it's expensive, views is everything. You need three inflated views let's say v1,v2,v3

I work with your provide git sample project, replace your HorizontalPaging with xml

<RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="300dp"
        android:id="@+id/scroller"
        app:layout_constraintEnd_toEndOf="parent"
        android:fillViewport="true"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent">


        <ImageView
            android:id="@+id/v1"
            android:layout_width="match_parent"
            android:layout_height="300dp"
            android:contentDescription="@null"
            android:src="@drawable/slider_topup" />

        <ImageView
            android:id="@+id/v2"
            android:layout_width="match_parent"
            android:layout_height="300dp"
            android:contentDescription="@null"
            android:src="@drawable/slider_balance" />

        <ImageView
            android:id="@+id/v3"
            android:layout_width="match_parent"
            android:layout_height="300dp"
            android:contentDescription="@null"
            android:src="@drawable/slider_bundles" />

    </RelativeLayout>

and add code to your onCreate

final View v1 = findViewById(R.id.v1);
        final View v2 = findViewById(R.id.v2);
        final View v3 = findViewById(R.id.v3);

        //set initial state keep it sync with wheel at start
        v1.setX(0);
        v2.setX(screenSize);
        v3.setX(2*screenSize);

        circle.setOnAngleChangeListener(new NowCircle.OnAngleChangeListener() {
            @Override
            public void onAngleChange(float delta) {
                float v1x = v1.getX() + (oneDegree * delta);
                float v2x = v2.getX() + (oneDegree * delta);
                float v3x = v3.getX() + (oneDegree * delta);

                Log.d("dd","delta:"+delta+", v1x:"+v1x+", v2x:"+v2x +", v3x:"+v3x);

                v1.setX(v1x);
                v2.setX(v2x);
                v3.setX(v3x);

                if(delta > 0){

                    if (v1x >= 0 && v1x <= screenSize) {
                        v3.setX(-screenSize+v1x);
                        //update data here
                    }else if (v3x >= 0  && v3x <= screenSize){
                        v2.setX(-screenSize+v3x);
                        //update data here
                    }else {
                        v1.setX(-screenSize+v2x);
                        //update data here
                    }
                }else {
                    if (v3x <= 0 && v3x >= -screenSize) {
                        v1.setX(screenSize+v3x);
                        //update data here
                    }else if(v1x <= 0 && v1x >= -screenSize){
                        v2.setX(screenSize+v1x);
                        //update data here
                    }else {
                        v3.setX(screenSize+v2x);
                        //update data here
                    }
                }
            }
        });

animation is achieved, working fine.

enter image description here

You need to improve this and bind data with your custom views and create one separate manage class. I put my time into this. you know :)

Chalky answered 26/4, 2018 at 10:20 Comment(4)
These menus are dynamic we fetch them from server.Fionnula
You can do that, fetch it from server and update both views, reset it's x keep array dataPosition along.Chalky
Ok. Let me check.Fionnula
You need to improve wheel animation and smooth value trigger, I'm working to make it more useful, add me on repo I will send you commit git user Qamar4PChalky

© 2022 - 2024 — McMap. All rights reserved.