Giter VIP home page Giter VIP logo

gravitysnaphelper's Introduction

GravitySnapHelper

A SnapHelper that snaps a RecyclerView to an edge.

Setup

Add this to your build.gradle:

implementation 'com.github.rubensousa:gravitysnaphelper:2.2.2'

How to use

You can either create a GravitySnapHelper, or use GravitySnapRecyclerView.

If you want to use GravitySnapHelper directly, you just need to create it and attach it to your RecyclerView:

val snapHelper = GravitySnapHelper(Gravity.START)
snapHelper.attachToRecyclerView(recyclerView)

If you want to use GravitySnapRecyclerView, you can use the following xml attributes for customisation:

<attr name="snapGravity" format="enum">
<attr name="snapEnabled" format="boolean" />
<attr name="snapLastItem" format="boolean" />
<attr name="snapToPadding" format="boolean" />
<attr name="snapScrollMsPerInch" format="float" />
<attr name="snapMaxFlingSizeFraction" format="float" />

Example:

<com.github.rubensousa.gravitysnaphelper.GravitySnapRecyclerView
    android:id="@+id/recyclerView"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:snapGravity="start" />

Start snapping

val snapHelper = GravitySnapHelper(Gravity.START)
snapHelper.attachToRecyclerView(recyclerView)

Center snapping

val snapHelper = GravitySnapHelper(Gravity.CENTER)
snapHelper.attachToRecyclerView(recyclerView)

Limiting fling distance

If you use setMaxFlingSizeFraction or setMaxFlingDistance you can change the maximum fling distance allowed.

With decoration

Features

  1. setMaxFlingDistance or setMaxFlingSizeFraction - changes the max fling distance allowed.
  2. setScrollMsPerInch - changes the scroll speed.
  3. setGravity - changes the gravity of the SnapHelper.
  4. setSnapToPadding - enables snapping to padding (default is false)
  5. smoothScrollToPosition and scrollToPosition
  6. RTL support out of the box

Nested RecyclerViews

Take a look at these blog posts if you're using nested RecyclerViews

  1. Improving scrolling behavior of nested RecyclerViews

  2. Saving scroll state of nested RecyclerViews

License

Copyright 2018 The Android Open Source Project
Copyright 2019 Rúben Sousa

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

gravitysnaphelper's People

Contributors

jt-gilkeson avatar rubensousa avatar supercilex avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

gravitysnaphelper's Issues

CoordinatorLayout does not scroll on list fling

I have a ViewPager having RecyclerView in each page.
ViewPager has layout behavior set to appbar_scrolling_view_behavior

when swiping list up, after finger is off the screen, fling starts, coordinator layout does not scroll, just the list moves up, appbar stays where the finger was left

Scrolls to far

So i started testing out this GravitySnapHelper and i noticed a very subtle issue that arises after continually testing. So its difficult to reproduce every single time but i have tested it enough to reproduce it several times.

If you are scrolling through the RecyclerView with a swipe gesture, your finger remains on the screen and you let go while the second half of an item ( lets say item number 5) in the adapter shows then it slides to the left so then item number 6 is the furthest left item to show.

Now if you are scrolling through the RecyclerView with a swipe gesture, your finger remains on the screen and you let go while the first half of an item ( lets say item number 5) in the adapter shows then it slides to the left so then item number 5 is the furthest left item to show.

Once in awhile, if you are scrolling through the RecyclerView with a swipe gesture, your finger remains on the screen and you let go while the first half of an item ( lets say item number 5) in the adapter shows then it slides to the left so then item number 4 is the furthest left item to show. So in this case it slides too far.

Create a library?

Thanks for your great work! Could you please create a library and host it on somewhere like bintray?

Scroll like viewpager

First of all, absolutely like this! It was really easy to use, and the results achieved is amazing.

I have a question, and not sure how do I go about if I implement this with my RecyclerView. Basically, my RecyclerView is showing 4 rows per screen. Using RecyclerViewSnap, how do I go about scrolling my RecyclerView like a ViewPager? I like how RecyclerViewSnap already does help me present only 4 rows per screen, but I was hoping to achieve this:

  1. User enters app, sees position 0 - 4 of the recycler view row.
  2. No matter how hard the user swipe / scroll, it will paginate to the next 4 position. Say if user were to scroll down, from the first screen (row 0-4), they will see position row 5-9. And if they scroll/swipe down again, they will see row 10-13. And if they swipe up from row 10-13, they will see row 5-9.

