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.

mallaudin
  • 4,235
  • 3
  • 29
  • 60
  • 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 infinite – tyczj Apr 23 '18 at 19:51
  • Any idea how to implement this? We have to scroll it with Wheel like menu. – mallaudin Apr 25 '18 at 15:45
  • May be https://github.com/TobiasBuchholz/CircularViewPager can help. – Ashish John Apr 26 '18 at 05:47
  • 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. – mallaudin Apr 26 '18 at 06:03
  • Have you considered [`InfiniteViewPager`](https://github.com/antonyt/InfiniteViewPager)? – azizbekian Apr 26 '18 at 06:16
  • Yes. Nothing works – mallaudin Apr 26 '18 at 06:22
  • 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 ratio – Qamar Apr 26 '18 at 06:25
  • Even with custom scroller *ViewPager* introduce glitches which effects the wheel to. – mallaudin Apr 26 '18 at 06:33
  • You can use https://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. – Anurag Singh Apr 26 '18 at 06:41
  • 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. – mallaudin Apr 26 '18 at 06:48
  • 1
    @mallaudin Could, you post a simple project at github with the setup that you have? – Anurag Singh Apr 26 '18 at 06:54
  • Yes sure. I am doing this in a while. – mallaudin Apr 26 '18 at 06:55
  • @AnuragSingh I have added a link in the question. Please check. – mallaudin Apr 26 '18 at 07:16
  • check image size first. – Atif AbbAsi Apr 26 '18 at 09:38

3 Answers3

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.

breakline
  • 5,006
  • 5
  • 35
  • 70
  • Yes. I am thinking about it as I have already tried everything. It works with view pager but animation is not smooth. – mallaudin Apr 26 '18 at 07:49
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.

Muhammad Hassaan
  • 769
  • 4
  • 17
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 :)

Qamar
  • 3,993
  • 23
  • 42