An Android Animation library which easily add itemanimator to RecyclerView items.

Overview

RecyclerView Animators

Android Arsenal License Maven Central

RecyclerView Animators is an Android library that allows developers to easily create RecyclerView with animations.

Please feel free to use this.

Features

Demo

ItemAnimator

Adapters

How do I use it?

Setup

Gradle

On your module's build.gradle file add this implementation statement to the dependencies section:

dependencies {
  // Kotlin
  implementation 'jp.wasabeef:recyclerview-animators:4.0.2'
}

Also make sure that the repositories section includes not only "mavenCentral()" but also a maven section with the "google()" endpoint.

repositories {
  google()
  mavenCentral()
  jcenter()
}

ItemAnimator

Step 1

Set RecyclerView ItemAnimator.

val recyclerView = findViewById<RecyclerView>(R.id.list)
recyclerView.itemAnimator = SlideInLeftAnimator()
val recyclerView = findViewById<RecyclerView>(R.id.list)
recyclerView.itemAnimator = SlideInUpAnimator(OvershootInterpolator(1f))

Step 2

Please use the following
notifyItemChanged(int)
notifyItemInserted(int)
notifyItemRemoved(int)
notifyItemRangeChanged(int, int)
notifyItemRangeInserted(int, int)
notifyItemRangeRemoved(int, int)

If you want your animations to work, do not rely on calling notifyDataSetChanged(); as it is the RecyclerView's default behavior, animations are not triggered to start inside this method.

fun remove(position: Int) {
  dataSet.removeAt(position)
  notifyItemRemoved(position)
}

fun add(text: String, position: Int) {
  dataSet.add(position, text)
  notifyItemInserted(position)
}

Advanced Step 3

You can change the durations.

recyclerView.itemAnimator?.apply {
  addDuration = 1000
  removeDuration = 100
  moveDuration = 1000
  changeDuration = 100
}

Advanced Step 4

Change the interpolator.

recyclerView.itemAnimator = SlideInLeftAnimator().apply {
  setInterpolator(OvershootInterpolator())
}

Advanced Step 5

By implementing AnimateViewHolder, you can override preset animation. So, custom animation can be set depending on view holder.

class MyViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView), AnimateViewHolder {

  override fun preAnimateRemoveImpl(holder: RecyclerView.ViewHolder) {
    // do something
  }

  override fun animateRemoveImpl(holder: RecyclerView.ViewHolder, listener: ViewPropertyAnimatorListener) {
    itemView.animate().apply {
      translationY(-itemView.height * 0.3f)
      alpha(0f)
      duration = 300
      setListener(listener)
    }.start()
  }

  override fun preAnimateAddImpl(holder: RecyclerView.ViewHolder) {
    itemView.setTranslationY(-itemView.height * 0.3f)
    itemView.setAlpha(0f)
  }

  override fun animateAddImpl(holder: RecyclerView.ViewHolder, listener: ViewPropertyAnimatorListener) {
    itemView.animate().apply {
      translationY(0f)
      alpha(1f)
      duration = 300
      setListener(listener)
    }.start()
  }
}

Animators

Cool

LandingAnimator

Scale

ScaleInAnimator, ScaleInTopAnimator, ScaleInBottomAnimator
ScaleInLeftAnimator, ScaleInRightAnimator

Fade

FadeInAnimator, FadeInDownAnimator, FadeInUpAnimator
FadeInLeftAnimator, FadeInRightAnimator

Flip

FlipInTopXAnimator, FlipInBottomXAnimator
FlipInLeftYAnimator, FlipInRightYAnimator

Slide

SlideInLeftAnimator, SlideInRightAnimator, OvershootInLeftAnimator, OvershootInRightAnimator
SlideInUpAnimator, SlideInDownAnimator

RecyclerView.Adapter

Step 1

Set RecyclerView ItemAnimator.

val recyclerView = findViewById<RecyclerView>(R.id.list)
recyclerView.adapter = AlphaInAnimationAdapter(MyAdapter())

Java