Thank you!

Bad scrolling horizontally and vertically

Hi @rubensousa, thank you for great library. I have scrolling problem when using this a library. I have a ViewPager and I have horizontal orientation RecyclerView inside secondary fragment page. All items of this RecyclerView is a vertical orientation RecyclerView.
So, you can visualize structure like that: vertical orientation RecyclerView is item of horizontal orientation RecyclerView is item of ViewPager. (RecyclerView->RecyclerView->ViewPager)

When you scrolling horizontally works not a stable and smoothly, works hardly and not works any time.
When you scrolling vertically of vertical orientation RecyclerView not fully end, RecyclerView will be automatic scroll to head of the list. If you will scroll until end of list then stopped auto scrolling above.

For understanding my problem i created sample project, please look it:

Sample project -> ProbaSnapRV.zip

Video:
ScreenReq

Please, help me solve horizontally and vertically scrolling problems, i want they works smoothly

OnClickListener for Each Item

I am trying to put onclick listener for each item in each snap,so for the first position in the spanscenter has different function than that in endsnap and startsnap,I succeeded in adding click listener for each item (code below),but am having same action for item position 1(for example) in the Four snaps


    public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {

        public ImageView imageView;
        public TextView nameTextView;
        public TextView ratingTextView;

        public ViewHolder(View itemView) {
            super(itemView);
            itemView.setOnClickListener(this);
            imageView = (ImageView) itemView.findViewById(R.id.imageView);
            nameTextView = (TextView) itemView.findViewById(R.id.nameTextView);
            ratingTextView = (TextView) itemView.findViewById(R.id.ratingTextView);
        }

        @Override
        public void onClick(View v) {
            Log.d("App", mApps.get(getAdapterPosition()).getName());
            if (getAdapterPosition()==0){
                Toast.makeText(itemView.getContext(), "Position: " + Integer.toString(getAdapterPosition()), Toast.LENGTH_LONG).show();


            }
        }
    }

GridLayoutManager.SpanSizeLookup is not considered

When we use GridLayoutManager not either element takes 1 cell. That's why logic
if (layoutManager instanceof GridLayoutManager) { offset += ((GridLayoutManager) layoutManager).getSpanCount() - 1; }
is not correct. We need to consider results of spanSizeLookup.getSpanSize

How to customize scroll behavior ?

 SnapHelper snapHelper = new GravitySnapHelper(Gravity.TOP);
  snapHelper.attachToRecyclerView(mRecyclerView);

For example I need to show next element if it is visible more than 50%. Or hide first element if it's hidden more than 50%.
Because current behavior is :
if we scroll down and first item is hidden by 80%, then SnapHelper scrolls up the list and first element is visible again.
Expected behavior :
if we scroll down and first item is hidden by 80%, then SnapHelper should scroll down to hide first item.

SnapListener broken if enough padding is added to end of items to snap to last item

Use Case: I want a Gravity.Start list where I can have the last item snapped to the first position (all the way at the start). The reason for this is that I want to highlight / show something related to the item currently snapped and I want to be able to do this for all items.

To accomplish this, you can add enough padding to the end of the recyclerview that you can scroll the last item all the way to the start of the view. The RecyclerViewSnap functions perfectly - it correctly can snap to all the items including the Last item - no problem. However, the SnapListener does not fire ever in this scenario. No matter where you are in the list (first item, middle of the list, last item), the code in GravityDelegate for onScrollStateChanged where it calls getSnappedPosition(recyclerView) returns RecyclerView.NO_POSITION even though the snap is working completely correctly and the item is completely visible.

Example: Make an item that is 150dp wide, set up your recyclerview like follows:

<android.support.v7.widget.RecyclerView
    android:id="@+id/myRecyclerview"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:paddingStart="12dp"
    android:paddingEnd="300dp"
    android:clipChildren="false"
    android:clipToPadding="false"/>

Snapping works correctly for all items, SnapListener never fires for any item.

Change the paddingEnd to be 200, you'll be able to snap to the 2nd to last item (further than the default with no padding - which is the 3rd to last item), and the SnapListener works correctly, however you can't snap to the last item.

In summary with enough padding added, the code to execute the snap appears to work 100% correctly, but the code to report the item snapped to seems to break.

Jumps to the end when more items are appended

I have a continuously loading paginated horizontal list. Loading new page is triggered on bottom scroll when there are less than 10 items to the end of the adapter list. The moment when a new page is loaded the snap jumps directly to the end. Maybe you tested only cases where adapter size does not change on the fly.

Unauthorized HttpErrorStatusCodeException

org.gradle.internal.resource.transport.http.HttpErrorStatusCodeException: Could not HEAD 'https://jitpack.io/com/github/rubensousa/gravitysnaphelper/1.5/gravitysnaphelper-1.5.pom'. Received status code 401 from server: Unauthorized at org.gradle.internal.resource.transport.http.HttpClientHelper.processResponse(HttpClientHelper.java:158) at org.gradle.internal.resource.transport.http.HttpClientHelper.performHead(HttpClientHelper.java:76) at org.gradle.internal.resource.transport.http.HttpResourceAccessor.getMetaData(HttpResourceAccessor.java:65) at org.gradle.internal.resource.transfer.DefaultExternalResourceConnector.getMetaData(DefaultExternalResourceConnector.java:63) at org.gradle.internal.resource.transfer.AccessorBackedExternalResource.getMetaData(AccessorBackedExternalResource.java:201) at org.gradle.internal.resource.BuildOperationFiringExternalResourceDecorator$1.call(BuildOperationFiringExternalResourceDecorator.java:61) at org.gradle.internal.resource.BuildOperationFiringExternalResourceDecorator$1.call(BuildOperationFiringExternalResourceDecorator.java:58) at org.gradle.internal.progress.DefaultBuildOperationExecutor$CallableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:350) at org.gradle.internal.progress.DefaultBuildOperationExecutor$CallableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:340) at org.gradle.internal.progress.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:199) at org.gradle.internal.progress.DefaultBuildOperationExecutor.call(DefaultBuildOperationExecutor.java:120) at org.gradle.internal.resource.BuildOperationFiringExternalResourceDecorator.getMetaData(BuildOperationFiringExternalResourceDecorator.java:58) at org.gradle.internal.resource.transfer.DefaultCacheAwareExternalResourceAccessor$1.create(DefaultCacheAwareExternalResourceAccessor.java:102) at org.gradle.internal.resource.transfer.DefaultCacheAwareExternalResourceAccessor$1.create(DefaultCacheAwareExternalResourceAccessor.java:82) at org.gradle.cache.internal.ProducerGuard$AdaptiveProducerGuard.guardByKey(ProducerGuard.java:97) at org.gradle.internal.resource.transfer.DefaultCacheAwareExternalResourceAccessor.getResource(DefaultCacheAwareExternalResourceAccessor.java:82) at org.gradle.api.internal.artifacts.repositories.resolver.DefaultExternalResourceArtifactResolver.downloadByCoords(DefaultExternalResourceArtifactResolver.java:129) at org.gradle.api.internal.artifacts.repositories.resolver.DefaultExternalResourceArtifactResolver.downloadStaticResource(DefaultExternalResourceArtifactResolver.java:95) at org.gradle.api.internal.artifacts.repositories.resolver.DefaultExternalResourceArtifactResolver.resolveArtifact(DefaultExternalResourceArtifactResolver.java:65) at org.gradle.api.internal.artifacts.repositories.resolver.ExternalResourceResolver.parseMetaDataFromArtifact(ExternalResourceResolver.java:216) at org.gradle.api.internal.artifacts.repositories.resolver.MavenResolver.parseMetaDataFromArtifact(MavenResolver.java:170) at org.gradle.api.internal.artifacts.repositories.resolver.MavenResolver.parseMetaDataFromArtifact(MavenResolver.java:65) at org.gradle.api.internal.artifacts.repositories.resolver.ExternalResourceResolver.resolveStaticDependency(ExternalResourceResolver.java:193) at org.gradle.api.internal.artifacts.repositories.resolver.MavenResolver.doResolveComponentMetaData(MavenResolver.java:145) at org.gradle.api.internal.artifacts.repositories.resolver.ExternalResourceResolver$RemoteRepositoryAccess.resolveComponentMetaData(ExternalResourceResolver.java:467) at org.gradle.api.internal.artifacts.ivyservice.ivyresolve.CachingModuleComponentRepository$ResolveAndCacheRepositoryAccess.resolveComponentMetaData(CachingModuleComponentRepository.java:363) at org.gradle.api.internal.artifacts.ivyservice.ivyresolve.BaseModuleComponentRepositoryAccess.resolveComponentMetaData(BaseModuleComponentRepositoryAccess.java:50) at org.gradle.api.internal.artifacts.ivyservice.ivyresolve.memcache.InMemoryCachedModuleComponentRepository$CachedAccess.resolveComponentMetaData(InMemoryCachedModuleComponentRepository.java:95) at org.gradle.api.internal.artifacts.ivyservice.ivyresolve.ErrorHandlingModuleComponentRepository$ErrorHandlingModuleComponentRepositoryAccess.resolveComponentMetaData(ErrorHandlingModuleComponentRepository.java:126) at org.gradle.api.internal.artifacts.ivyservice.ivyresolve.ComponentMetaDataResolveState.process(ComponentMetaDataResolveState.java:66) at org.gradle.api.internal.artifacts.ivyservice.ivyresolve.ComponentMetaDataResolveState.resolve(ComponentMetaDataResolveState.java:58) at org.gradle.api.internal.artifacts.ivyservice.ivyresolve.RepositoryChainComponentMetaDataResolver.findBestMatch(RepositoryChainComponentMetaDataResolver.java:138) at org.gradle.api.internal.artifacts.ivyservice.ivyresolve.RepositoryChainComponentMetaDataResolver.findBestMatch(RepositoryChainComponentMetaDataResolver.java:119) at org.gradle.api.internal.artifacts.ivyservice.ivyresolve.RepositoryChainComponentMetaDataResolver.resolveModule(RepositoryChainComponentMetaDataResolver.java:92) at org.gradle.api.internal.artifacts.ivyservice.ivyresolve.RepositoryChainComponentMetaDataResolver.resolve(RepositoryChainComponentMetaDataResolver.java:63) at org.gradle.api.internal.artifacts.query.DefaultArtifactResolutionQuery.buildComponentResult(DefaultArtifactResolutionQuery.java:147) at org.gradle.api.internal.artifacts.query.DefaultArtifactResolutionQuery.access$100(DefaultArtifactResolutionQuery.java:64) at org.gradle.api.internal.artifacts.query.DefaultArtifactResolutionQuery$1.create(DefaultArtifactResolutionQuery.java:123) at org.gradle.api.internal.artifacts.query.DefaultArtifactResolutionQuery$1.create(DefaultArtifactResolutionQuery.java:116) at org.gradle.cache.internal.DefaultCacheAccess.useCache(DefaultCacheAccess.java:222) at org.gradle.cache.internal.DefaultPersistentDirectoryStore.useCache(DefaultPersistentDirectoryStore.java:152) at org.gradle.cache.internal.DefaultCacheFactory$ReferenceTrackingCache.useCache(DefaultCacheFactory.java:190) at org.gradle.api.internal.artifacts.ivyservice.DefaultCacheLockingManager.useCache(DefaultCacheLockingManager.java:62) at org.gradle.api.internal.artifacts.query.DefaultArtifactResolutionQuery.execute(DefaultArtifactResolutionQuery.java:116)