RecyclerView recyclerView = findViewById(R.id.list);
recyclerView.setAdapter(new AlphaInAnimationAdapter(MyAdapter());

Advanced Step 2

recyclerView.adapter = AlphaInAnimationAdapter(MyAdapter()).apply {
  // Change the durations.
  setDuration(1000)
  // Change the interpolator.
  setInterpolator(vershootInterpolator())
  // Disable the first scroll mode.
  setFirstOnly(false)
}

Java

AlphaInAnimationAdapter alphaInAnimationAdapter = new AlphaInAnimationAdapter(new MyAdapter());
alphaInAnimationAdapter.setDuration(1000);
alphaInAnimationAdapter.setInterpolator(new OvershootInterpolator());
alphaInAnimationAdapter.setFirstOnly(false);

Advanced Step 3

Multiple Animations

val alphaAdapter = AlphaInAnimationAdapter(MyAdapter())
recyclerView.adapter = ScaleInAnimationAdapter(alphaAdapter)

Java

recyclerView.setAdapter(new ScaleInAnimationAdapter(alphaInAnimationAdapter));

Adapters

Alpha

AlphaInAnimationAdapter

Scale

ScaleInAnimationAdapter

Slide

SlideInBottomAnimationAdapter
SlideInRightAnimationAdapter, SlideInLeftAnimationAdapter

Applications using RecyclerView Animators

Please ping me or send a pull request if you would like to be added here.

Icon Application
Ameba Ownd
QuitNow!
AbemaTV
CL

Developed By

Daichi Furiya (Wasabeef) - [email protected]

Follow me on Twitter

Contributions

Any contributions are welcome!

Contributers

Thanks

  • Inspired by AndroidViewAnimations in daimajia.

License

Copyright 2020 Daichi Furiya / Wasabeef

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.
Comments
  • Notify changes on an item

    Notify changes on an item

    Hi, nice library! The animation on insert, delete and show item work very well but when I call "notifyItemChanged" or "notifyDatasetChanged" on the adapter, nothing happens.

    opened by folivares 20
  • java.lang.IllegalArgumentException: Called attach on a child which is not detached: ViewHolder{40e612c0 position=2 id=-1, oldPos=-1, pLpos:-1 no parent}

    java.lang.IllegalArgumentException: Called attach on a child which is not detached: ViewHolder{40e612c0 position=2 id=-1, oldPos=-1, pLpos:-1 no parent}

    crash on android 4.0.4

    after adding item and calling notifyItemMoved.
    flinging recyclerview crashes app.

    java.lang.IllegalArgumentException: Called attach on a child which is not detached: ViewHolder{40e612c0 position=2 id=-1, oldPos=-1, pLpos:-1 no parent} at android.support.v7.widget.RecyclerView$4.attachViewToParent(RecyclerView.java:377) at android.support.v7.widget.ChildHelper.attachViewToParent(ChildHelper.java:208) at android.support.v7.widget.RecyclerView$LayoutManager.addViewInt(RecyclerView.java:4936) at android.support.v7.widget.RecyclerView$LayoutManager.addView(RecyclerView.java:4913) at android.support.v7.widget.RecyclerView$LayoutManager.addView(RecyclerView.java:4901) at android.support.v7.widget.StaggeredGridLayoutManager.fill(StaggeredGridLayoutManager.java:1340) at android.support.v7.widget.StaggeredGridLayoutManager.onLayoutChildren(StaggeredGridLayoutManager.java:584) at android.support.v7.widget.RecyclerView.dispatchLayout(RecyclerView.java:1988) at android.support.v7.widget.RecyclerView.onLayout(RecyclerView.java:2237) at android.view.View.layout(View.java:11425) at android.view.ViewGroup.layout(ViewGroup.java:4232) at android.widget.RelativeLayout.onLayout(RelativeLayout.java:925) at android.view.View.layout(View.java:11425) at android.view.ViewGroup.layout(ViewGroup.java:4232) at android.widget.FrameLayout.onLayout(FrameLayout.java:431) at android.view.View.layout(View.java:11425) at android.view.ViewGroup.layout(ViewGroup.java:4232) at android.widget.FrameLayout.onLayout(FrameLayout.java:431) at android.view.View.layout(View.java:11425) at android.view.ViewGroup.layout(ViewGroup.java:4232) at android.widget.FrameLayout.onLayout(FrameLayout.java:431) at android.view.View.layout(View.java:11425) at android.view.ViewGroup.layout(ViewGroup.java:4232) at android.support.v4.widget.DrawerLayout.onLayout(DrawerLayout.java:890) at android.view.View.layout(View.java:11425) at android.view.ViewGroup.layout(ViewGroup.java:4232) at android.widget.FrameLayout.onLayout(FrameLayout.java:431) at android.view.View.layout(View.java:11425) at android.view.ViewGroup.layout(ViewGroup.java:4232) at android.widget.FrameLayout.onLayout(FrameLayout.java:431) at android.view.View.layout(View.java:11425) at android.view.ViewGroup.layout(ViewGroup.java:4232) at android.widget.FrameLayout.onLayout(FrameLayout.java:431) at android.view.View.layout(View.java:11425) at android.view.ViewGroup.layout(ViewGroup.java:4232) at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1628) at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1486) at android.widget.LinearLayout.onLayout(LinearLayout.java:1399) at android.view.View.layout(View.java:11425) at android.view.ViewGroup.layout(ViewGroup.java:4232) at android.widget.FrameLayout.onLayout(FrameLayout.java:431) at android.view.View.layout(View.java:11425) at android.view.ViewGroup.layout(ViewGroup.java:4232) at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1509) at android.view.ViewRootImpl.handleMessage(ViewRootImpl.java:2498) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loop(Looper.java:154) at android.app.ActivityThread.main(ActivityThread.java:4944) at java.lang.reflect.Method.invokeNative(Method.java) at java.lang.reflect.Method.invoke(Method.java:511) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551) at dalvik.system.NativeStart.main(NativeStart.java)

    opened by mshearer123 8
  • Fixing #64 issue that we faced in special case

    Fixing #64 issue that we faced in special case

    We faced IndexOutOfBoundException because we remove animator at the end of the animation. This small change checks size before removing.

    Please review and comment!

    opened by emartynov 7
  • BREAKING CHANGES in revision 23.1.0 of Android Support Library

    BREAKING CHANGES in revision 23.1.0 of Android Support Library

    Revision 23.1.0 of the Android Support Library includes the following updates:

    Added an improved animation API to the ItemAnimator class for better customizations:

    • Change animations no longer enforce two copies of the ViewHolder object, which enables item content animations. Also, the ItemAnimator object decides whether it wants to reuse the same ViewHolder object or create a new one.
    • The new information record API gives the ItemAnimator class the flexibility to collect data at the correct point in the layout lifecycle. This information is later passed into the animate callbacks.
    • Provided an easy transition plan for this backward-incompatible API change:

    If you’ve previously extended the ItemAnimator class, you can change your base class to SimpleItemAnimator and your code should work as before. The SimpleItemAnimator class provides the old API by wrapping the new API.

    Some methods were removed from the ItemAnimator class. The following code will no longer compile:

    recyclerView.getItemAnimator().setSupportsChangeAnimations(false)
    

    You can replace it with:

    ItemAnimator animator = recyclerView.getItemAnimator();
    if (animator instanceof SimpleItemAnimator) {
       ((SimpleItemAnimator) animator).setSupportsChangeAnimations(false);
    }
    

    In my project I am using Proguard, and with the new revision of the support library there are these warnings:

    Warning:jp.wasabeef.recyclerview.animators.BaseItemAnimator: can't find referenced method 'void dispatchMoveFinished(android.support.v7.widget.RecyclerView$ViewHolder)' in program class jp.wasabeef.recyclerview.animators.BaseItemAnimator
    Warning:jp.wasabeef.recyclerview.animators.BaseItemAnimator: can't find referenced method 'void dispatchChangeFinished(android.support.v7.widget.RecyclerView$ViewHolder,boolean)' in program class jp.wasabeef.recyclerview.animators.BaseItemAnimator
    Warning:jp.wasabeef.recyclerview.animators.BaseItemAnimator: can't find referenced method 'void dispatchRemoveFinished(android.support.v7.widget.RecyclerView$ViewHolder)' in program class jp.wasabeef.recyclerview.animators.BaseItemAnimator
    Warning:jp.wasabeef.recyclerview.animators.BaseItemAnimator: can't find referenced method 'void dispatchAddFinished(android.support.v7.widget.RecyclerView$ViewHolder)' in program class jp.wasabeef.recyclerview.animators.BaseItemAnimator
    Warning:jp.wasabeef.recyclerview.animators.BaseItemAnimator$4: can't find referenced method 'void dispatchMoveStarting(android.support.v7.widget.RecyclerView$ViewHolder)' in program class jp.wasabeef.recyclerview.animators.BaseItemAnimator
    Warning:jp.wasabeef.recyclerview.animators.BaseItemAnimator$4: can't find referenced method 'void dispatchMoveFinished(android.support.v7.widget.RecyclerView$ViewHolder)' in program class jp.wasabeef.recyclerview.animators.BaseItemAnimator
    Warning:jp.wasabeef.recyclerview.animators.BaseItemAnimator$5: can't find referenced method 'void dispatchChangeStarting(android.support.v7.widget.RecyclerView$ViewHolder,boolean)' in program class jp.wasabeef.recyclerview.animators.BaseItemAnimator
    Warning:jp.wasabeef.recyclerview.animators.BaseItemAnimator$5: can't find referenced method 'void dispatchChangeFinished(android.support.v7.widget.RecyclerView$ViewHolder,boolean)' in program class jp.wasabeef.recyclerview.animators.BaseItemAnimator
    Warning:jp.wasabeef.recyclerview.animators.BaseItemAnimator$6: can't find referenced method 'void dispatchChangeStarting(android.support.v7.widget.RecyclerView$ViewHolder,boolean)' in program class jp.wasabeef.recyclerview.animators.BaseItemAnimator
    Warning:jp.wasabeef.recyclerview.animators.BaseItemAnimator$6: can't find referenced method 'void dispatchChangeFinished(android.support.v7.widget.RecyclerView$ViewHolder,boolean)' in program class jp.wasabeef.recyclerview.animators.BaseItemAnimator
    Warning:jp.wasabeef.recyclerview.animators.BaseItemAnimator$DefaultAddVpaListener: can't find referenced method 'void dispatchAddStarting(android.support.v7.widget.RecyclerView$ViewHolder)' in program class jp.wasabeef.recyclerview.animators.BaseItemAnimator
    Warning:jp.wasabeef.recyclerview.animators.BaseItemAnimator$DefaultAddVpaListener: can't find referenced method 'void dispatchAddFinished(android.support.v7.widget.RecyclerView$ViewHolder)' in program class jp.wasabeef.recyclerview.animators.BaseItemAnimator
    Warning:jp.wasabeef.recyclerview.animators.BaseItemAnimator$DefaultRemoveVpaListener: can't find referenced method 'void dispatchRemoveStarting(android.support.v7.widget.RecyclerView$ViewHolder)' in program class jp.wasabeef.recyclerview.animators.BaseItemAnimator
    Warning:jp.wasabeef.recyclerview.animators.BaseItemAnimator$DefaultRemoveVpaListener: can't find referenced method 'void dispatchRemoveFinished(android.support.v7.widget.RecyclerView$ViewHolder)' in program class jp.wasabeef.recyclerview.animators.BaseItemAnimator
    

    Indeed, if I ignore these warnings, it causes a crash in my app. Please fix, thank you!

    opened by ygnessin 7
  • Getting type = 0 in my Adapter and crashing the app. Adapter with several view types.

    Getting type = 0 in my Adapter and crashing the app. Adapter with several view types.

    Hi, I'm using the SlideInBottomAnimationAdapter in my Adapter as it is in the documentation:

       vRecyclerView.setAdapter(new SlideInBottomAnimationAdapter(new AlphaInAnimationAdapter(getAdapter())));
    

    But im getting type = 0 in the method onCreateViewHolder from my own adapter:

       @Override
        public PublicationViewHolder onCreateViewHolder(ViewGroup viewGroup, int type) {
            View v;
            switch (type) {
                case USER_PUBLICATION_TYPE:
                    v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.view_holder_user_publication_no_images, null);
                    return new UserPublicationViewHolder(v);
                case USER_PUBLICATION_TYPE_W_1_IMG:
                    v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.view_holder_user_publication_w_1_img, null);
                    return new UserPublicationSingleImageViewHolder(v);
                case USER_PUBLICATION_TYPE_W_2_IMG:
                    v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.view_holder_user_publication_w_2_img, null);
                    return new UserPublicationTwoImagesViewHolder(v);
                case USER_PUBLICATION_TYPE_W_3_IMG:
                    v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.view_holder_user_publication_w_3_img, null);
                    return new UserPublicationThreeImagesViewHolder(v);
                case USER_PUBLICATION_TYPE_W_4_IMG:
                    v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.view_holder_user_publication_w_4_img, null);
                    return new UserPublicationFourImagesViewHolder(v);
                case SOCIALNETWORK_PUBLICATION_TYPE:
                    v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.view_holder_user_publication_no_images, null);
                    return new SocialNetworkPublicationViewHolder(v);
                case SOCIALNETWORK_PUBLICATION_TYPE_W_1_IMG:
                    v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.view_holder_user_publication_w_1_img, null);
                    return new SocialNetworkPublicationSingleImageViewHolder(v);
                case SOCIALNETWORK_PUBLICATION_TYPE_W_2_IMG:
                    v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.view_holder_user_publication_w_2_img, null);
                    return new SocialNetworkPublicationTwoImagesViewHolder(v);
                case SOCIALNETWORK_PUBLICATION_TYPE_W_3_IMG:
                    v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.view_holder_user_publication_w_3_img, null);
                    return new SocialNetworkPublicationThreeImagesViewHolder(v);
                case SOCIALNETWORK_PUBLICATION_TYPE_W_4_IMG:
                    v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.view_holder_user_publication_w_4_img, null);
                    return new SocialNetworkPublicationFourImagesViewHolder(v);
                case EVENT_PUBLICATION_TYPE:
                    v = LayoutInflater.from(getActivity()).inflate(R.layout.view_holder_event_publication, null);
                    return new EventPublicationViewHolder(v);
                case PLACE_PUBLICATION_TYPE:
                    v = LayoutInflater.from(getActivity()).inflate(R.layout.view_holder_place_publication, null);
                    return new PlacePublicationViewHolder(v);
            }
            throw new RuntimeException("No type matched! Type="+type);
        }
    

    I have several views as you can see but I didn't think that this will be a problem, is theres some work around?

    I show you the full adapter but theres nothing from another world. Maybe I need to call some super? But the onCreateViewHolder method is abstract so I know what should I do there.

       public class PublicationAdapter extends RecyclerView.Adapter<PublicationViewHolder> {
    
        public static final int USER_PUBLICATION_TYPE = 1;
        public static final int EVENT_PUBLICATION_TYPE = 2;
        public static final int PLACE_PUBLICATION_TYPE = 7;
        private static final int USER_PUBLICATION_TYPE_W_1_IMG = 3;
        private static final int USER_PUBLICATION_TYPE_W_2_IMG = 4;
        private static final int USER_PUBLICATION_TYPE_W_3_IMG = 5;
        private static final int USER_PUBLICATION_TYPE_W_4_IMG = 6;
        public static final int SOCIALNETWORK_PUBLICATION_TYPE = 8;
        private static final int SOCIALNETWORK_PUBLICATION_TYPE_W_1_IMG = 9;
        private static final int SOCIALNETWORK_PUBLICATION_TYPE_W_2_IMG = 10;
        private static final int SOCIALNETWORK_PUBLICATION_TYPE_W_3_IMG = 11;
        private static final int SOCIALNETWORK_PUBLICATION_TYPE_W_4_IMG = 12;
    
    
    
        private ArrayList<Publication> publications = new ArrayList<Publication>();
    
        public ArrayList<Publication> getPublications() {
            return publications;
        }
    
    
        public void setPublications(ArrayList<Publication> publications) {
            this.publications = publications;
        }
    
        @Override
        public int getItemViewType(int position) {
            Publication publication = publications.get(position);
            if (publication instanceof UserPublication) {
                int length = publication.getMedias().size();
                switch (length) {
                    case 1:
                        return USER_PUBLICATION_TYPE_W_1_IMG;
                    case 2:
                        return USER_PUBLICATION_TYPE_W_2_IMG;
                    case 3:
                        return USER_PUBLICATION_TYPE_W_3_IMG;
                    case 4:
                        return USER_PUBLICATION_TYPE_W_4_IMG;
                    default:
                        if (length > 4) {
                            return USER_PUBLICATION_TYPE_W_4_IMG;
                        }
                        break;
                }
                return USER_PUBLICATION_TYPE;
            }
            if (publication instanceof SocialNetworkPublication) {
                int length = publication.getMedias().size();
                switch (length) {
                    case 1:
                        return SOCIALNETWORK_PUBLICATION_TYPE_W_1_IMG;
                    case 2:
                        return SOCIALNETWORK_PUBLICATION_TYPE_W_2_IMG;
                    case 3:
                        return SOCIALNETWORK_PUBLICATION_TYPE_W_3_IMG;
                    case 4:
                        return SOCIALNETWORK_PUBLICATION_TYPE_W_4_IMG;
                    default:
                        if (length > 4) {
                            return SOCIALNETWORK_PUBLICATION_TYPE_W_4_IMG;
                        }
                        break;
                }
                return SOCIALNETWORK_PUBLICATION_TYPE;
            }
            if (publication instanceof EventPublication) {
                return EVENT_PUBLICATION_TYPE;
            }
            if(publication instanceof PlacePublication){
                return PLACE_PUBLICATION_TYPE;
            }
            throw new RuntimeException("Unknown view type in PublicationAdapter");
        }
    
        @Override
        public PublicationViewHolder onCreateViewHolder(ViewGroup viewGroup, int type) {
            View v;
            switch (type) {
                case USER_PUBLICATION_TYPE:
                    v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.view_holder_user_publication_no_images, null);
                    return new UserPublicationViewHolder(v);
                case USER_PUBLICATION_TYPE_W_1_IMG:
                    v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.view_holder_user_publication_w_1_img, null);
                    return new UserPublicationSingleImageViewHolder(v);
                case USER_PUBLICATION_TYPE_W_2_IMG:
                    v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.view_holder_user_publication_w_2_img, null);
                    return new UserPublicationTwoImagesViewHolder(v);
                case USER_PUBLICATION_TYPE_W_3_IMG:
                    v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.view_holder_user_publication_w_3_img, null);
                    return new UserPublicationThreeImagesViewHolder(v);
                case USER_PUBLICATION_TYPE_W_4_IMG:
                    v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.view_holder_user_publication_w_4_img, null);
                    return new UserPublicationFourImagesViewHolder(v);
                case SOCIALNETWORK_PUBLICATION_TYPE:
                    v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.view_holder_user_publication_no_images, null);
                    return new SocialNetworkPublicationViewHolder(v);
                case SOCIALNETWORK_PUBLICATION_TYPE_W_1_IMG:
                    v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.view_holder_user_publication_w_1_img, null);
                    return new SocialNetworkPublicationSingleImageViewHolder(v);
                case SOCIALNETWORK_PUBLICATION_TYPE_W_2_IMG:
                    v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.view_holder_user_publication_w_2_img, null);
                    return new SocialNetworkPublicationTwoImagesViewHolder(v);
                case SOCIALNETWORK_PUBLICATION_TYPE_W_3_IMG:
                    v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.view_holder_user_publication_w_3_img, null);
                    return new SocialNetworkPublicationThreeImagesViewHolder(v);
                case SOCIALNETWORK_PUBLICATION_TYPE_W_4_IMG:
                    v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.view_holder_user_publication_w_4_img, null);
                    return new SocialNetworkPublicationFourImagesViewHolder(v);
                case EVENT_PUBLICATION_TYPE:
                    v = LayoutInflater.from(getActivity()).inflate(R.layout.view_holder_event_publication, null);
                    return new EventPublicationViewHolder(v);
                case PLACE_PUBLICATION_TYPE:
                    v = LayoutInflater.from(getActivity()).inflate(R.layout.view_holder_place_publication, null);
                    return new PlacePublicationViewHolder(v);
            }
            throw new RuntimeException("No type matched! Type="+type);
        }
    
        private static final String INTERACTION_LIKE = "LIKE";
        private static final String INTERACTION_DISLIKE = "DISLIKE";
        private static final String INTERACTION_LOVE = "LOVE";
        private static final String INTERACTION_NONE = "";
    
        @Override
        public void onBindViewHolder(final PublicationViewHolder aPublicationHolder, int i) {
            switch (publications.get(i).getType()) {
                case Publication.TYPE_SOCIAL_NETWORK_PUBLICATION:
                    bindSocialNetworkPublicationCallbacks(aPublicationHolder, i);
                    aPublicationHolder.load(publications.get(i), FeedFragment.this);
                    break;
                case Publication.TYPE_USER_PUBLICATION:
                    bindUserPublicationCallbacks(aPublicationHolder, i);
                    aPublicationHolder.load(publications.get(i), FeedFragment.this);
                break;
                case Publication.TYPE_EVENT_PUBLICATION:
                    bindEventPublicationCallbacks(aPublicationHolder, i);
                    aPublicationHolder.load(publications.get(i), FeedFragment.this);
                break;
                case Publication.TYPE_PLACE_PUBLICATION:
                    bindPlacePublicationCallbacks(aPublicationHolder, i);
                    aPublicationHolder.load(publications.get(i), FeedFragment.this);
                break;
            }
            if (i == 0) {
                onFirstViewHolderBinded(aPublicationHolder);
            }
        }
    
        private void bindPlacePublicationCallbacks(PublicationViewHolder aPublicationHolder, int i) {
            final PlacePublication publication = (PlacePublication) publications.get(i);
            aPublicationHolder.load(publication,
                    new View.OnClickListener() {
                        @Override
                        public void onClick(View view) {
                            onLikeClicked(publication);
                        }
                    },
                    new View.OnClickListener() {
                        @Override
                        public void onClick(View view) {
                            onDislikeClicked(publication);
                        }
                    },
                    new View.OnClickListener() {
                        @Override
                        public void onClick(View view) {
                            onFavoriteClicked(publication);
                        }
                    }, FeedFragment.this);
        }
    
        private void bindEventPublicationCallbacks(PublicationViewHolder aPublicationHolder, int i) {
            final EventPublication publication = (EventPublication) publications.get(i);
            aPublicationHolder.load(publication,
                    new View.OnClickListener() {
                        @Override
                        public void onClick(View view) {
                            onLikeClicked(publication);
                        }
                    },
                    new View.OnClickListener() {
                        @Override
                        public void onClick(View view) {
                            onDislikeClicked(publication);
                        }
                    },
                    new View.OnClickListener() {
                        @Override
                        public void onClick(View view) {
                            onFavoriteClicked(publication);
                        }
                    }, FeedFragment.this);
        }
    
        private void bindUserPublicationCallbacks(PublicationViewHolder aPublicationHolder, int i) {
            final UserPublication publication = (UserPublication) publications.get(i);
            aPublicationHolder.load(publication,
                    new View.OnClickListener() {
                        @Override
                        public void onClick(View view) {
                            onLikeClicked(publication);
                        }
                    },
                    new View.OnClickListener() {
                        @Override
                        public void onClick(View view) {
                            onDislikeClicked(publication);
                        }
                    },
                    new View.OnClickListener() {
                        @Override
                        public void onClick(View view) {
                            onFavoriteClicked(publication);
                        }
                    },
                    new View.OnClickListener() {
                        @Override
                        public void onClick(View view) {
                            onEditPostClicked(publication);
                        }
                    },
                    new View.OnClickListener() {
                        @Override
                        public void onClick(View view) {
                            onDeletePostClicked(publication);
                        }
                    },
                    new TagCloudLocationFriends.OnTagSelectListener() {
                        @Override
                        public void onTagSelected(MinikastTag tag, int position) {
                            if(tag.getType() == 2){
                                GoTo.placeDetail(getActivity(), publication.getLocation().getId(), publication.getLocation().getName());
                            }else if (tag.getType() == 3){
                                User aUser = new User(-1);
                                aUser.setProfileId(String.valueOf(tag.getUserID()));
                                GoTo.user(getActivity(), aUser);
                            }
                        }
                    }, FeedFragment.this);
        }
    
        private void bindSocialNetworkPublicationCallbacks(PublicationViewHolder aPublicationHolder, int i) {
            final SocialNetworkPublication publication = (SocialNetworkPublication) publications.get(i);
            aPublicationHolder.load(publication,
                    new View.OnClickListener() {
                        @Override
                        public void onClick(View view) {
                            onLikeClicked(publication);
                        }
                    },
                    new View.OnClickListener() {
                        @Override
                        public void onClick(View view) {
                            onDislikeClicked(publication);
                        }
                    },
                    new View.OnClickListener() {
                        @Override
                        public void onClick(View view) {
                            onFavoriteClicked(publication);
                        }
                    },
                    new TagCloudLocationFriends.OnTagSelectListener() {
                        @Override
                        public void onTagSelected(MinikastTag tag, int position) {
                            if(tag.getType() == 2){
                                GoTo.placeDetail(getActivity(), publication.getLocation().getId(), publication.getLocation().getName());
                            }else if (tag.getType() == 3){
                                User aUser = new User(-1);
                                aUser.setProfileId(String.valueOf(tag.getUserID()));
                                GoTo.user(getActivity(), aUser);
                            }
                        }
                    }, FeedFragment.this);
        }
    
        private void onDeletePostClicked(UserPublication publication) {
            showDialogDeletePost(publication.getId(), mCurrentPosts.indexOf(publication));
        }
    
        private void onEditPostClicked(UserPublication publication) {
            GoTo.editPost(getActivity(), publication);
        }
    
        private void removeInteraction(Publication publication, String oldInteraction){
            RemovePostInteraction operation = new RemovePostInteraction(publication, String.valueOf(publication.getId()), StartupSharedPreferences.getUserId(), oldInteraction);
            operation.setmToken(getToken());
            sendOperationRequest(operation);
        }
    
        private void addInteraction(Publication publication, String newInteraction){
            SavePostInteractionOperation operation = new SavePostInteractionOperation(publication, String.valueOf(publication.getId()), StartupSharedPreferences.getUserId(), newInteraction);
            operation.setmToken(getToken());
            sendOperationRequest(operation);
        }
    
        private void onLikeClicked(Publication publication) {
            if(publication.getRelationship().equals(INTERACTION_LIKE)){
                publication.setRelationship(INTERACTION_NONE);
                removeInteraction(publication, INTERACTION_LIKE);
            }else{
                publication.setRelationship(INTERACTION_LIKE);
                addInteraction(publication, INTERACTION_LIKE);
            }
        }
    
        private void onFavoriteClicked(Publication publication) {
            if(publication.getRelationship().equals(INTERACTION_LOVE)){
                publication.setRelationship(INTERACTION_NONE);
                removeInteraction(publication, INTERACTION_LOVE);
            }else{
                publication.setRelationship(INTERACTION_LOVE);
                addInteraction(publication, INTERACTION_LOVE);
            }
        }
    
        private void onDislikeClicked(Publication publication) {
            if(publication.getRelationship().equals(INTERACTION_DISLIKE)){
                publication.setRelationship(INTERACTION_NONE);
                removeInteraction(publication, INTERACTION_DISLIKE);
            }else{
                publication.setRelationship(INTERACTION_DISLIKE);
                addInteraction(publication, INTERACTION_DISLIKE);
            }
        }
    
        @Override
        public long getItemId(int position) {
           return publications.get(position).getId();
        }
    
        @Override
        public int getItemCount() {
            return publications.size();
        }
    
        public void updatePublication(Publication modifP) {
            int idx = publications.indexOf(modifP);
            publications.set(idx, modifP);
        }
    }
    

    I also set the hasStableItems to true. I still can call the super.getItemViewType() but if I do so, It will still crach in the onCreateViewHolder

    opened by 4gus71n 7
  • SlideInRightAnimator Crash

    SlideInRightAnimator Crash

    i'm using API 15 on Samsung Galaxy Tab 10.1

    call AB method on UiThread

    next .. error message

    java.lang.IllegalArgumentException: Called attach on a child which is not detached: ViewHolder{4142f648 position=6 id=-1, oldPos=-1, pLpos:7undefined adapter position no parent} at android.support.v7.widget.RecyclerView$4.attachViewToParent(RecyclerView.java:422) at android.support.v7.widget.ChildHelper.attachViewToParent(ChildHelper.java:208) at android.support.v7.widget.RecyclerView$LayoutManager.addViewInt(RecyclerView.java:5239) at android.support.v7.widget.RecyclerView$LayoutManager.addView(RecyclerView.java:5216) at android.support.v7.widget.RecyclerView$LayoutManager.addView(RecyclerView.java:5204) at android.support.v7.widget.LinearLayoutManager.layoutChunk(LinearLayoutManager.java:1325) at android.support.v7.widget.LinearLayoutManager.fill(LinearLayoutManager.java:1274) at android.support.v7.widget.LinearLayoutManager.onLayoutChildren(LinearLayoutManager.java:525) at android.support.v7.widget.RecyclerView.dispatchLayout(RecyclerView.java:2072) at android.support.v7.widget.RecyclerView.onLayout(RecyclerView.java:2415) at android.view.View.layout(View.java:11477) at android.view.ViewGroup.layout(ViewGroup.java:4232) at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1644) at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1502) at android.widget.LinearLayout.onLayout(LinearLayout.java:1415) at android.view.View.layout(View.java:11477) at android.view.ViewGroup.layout(ViewGroup.java:4232) at android.widget.FrameLayout.onLayout(FrameLayout.java:431) at android.view.View.layout(View.java:11477) at android.view.ViewGroup.layout(ViewGroup.java:4232) at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1644) at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1502) at android.widget.LinearLayout.onLayout(LinearLayout.java:1415) at android.view.View.layout(View.java:11477) at android.view.ViewGroup.layout(ViewGroup.java:4232) at android.widget.FrameLayout.onLayout(FrameLayout.java:431) at android.view.View.layout(View.java:11477) at android.view.ViewGroup.layout(ViewGroup.java:4232) at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1644) at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1502) at android.widget.LinearLayout.onLayout(LinearLayout.java:1415) at android.view.View.layout(View.java:11477) at android.view.ViewGroup.layout(ViewGroup.java:4232) at android.widget.FrameLayout.onLayout(FrameLayout.java:431) at android.view.View.layout(View.java:11477) at android.view.ViewGroup.layout(ViewGroup.java:4232) at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1692) at android.view.ViewRootImpl.handleMessage(ViewRootImpl.java:2649) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loop(Looper.java:137) at android.app.ActivityThread.main(ActivityThread.java:4507) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:511) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:978) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:745) at dalvik.system.NativeStart.main(Native Method)

    opened by kronenz 4
  • Support for androidx

    Support for androidx

    Hey, is it possible to get support for androidx for this library? The current version builds just fine but it shows errors in Android Studio since the classes are basically the same but the package names are not.

    opened by KartikShankhavaram 3
  • Implement Hierarchical Timing specification for all animators in accordance with Google Material Design motion guidelines

    Implement Hierarchical Timing specification for all animators in accordance with Google Material Design motion guidelines

    Goal

    Adhere to the Google Material Design Hierarchical Timing spec, illustrated in this video.

    Motivation

    The Google Material Design spec for recycler view animations specifies:

    When building a transition, consider the order and timing of element movement. Ensure that motion supports the information hierarchy, conveying what content is most important by creating a path for the eye to follow. recyclerview-animators does not currently follow this specification - all elements animate in at once.

    Pull Request

    In this PR, I've implemented the Hierarchical Timing specification for all animators, achieving the cool effect that the spec video shows.

    Here's a video of my implementation in action, in my app: https://www.dropbox.com/s/gxiw63pn7ljv3if/recyclerview-animation.mp4?dl=0

    Implementation details

    I achieved this by adding a .setStartDelay call to each Animator's animateAddImpl and animateRemoveImpl method. They call two new methods on BaseAnimator: getAddDelay and getRemoveDelay respectively. These methods will determine the delay based on:

    1. the element's position in the adapter
    2. the current add or remove duration set by .setAddDuration or setRemoveDuration (currently, this is retrieved and then divided by 4 - I found this gives the best result and provides smooth, overlapping animations that are closest to the spec video.)

    Let me know if you need more information to merge this. Thanks for the great library!

    opened by aphexcx 3
  • Added in ability to pass in interpolators to the four ItemAnimators

    Added in ability to pass in interpolators to the four ItemAnimators

    Added in an interpolator member to BaseItem. This allowed for the 4 SlideIn itemanimators to have a secondary constructor that accepts an Interpolator as an argument. If none was passed into the constructor, then the default LinearInterpolator is used.

    enhancement 
    opened by christophereluc 3
  • No animation when using with cursor

    No animation when using with cursor

    Hello, First of all, this is a really nice project and initiative. Congrats! I tested with using an ArrayList as Dataset and worked just fine. But when I tried to implement in my project, where I use a cursor as data, no animation played (except the adapter animation, with was a little buggy). I don't know if is a problem, but I'm just notifying the adapter with: notifyDataSetChanged()

    RecyclerView Declaration and setup:

    // Cursor Adapter  
     recyclerAdapterDetail   = new DetailTaskRecyclerAdapter( getActivity(), null );
     recyclerViewDetail      = (RecyclerView)       fragmentView.findViewById(R.id.fragment_detail_recyclerview);
    
      LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getActivity());
      linearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
    
      recyclerViewDetail.setItemAnimator(new FadeInAnimator());
      recyclerViewDetail.getItemAnimator().setAddDuration( 1000 );
      recyclerViewDetail.setLayoutManager(linearLayoutManager);
    
      recyclerViewDetail.setAdapter( recyclerAdapterDetail );
    

    Notifying part on the adapter:

    public Cursor swapCursor(Cursor cursor) {
        if (this.cursor == cursor) {
            return null;
        }
        Cursor oldCursor = this.cursor;
        this.cursor = cursor;
        if (cursor != null) {
            this.notifyDataSetChanged();
        }
        return oldCursor;
    }
    
    opened by tinmegali 3
  • Delegate hasStableIds to wrapped adapter

    Delegate hasStableIds to wrapped adapter

    What does this change?

    RecyclerView behavior can change based on hasStableIds, it's better to delegate hasStableIds to the wrapped adapter. Noticed that hasStableIds is final, so we cannot completely delegate the behavior to the wrapped adapter.

    What is the value of this and can you measure success?

    hasStableIds works properply

    Screenshots

    No

    opened by lcdsmao 2
  • Animator Crashing

    Animator Crashing

    Bug Reporting

    We recently started getting the crash below on some devices (200 / 7000). I can't even tell at which part of our code is it.

    Steps to Reproduce

    • Unknown

    OS details

    • Device: Some
    • OS: 11-13

    Stacktrace

    Fatal Exception: java.lang.IllegalStateException: Cannot find wrapper for b{d3fe4d5 position=4 id=-1, oldPos=-1, pLpos:-1 invalid update undefined adapter position no parent}, seems like it is not bound by this adapter: androidx.recyclerview.widget.e@12c523f
           at androidx.recyclerview.widget.ConcatAdapterController.onViewRecycled(ConcatAdapterController.java:51)
           at androidx.recyclerview.widget.ConcatAdapter.onViewRecycled(ConcatAdapter.java:51)
           at androidx.recyclerview.widget.RecyclerView$Recycler.dispatchViewRecycled(RecyclerView.java:76)
           at androidx.recyclerview.widget.RecyclerView$Recycler.recycleViewHolderInternal(RecyclerView.java:202)
           at androidx.recyclerview.widget.RecyclerView.removeAnimatingView(RecyclerView.java:62)
           at androidx.recyclerview.widget.RecyclerView$ItemAnimatorRestoreListener.onAnimationFinished(RecyclerView.java:42)
           at androidx.recyclerview.widget.RecyclerView$ItemAnimator.dispatchAnimationFinished(RecyclerView.java:42)
           at androidx.recyclerview.widget.SimpleItemAnimator.dispatchAddFinished(SimpleItemAnimator.java:22)
           at jp.wasabeef.recyclerview.animators.BaseItemAnimator$DefaultAddAnimatorListener.onAnimationEnd(BaseItemAnimator.java:22)
           at android.view.ViewPropertyAnimator$AnimatorEventListener.onAnimationEnd(ViewPropertyAnimator.java:1116)
           at android.animation.Animator$AnimatorListener.onAnimationEnd(Animator.java:563)
           at android.animation.ValueAnimator.endAnimation(ValueAnimator.java:1250)
           at android.animation.ValueAnimator.doAnimationFrame(ValueAnimator.java:1505)
           at android.animation.AnimationHandler.doAnimationFrame(AnimationHandler.java:146)
           at android.animation.AnimationHandler.access$100(AnimationHandler.java:37)
           at android.animation.AnimationHandler$1.doFrame(AnimationHandler.java:54)
           at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1221)
           at android.view.Choreographer.doCallbacks(Choreographer.java:1020)
           at android.view.ChoreographerExtImpl.checkScrollOptSceneEnable(ChoreographerExtImpl.java:319)
           at android.view.Choreographer.doFrame(Choreographer.java:909)
           at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:1208)
           at android.os.Handler.handleCallback(Handler.java:938)
           at android.os.Handler.dispatchMessage(Handler.java:99)
           at android.os.Looper.loopOnce(Looper.java:233)
           at android.os.Looper.loop(Looper.java:344)
           at android.app.ActivityThread.main(ActivityThread.java:8191)
           at java.lang.reflect.Method.invoke(Method.java)
           at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:584)
           at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1034)
    
    opened by rtsketo 0
  • Add animations work; Remove animations are clunky

    Add animations work; Remove animations are clunky

    Video: https://imgur.com/a/DoDWNvE

    Hi, I'm using an animator like so:

        views.list.layoutManager = LinearLayoutManager(context)
        views.list.itemAnimator = SlideInLeftAnimator()
    

    The add animation work nicely, there is cascading effect where the items arrives one by one. However, the remove animation is clunky: all the items are removed at the same time. I would expect the items to be removed one by one as well.

    After reading the source, I noticed that BaseItemAnimator uses ViewHolder.getOldPosition() to achieve the cascading effect for remove animations. But for me, the old position is always -1, meaning the RecyclerView is not recording ViewHolder's old position.

    Are there any special setup you have to do to make RecyclerView record ViewHolder's old position?

    opened by littledot 1
  • Default ItemAnimators don't use interpolator from constructor

    Default ItemAnimators don't use interpolator from constructor

    For example FadeInAnimator

    `  override fun animateRemoveImpl(holder: RecyclerView.ViewHolder) {
        holder.itemView.animate().apply {
          alpha(0f)
          duration = removeDuration
          interpolator = interpolator
          setListener(DefaultRemoveAnimatorListener(holder))
          startDelay = getRemoveDelay(holder)
        }.start()
      }`
    

    The code interpolator = interpolator is similar to ViewPropertyAnimator.setInterpolator(ViewPropertyAnimator.getInterpolator())

    To fix, you need to use interpolator = [email protected]

    FideInAnimator

    Library version : 4.0.2

    opened by ggolyakov 0
  • Remove Animation Is Applied To All Items Strange Behaviour

    Remove Animation Is Applied To All Items Strange Behaviour

    I am trying to apply slide to right animation to only removed item but for some reason all items in recyclerview disappear first and then animated back to their position strangely. Please watch the following video. https://i.stack.imgur.com/s14Jr.gif

    Here is my code its very simple:

       friends_screen_friendlist_recyclerview.itemAnimator = SlideInRightAnimator()
                       friends_screen_friendlist_recyclerview.itemAnimator?.apply {
                            addDuration = 120;
                           removeDuration = 1000;
                            moveDuration = 500;
                            changeDuration = 500;
                       }
        friendItems.removeAt(0)
    
                   friends_screen_friendlist_recyclerview.adapter!!.notifyItemRemoved(0)
    
    
    opened by lastpeony 1
  • start delay for add/remove animation

    start delay for add/remove animation

    What does this change?

    • Resolving #176
    • Convert AnimatorSampleActivity to Kotlin
    • Set function for AddDelay and RemoveDelay for customizing delay for starting add/remove animation

    What is the value of this and can you measure success?

    • Everyone using this library can set getAddDelay and getRemoveDelay function without changing the core of the library

    Screenshots

    opened by kAvEh-- 0