Find out which item was snapped?

I'm trying to do a snappy recycler view and your code works perfectly for that. However, I'm trying to figure out how to get the index of the item that was snapped. I proxied the findTargetSnapPosition method, but it tends to return -1 quite often.

Any idea how to fetch the position, preferably by listening to the snap helper?

GravitySnapHelper dont return the first position when the user scroll at (0,0) position

I have the next problem, I have this view, the problem is when the user scroll at first element, when the "top" of the view is reached (0,0) the GravitySnapHelper.SnapListener dont return the position, this only happens if the view is scrolled at "(0,0) ", but if i scroll at "(0, .1)" for example(only a little bit of scroll in y position) , it wokrs fine. . The callback is not fired, when the view is in their original state

Here is the layout:

  private fun setProductsAdapter() {
        val layoutManager = LinearLayoutManager(activity)
        layoutManager.isItemPrefetchEnabled = false
        recyclerViewGallery.layoutManager = layoutManager
        recyclerViewGallery.setHasFixedSize(true)

        productImageAdapter = ProductImageAdapter(product)
        recyclerViewGallery.adapter = productImageAdapter

        GravitySnapHelper(Gravity.TOP, false,
            GravitySnapHelper.SnapListener { position ->

                drawGalleryIndicator(position)
              
            }).attachToRecyclerView(recyclerViewGallery)

        drawGalleryIndicator(0)
    }
<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:clickable="true"
    android:foreground="?attr/selectableItemBackground"
    android:orientation="vertical">

    <ImageView xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:id="@+id/iv_product"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:adjustViewBounds="true"
        android:scaleType="centerCrop"
        app:srcCompat="@drawable/ic_perro_logo_w_letters">

    </ImageView>
</androidx.cardview.widget.CardView>

How to choose if it should create the views around?

Upon using the sample, I noticed it calls onCreateViewHolder and onBindViewHolder just once.

On a normal ViewPager (and RecyclerView), it always loads those around, so those functions are called for the page on the left and on the right, too.

Is it possible to do it here too?
Maybe do it for current page, and soon after, to those around?
I ask this so that in case the pages are heavy, it will be smooth to load them, so the user won't notice we load more views.

GravitySnapHelper ignores RecyclerView padding in 2.0

In version 1.5 GravitySnapHelper respected paddings of RecyclerView, which it was attached to. For example, using helper Gravity.START to recycler with paddingLeft > 0 was correctly handled, i.e. this padding remained while snapping to next elements.
But in 2.0 this padding is ignored while snapping and this leads to layout break.

Example of used RecyclerView:

GravitySnapHelper(Gravity.START).attachToRecyclerView(recyclerView)

<androidx.recyclerview.widget.RecyclerView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/recyclerView"
    android:layout_width="match_parent"
    android:layout_height="100dp"
    android:layout_marginLeft="0dp"
    android:layout_marginRight="0dp"
    android:clipToPadding="false"
    android:nestedScrollingEnabled="false"
    android:paddingLeft="5dp"
    android:paddingRight="5dp" />

Layout of item used seems to be insignificant for this.

java.lang.IllegalStateException: An instance of OnFlingListener already set.

java.lang.IllegalStateException: An instance of OnFlingListener already set.
at android.support.v7.widget.SnapHelper.setupCallbacks(SnapHelper.java:115)
at android.support.v7.widget.SnapHelper.attachToRecyclerView(SnapHelper.java:103)
at com.github.rubensousa.recyclerviewsnap.SnapAdapter.onBindViewHolder(SnapAdapter.java:92)
at com.github.rubensousa.recyclerviewsnap.SnapAdapter.onBindViewHolder(SnapAdapter.java:20)
at android.support.v7.widget.RecyclerView$Adapter.onBindViewHolder(RecyclerView.java:6508)
at android.support.v7.widget.RecyclerView$Adapter.bindViewHolder(RecyclerView.java:6541)
at android.support.v7.widget.RecyclerView$Recycler.tryBindViewHolderByDeadline(RecyclerView.java:5484)
at android.support.v7.widget.RecyclerView$Recycler.tryGetViewHolderForPositionByDeadline(RecyclerView.java:5750)
at android.support.v7.widget.GapWorker.prefetchPositionWithDeadline(GapWorker.java:285)
at android.support.v7.widget.GapWorker.flushTaskWithDeadline(GapWorker.java:342)
at android.support.v7.widget.GapWorker.flushTasksWithDeadline(GapWorker.java:358)
at android.support.v7.widget.GapWorker.prefetch(GapWorker.java:365)
at android.support.v7.widget.GapWorker.run(GapWorker.java:396)
at android.os.Handler.handleCallback(Handler.java:815)
at android.os.Handler.dispatchMessage(Handler.java:104)
at android.os.Looper.loop(Looper.java:194)
at android.app.ActivityThread.main(ActivityThread.java:5868)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1019)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:814)

Snapping is broken in horizontal RecyclerViews when in RTL

Hey,
Thanks for sharing this example! I was playing around with the GravitySnapHelper and noticed an issue in RTL, which would cause the carousel to scroll back to the first item, regardless of how far along it was in the list of items.

After investigating a bit, I realized that this is because the support library's OrientationHelper always assumes that start is left and end is right (which doesn't hold true when in RTL). Ideally, this would be fixed in a support library update, but I've created a gist of my modifications to GravitySnapHelper if anyone else runs across this issue and would like to fix it temporarily. I haven't tested it too much with Gravity.END so please let me know if you notice any issues in my calculation there.