Owner
Daichi Furiya
Google Developers Expert for Android
Daichi Furiya
Android library providing simple way to control divider items (ItemDecoration) of RecyclerView

RecyclerView-FlexibleDivider Android library providing simple way to control divider items of RecyclerView Release Note [Release Note] (https://github

Yoshihito Ikeda 2.4k Dec 18, 2022
Android library for RecyclerView to manage order of items and multiple view types.

recyclerview-binder Android Library for RecyclerView to manage order of items and multiple view types. Features Insert any items to wherever you want

Satoru Fujiwara 185 Nov 15, 2022
ANDROID. ChipsLayoutManager (SpanLayoutManager, FlowLayoutManager). A custom layout manager for RecyclerView which mimicric TextView span behaviour, flow layouts behaviour with support of amazing recyclerView features

ChipsLayoutManager This is ChipsLayoutManager - custom Recycler View's LayoutManager which moves item to the next line when no space left on the curre

Oleg Beloy 3.2k Dec 25, 2022
Square Cycler API allows you to easily configure an Android RecyclerView declaratively in a succinct way.

Square Cycler – a RecyclerView API The Square Cycler API allows you to easily configure an Android RecyclerView declaratively in a succinct way. Desig

Square 791 Dec 23, 2022
Add RecyclerView, use Adapter class and ViewHolder to display data.

فكرة المشروع في هذا المشروع سنقوم بعرض قائمة من البيانات للطلاب على واجهة تطبيق Android بإستخدام: مفهوم RecyclerView مفهوم Adapter مفهوم ViewModel محت

Shaima Alghamdi 3 Nov 18, 2021
Add error handling in RecyclerView

MarsPhotosAPi Exercises Components Used Recycler View API enu The Second Image when i Turn off wifi . References https://developer.android.com/courses

Abdullah Alsmari 0 Nov 25, 2021
A RecyclerView(advanced and flexible version of ListView in Android) with refreshing,loading more,animation and many other features.

UltimateRecyclerView Master branch: Dev branch: Project website:https://github.com/cymcsg/UltimateRecyclerView Description UltimateRecyclerView is a R

MarshalChen 7.2k Jan 2, 2023
TikTok-RecyclerView - This is a demo app built using 'Koin' a new dependency injection framework for Android along with RecyclerView and ExoPlayer2.

TikTok-RecyclerView Demo About This is a demo app built using 'Koin' a new dependency injection framework for Android along with RecyclerView and ExoP

Baljeet Singh 19 Dec 28, 2022
A RecyclerView that implements pullrefresh and loadingmore featrues.you can use it like a standard RecyclerView

XRecyclerView a RecyclerView that implements pullrefresh , loadingmore and header featrues.you can use it like a standard RecyclerView. you don't need

XRecyclerView 5.3k Dec 26, 2022
A RecyclerView that implements pullrefresh and loadingmore featrues.you can use it like a standard RecyclerView

XRecyclerView a RecyclerView that implements pullrefresh , loadingmore and header featrues.you can use it like a standard RecyclerView. you don't need

XRecyclerView 5.3k Dec 26, 2022
Carousel Recyclerview let's you create carousel layout with the power of recyclerview by creating custom layout manager.

Carousel Recyclerview let's you create carousel layout with the power of recyclerview by creating custom layout manager.

Jack and phantom 504 Dec 25, 2022
RecyclerView : SleepQualityTracker with RecyclerView app

RecyclerView - SleepQualityTracker with RecyclerView app SleepQualityTracker with RecyclerView This app builds on the SleepQualityTracker developed pr

Kevin 2 May 14, 2022
Pagination-RecyclerView - Simple and easy way to Paginating a RecyclerView

Pagination-RecyclerView Simple and easy way to Paginating a RecyclerView Android

Rakshit Nawani 0 Jan 3, 2022
RecyclerView extension library which provides advanced features. (ex. Google's Inbox app like swiping, Play Music app like drag and drop sorting)

Advanced RecyclerView This RecyclerView extension library provides Google's Inbox app like swiping, Play Music app like drag-and-drop sorting and expa

Haruki Hasegawa 5.2k Dec 23, 2022
Examples of custom recycler view items. Automatically detecting a dominant color of an image using Picasso and Palette libraries

custom-image-list-item Examples of custom RecyclerView items using Data Binding Features: Loading images urls with the help of a Picasso library Autom

Alina Stepanova 2 Sep 12, 2022
A RecyclerView Adapter which allows you to have an Infinite scrolling list in your apps

Infinite Recycler View A RecyclerView Adapter which allows you to have an Infinite scrolling list in your apps. This library offers you a custom adapt

IB Sikiru 26 Dec 10, 2019
Android Library to provide swipe, click and other functionality to RecyclerView

RecyclerViewEnhanced Android Library to provide swipe, click and other functionality to RecyclerView Usage Add this to your build.gradle file dependen

Nikhil Panju 1k Dec 29, 2022
Android library defining adapter classes of RecyclerView to manage multiple view types

RecyclerView-MultipleViewTypeAdapter RecyclerView adapter classes for managing multiple view types Release Note [Release Note] (https://github.com/yqr

Yoshihito Ikeda 414 Nov 21, 2022