EDIT: Submitted to the AOSP bug tracker.

padding / clipToPadding="false" does not work

When I apply

android:padding="8dp"
android:clipToPadding="false"

to my RecyclerView, the list element does not "snap" but jumps between position with padding and without padding. Any ideas how to fix that? Thanks!

Reduce minSdkVersion?

Thanks for the great library - it works perfectly!

Just one issue - at the moment I'm having to override its minSdkVersion (by using <uses-sdk tools:overrideLibrary="com.github.rubensousa.gravitysnaphelper"/> in a manifest file).

As the RecyclerViewSnap library is intended solely to augment the functionality of the RecyclerView v7 support library, could you reduce minSdkVersion to the same as the v7 libraries (e.g., 9), rather then the current version 15?

Dynamic Gravity

@rubensousa is it possible to have a dynamic gravity?
My intention is make to make the first item with Gravity.LEFT, the last with Gravity.RIGHT and all the others with Gravity.CENTER.

LinearSnapHelper and scrollToPosition

Hi there,
I'm using "LinearSnapHelper" for center snapping and when using "scrollToPosition" the RecyclerView's layout is not centering as if i were scrolling manually.
Tried "smoothScrollToPosition" as i found on Stack OverFlow but then i'm getting a blank RecyclerView.
Any solution?
Thanks!

SCROLL_STATE_IDLE is never called in case of scrolling up

In case of swiping up when we are focused on first element, SCROLL_STATE_IDLE is never called.
The same issue occurs when we are focused on second or third element and we swipe up really fast.
This problem does not occur in case of using LinearSnapHelper

Auto left scrolling

I'm using the SnapHelper inside a recyclerView, but I found out that after scrolling the list for a bit (thus recycling its views) the RecyclerView automatically scrolls to the start of the list after any scroll motion, I mean, I scroll for instance, to the middle of the list. it suddenly goes to the first item, without any user interaction.

My code:

@Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
SnapHelper snapHelper = new GravitySnapHelper(Gravity.BOTTOM);
            productsRecyclerView.setOnFlingListener(null);
            snapHelper.attachToRecyclerView(productsRecyclerView);
}

An image demonstrating the issue: (sorry for the hogging, my mac sucks)
Imgur

Any thoughts on that ?

java.lang.IllegalStateException: An instance of OnFlingListener already set.

Here is my code:

SnapHelper snapHelper = new GravitySnapHelper(Gravity.START);
snapHelper.attachToRecyclerView(mRecyclerView);

but sometimes the issue occurs:

FATAL EXCEPTION: main
                                                                        Process: by.gramoplayer.android, PID: 12195
                                                                        java.lang.IllegalStateException: An instance of OnFlingListener already set.
                                                                            at android.support.v7.widget.SnapHelper.setupCallbacks(SnapHelper.java:114)
                                                                            at android.support.v7.widget.SnapHelper.attachToRecyclerView(SnapHelper.java:102)
                                                                            at com.github.rubensousa.gravitysnaphelper.GravitySnapHelper.attachToRecyclerView(GravitySnapHelper.java:47)

How to get Context

On /app/src/main/java/com/github/rubensousa/recyclerviewsnap/Adapter.java
how to get Application Context?
eg. I want to set a click to start new Intent or Make a Toast

Snap center can't see the last item completely

If you change the CardView's "layout_width" to 152dp which is in the adapter.xml,
then for the type which is "Snap center" in the demo app can't see the first and last item completely.

<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="152dp"
    android:layout_height="wrap_content"
    android:layout_margin="4dp"
    android:clickable="true"
    android:foreground="?attr/selectableItemBackground"
    android:orientation="vertical">

image

RecyclerView Auto Scrolling with GravitySnapHelper

I use RTL horizontal recyclerview with LinearLayoutManager and set GravitySnapHelper(Gravity.END) to it. But after apply a little scroll to left, the recyclerview scrolls to left automatically without any user touches.
I attached a gif following to show the problem:
2017_12_08_14_58_08

scrolling two lines

Two lines of one scrolling,how to do,please give me some suggest,thank you!

Center Snap with support to snap to edge items

GravirySnapHelper is awesome comparing to default LinearSnapHelper. But It would be perfect if it is support also Gravity.CENTER and simultaneously snap to first and last item if scrolled to one of the edges.
Regretfully LinearSnapHelper (though snap to center) can't snap to side items as your GravirySnapHelper does. So in order your GravirySnapHelper become far more superior you should add Gravity.CENTER. Thanks. Also I found that if I set snapToLastItem(true) it does not snap, though it snap to edge items by default.

Disable flinging

Hi, nice effect but being able to fling which turns into linear scroll really ruins it, id like to mimic view pager physics, exactly how google play does it

thanks

Scrolling issue with snap center

This is only an issue with the snap-center functionality.
When i slide horizontally in the RecyclerView i cant slide vertically afterwards in the wrapping RecyclerView - it is like the horizontal RecyclerView steals the focus without clearing it afterwards. Please see this video:
http://i.imgur.com/5NwrR5s.gifv

a GravityPagerSnapHelper snap bug in version 1.5

I am still using version 1.5 because my project does not surpport androidx. I need to use GravityPagerSnapHelper and listening page selected,like this:
new GravityPagerSnapHelper(Gravity.START, true, new GravitySnapHelper.SnapListener() { @Override public void onSnap(int position) { Toast.makeText(holder.recyclerView.getContext(),"Snapped: "+ position,Toast.LENGTH_SHORT).show(); } }).attachToRecyclerView(holder.recyclerView);
it works well before last one. When I slide to the last one, it always automatically returns to the previous one. Is there any way to solve this problem?

at RecyclerView nested(嵌套) RecyclerView,an interesting problem....

I have a problem, at RecyclerView nested(嵌套) RecyclerView, It creates an interesting problem, It's been rocking there.
can you help me,thank you very much.
this is the video connection:
https://res.cloudinary.com/liuyuesha/video/upload/v1540888109/test_snap_b2aa9s.mp4

Part of the code:
@OverRide
public void onBindViewHolder(@nonnull RecyclerView.ViewHolder holder, final int position) {

    if (holder instanceof RecommendSongsHolder) {
     
        FindBean.ModulesBean modulesBean = mFindDataList.get(position);
        List<FindRecommendSongInfo> program_list = modulesBean.getData().getTrack_list();

        LinearLayoutManager manager = new LinearLayoutManager(mContext, LinearLayoutManager.HORIZONTAL, false);
        ((RecommendSongsHolder) holder).recyclerView.setLayoutManager(manager);
        ((RecommendSongsHolder) holder).recyclerView.setHasFixedSize(true);
        ((RecommendSongsHolder) holder).recyclerView.setNestedScrollingEnabled(false);
        RecommendSongsChildAdapter songsChildAdapter = new RecommendSongsChildAdapter(mContext, mActivity, program_list, mDeviceDialog);
        ((RecommendSongsHolder) holder).recyclerView.setAdapter(songsChildAdapter);

        ((RecommendSongsHolder) holder).recyclerView.setOnFlingListener(null);
        SnapHelper snapHelper = new GravitySnapHelper(Gravity.START);
        snapHelper.attachToRecyclerView(((RecommendSongsHolder) holder).recyclerView);

    }

Snap to a custom position

Hi,

First of all, thank you for your work and appreciate it. This is more like a requirement than an issue.
screenshot_20170804-135308

So I have this requirement to snap the horizontal recyclerView to the left edge of the screen (exactly like latest play store update for movies) during the first scroll event. Does the library support this kind of requirement ? or do you have any bright work around's?

java.lang.IllegalStateException: An instance of OnFlingListener already set.

Adding Snaps dynamicaly and notifyDataSetChanged gives this above error what i'm doing so far is

 //add three more items
            progressBar.setVisibility(View.VISIBLE);
            new Handler().postDelayed(new Runnable() {
                @Override
                public void run() {

                    List<App> apps = getApps();
                    snapAdapter.addSnap(new Snap(Gravity.CENTER_HORIZONTAL, "Paper Industry", apps));
                    snapAdapter.addSnap(new Snap(Gravity.CENTER_HORIZONTAL, "Wood Industry", apps));
                    snapAdapter.addSnap(new Snap(Gravity.CENTER_HORIZONTAL, "Cement Industry", apps));
                    snapAdapter.notifyDataSetChanged();
                    progressBar.setVisibility(View.GONE);
                }
            },3000);

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.