wake-up-neo.com

Wie animiere ich RecyclerView-Elemente, wenn sie angezeigt werden?

Wie kann ich die RecyclerView-Elemente beim Erscheinen animieren?

Der Standardelementanimator wird nur animiert, wenn Daten hinzugefügt oder entfernt werden, nachdem die Recyclingdaten festgelegt wurden. Ich entwickle neue Anwendungen und habe keine Ahnung, wo ich anfangen soll.

Irgendwelche Ideen, wie man das erreichen kann?

203
PaulNunezM

EDIT:

Gemäß der ItemAnimator-Dokumentation :

Diese Klasse definiert die Animationen, die für Elemente ausgeführt werden, wenn Änderungen am Adapter vorgenommen werden.

Wenn Sie also Ihre Elemente nicht einzeln zu Ihrer RecyclerView hinzufügen und die Ansicht bei jeder Iteration aktualisieren, glaube ich nicht, dass ItemAnimator die Lösung für Ihre Bedürfnisse ist.

So können Sie die RecyclerView-Elemente animieren, wenn sie mit einem CustomAdapter angezeigt werden:

public class CustomAdapter extends RecyclerView.Adapter<CustomAdapter.ViewHolder>
{
    private Context context;

    // The items to display in your RecyclerView
    private ArrayList<String> items;
    // Allows to remember the last item shown on screen
    private int lastPosition = -1;

    public static class ViewHolder extends RecyclerView.ViewHolder
    {
        TextView text;
        // You need to retrieve the container (ie the root ViewGroup from your custom_item_layout)
        // It's the view that will be animated
        FrameLayout container;

        public ViewHolder(View itemView)
        {
            super(itemView);
            container = (FrameLayout) itemView.findViewById(R.id.item_layout_container);
            text = (TextView) itemView.findViewById(R.id.item_layout_text);
        }
    }

    public CustomAdapter(ArrayList<String> items, Context context)
    {
        this.items = items;
        this.context = context;
    }

    @Override
    public CustomAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType)
    {
        View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.custom_item_layout, parent, false);
        return new ViewHolder(v);
    }

    @Override
    public void onBindViewHolder(ViewHolder holder, int position)
    {
        holder.text.setText(items.get(position));

        // Here you apply the animation when the view is bound
        setAnimation(holder.itemView, position);
    }

    /**
     * Here is the key method to apply the animation
     */
    private void setAnimation(View viewToAnimate, int position)
    {
        // If the bound view wasn't previously displayed on screen, it's animated
        if (position > lastPosition)
        {
            Animation animation = AnimationUtils.loadAnimation(context, Android.R.anim.slide_in_left);
            viewToAnimate.startAnimation(animation);
            lastPosition = position;
        }
    }
}

Und Ihr custom_item_layout würde so aussehen:

<FrameLayout
    Android:id="@+id/item_layout_container"
    xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:layout_width="match_parent"
    Android:layout_height="wrap_content">

    <TextView
        Android:id="@+id/item_layout_text"
        Android:layout_width="match_parent"
        Android:layout_height="wrap_content"
        Android:textAppearance="?android:attr/textAppearanceListItemSmall"
        Android:gravity="center_vertical"
        Android:minHeight="?android:attr/listPreferredItemHeightSmall"/>

</FrameLayout>

Weitere Informationen zu CustomAdapters und RecyclerView finden Sie in diesem training in der offiziellen Dokumentation .

Probleme beim schnellen Blättern

Die Verwendung dieser Methode kann zu Problemen beim schnellen Scrollen führen. Die Ansicht kann während der Animation erneut verwendet werden. Um dies zu vermeiden, empfiehlt es sich, die Animation zu löschen, wenn sie getrennt wird.

    @Override
    public void onViewDetachedFromWindow(final RecyclerView.ViewHolder holder)
    {
        ((CustomViewHolder)holder).clearAnimation();
    }

Auf CustomViewHolder:

    public void clearAnimation()
    {
        mRootLayout.clearAnimation();
    }

Alte Antwort:

Werfen Sie einen Blick auf Gabrielo Mariottis Repo , ich bin mir ziemlich sicher, dass Sie finden, was Sie brauchen. Er stellt einfache ItemAnimators für die RecyclerView bereit, beispielsweise SlideInItemAnimator oder SlideScaleItemAnimator.

291
MathieuMaree

Ich habe das Einblenden von Recyclerview-Objekten animiert, wenn sie wie im folgenden Code gezeigt angezeigt werden. Vielleicht hilft das jemandem.

private final static int FADE_DURATION = 1000; //FADE_DURATION in milliseconds

@Override
public void onBindViewHolder(ViewHolder holder, int position) {

    holder.getTextView().setText("some text");

    // Set the view to fade in
    setFadeAnimation(holder.itemView);            
}

private void setFadeAnimation(View view) {
    AlphaAnimation anim = new AlphaAnimation(0.0f, 1.0f);
    anim.setDuration(FADE_DURATION);
    view.startAnimation(anim);
}

Sie können setFadeAnimation() auch durch die folgende setScaleAnimation() ersetzen, um das Erscheinungsbild von Elementen zu animieren, indem Sie sie von einem Punkt aus skalieren:

private void setScaleAnimation(View view) {
    ScaleAnimation anim = new ScaleAnimation(0.0f, 1.0f, 0.0f, 1.0f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
    anim.setDuration(FADE_DURATION);
    view.startAnimation(anim);
}

Der obige Code weist einige Warzen auf, sofern beim Scrollen die RecyclerView-Elemente immer verblassen oder skalieren. Wenn Sie möchten, können Sie Code hinzufügen, um die Animation nur dann zuzulassen, wenn das Fragment oder die Aktivität mit der Variablen RecyclerView zum ersten Mal erstellt wird (z. B. Systemzeit bei der Erstellung abrufen und Animation nur für die ersten FADE_DURATION-Millisekunden zulassen).

53
pbm

Ich habe eine Animation aus pbms Antwort mit wenig modification erstellt, damit die Animation nur einmal ausgeführt wird 

im anderen Wort der Animation appear with you scroll down only 

private int lastPosition = -1;

private void setAnimation(View viewToAnimate, int position) {
    // If the bound view wasn't previously displayed on screen, it's animated
    if (position > lastPosition) {
        ScaleAnimation anim = new ScaleAnimation(0.0f, 1.0f, 0.0f, 1.0f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
        anim.setDuration(new Random().nextInt(501));//to make duration random number between [0,501)
        viewToAnimate.startAnimation(anim);
        lastPosition = position;
    }
}

und in onBindViewHolder rufen Sie die Funktion auf 

@Override
public void onBindViewHolder(ViewHolder holder, int position) {

holder.getTextView().setText("some text");

// call Animation function
setAnimation(holder.itemView, position);            
}
21

Sie können ein RecyclerView-Attribut wie folgt hinzufügen: layoutAnimation = "@ anim/rv_item_animation":

<Android.support.v7.widget.RecyclerView
    Android:layout_width="match_parent"
    Android:layout_height="match_parent"                                        
    Android:layoutAnimation="@anim/layout_animation_fall_down"
    />

danke für den ausgezeichneten Artikel hier: https://proandroiddev.com/enter-animation-using-recyclerview-and-layoutanimation-part-1-list-75a874a5d213

11
Pavel Biryukov

Ein guter Anfang ist folgender: https://github.com/wasabeef/recyclerview-animators/blob/master/animators/src/main/Java/jp/wasabeef/recyclerview/adapters/AnimationAdapter.Java

Sie benötigen nicht einmal die gesamte Bibliothek, diese Klasse reicht aus ... __ Wenn Sie Ihre Adapter-Klasse einfach implementieren, geben Sie einen Animator wie folgt:

@Override
protected Animator[] getAnimators(View view) {
    return new Animator[]{
            ObjectAnimator.ofFloat(view, "translationY", view.getMeasuredHeight(), 0)
    };
}

@Override
public long getItemId(final int position) {
    return getWrappedAdapter().getItemId(position);
}

sie sehen Elemente, die beim Scrollen von unten erscheinen, und vermeiden auch das Problem mit dem schnellen Scrollen.

8

Das Animieren von Elementen in der Recyclingübersicht, wenn sie im Adapter gebunden sind, ist möglicherweise nicht die beste Idee, da dies dazu führen kann, dass die Elemente in der Recyclingübersicht mit unterschiedlichen Geschwindigkeiten animiert werden. In meinem Fall animieren die Gegenstände am Ende des Recyclingberichts schneller zu ihrer Position, als diejenigen, die oben sind, da die Gegenstände weiter oben reisen müssen, so dass es unordentlich aussieht.

Den ursprünglichen Code, mit dem ich jeden Artikel in das Recycling-Fenster animiert habe, finden Sie hier:

http://frogermcs.github.io/Instagram-with-Material-Design-concept-is-getting-real/

Aber ich werde den Code kopieren und einfügen, falls der Link bricht.

SCHRITT 1: Legen Sie dies in Ihrer onCreate-Methode fest, damit die Animation nur einmal ausgeführt wird:

if (savedInstanceState == null) {
    pendingIntroAnimation = true;
}

SCHRITT 2: Sie müssen diesen Code in die Methode einfügen, in der Sie die Animation starten möchten:

if (pendingIntroAnimation) {
    pendingIntroAnimation = false;
    startIntroAnimation();
}

In dem Link animiert der Schreiber die Symbolleistensymbole, sodass er sie in diese Methode einfügt:

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.menu_main, menu);
    inboxMenuItem = menu.findItem(R.id.action_inbox);
    inboxMenuItem.setActionView(R.layout.menu_item_view);
    if (pendingIntroAnimation) {
        pendingIntroAnimation = false;
        startIntroAnimation();
    }
    return true;
}

SCHRITT 3: Schreibe jetzt die Logik für startIntroAnimation ():

private static final int ANIM_DURATION_TOOLBAR = 300;

private void startIntroAnimation() {
    btnCreate.setTranslationY(2 * getResources().getDimensionPixelOffset(R.dimen.btn_fab_size));

    int actionbarSize = Utils.dpToPx(56);
    toolbar.setTranslationY(-actionbarSize);
    ivLogo.setTranslationY(-actionbarSize);
    inboxMenuItem.getActionView().setTranslationY(-actionbarSize);

    toolbar.animate()
            .translationY(0)
            .setDuration(ANIM_DURATION_TOOLBAR)
            .setStartDelay(300);
    ivLogo.animate()
            .translationY(0)
            .setDuration(ANIM_DURATION_TOOLBAR)
            .setStartDelay(400);
    inboxMenuItem.getActionView().animate()
            .translationY(0)
            .setDuration(ANIM_DURATION_TOOLBAR)
            .setStartDelay(500)
            .setListener(new AnimatorListenerAdapter() {
                @Override
                public void onAnimationEnd(Animator animation) {
                    startContentAnimation();
                }
            })
            .start();
}

Meine bevorzugte Alternative:

Ich möchte lieber das gesamte Recyclingblatt animieren, anstatt die Elemente im Recyclingblatt.

SCHRITT 1 und 2 bleiben gleich.

In Schritt 3 würde ich die Animation starten, sobald Ihr API-Aufruf mit Ihren Daten zurückkehrt.

private void startIntroAnimation() {
    recyclerview.setTranslationY(latestPostRecyclerview.getHeight());
    recyclerview.setAlpha(0f);
    recyclerview.animate()
            .translationY(0)
            .setDuration(400)
            .alpha(1f)
            .setInterpolator(new AccelerateDecelerateInterpolator())
            .start();
}

Dies würde Ihr gesamtes Recycling-Fenster so animieren, dass es vom unteren Bildschirmrand eingeblendet wird.

3
Simon

Erstellen Sie diese Methode in Ihrem recyclerview Adapter

private void setZoomInAnimation(View view) {
        Animation zoomIn = AnimationUtils.loadAnimation(context, R.anim.zoomin);// animation file 
        view.startAnimation(zoomIn);
    }

Und schließlich fügen Sie diese Codezeile in onBindViewHolder hinzu

setZoomInAnimation(holder.itemView);

2

Fügen Sie diese Zeile zu RecyclerView.xml hinzu

Android:animateLayoutChanges="true"
0
Avinash Verma

Erweitert einfach deinen Adapter wie unten 

public class RankingAdapter extends AnimatedRecyclerView<RankingAdapter.ViewHolder> 

Fügen Sie eine Supermethode zu onBindViewHolder hinzu

@Override
    public void onBindViewHolder(ViewHolder holder, final int position) {
        super.onBindViewHolder(holder, position);

Es ist ein automatischer Weg, animierte Adapter wie "Basheer AL-MOMANI" zu erstellen.

import Android.support.v7.widget.RecyclerView;
import Android.view.View;
import Android.view.ViewGroup;
import Android.view.animation.Animation;
import Android.view.animation.ScaleAnimation;

import Java.util.Random;

/**
 * Created by eliaszkubala on 24.02.2017.
 */
public class AnimatedRecyclerView<T extends RecyclerView.ViewHolder> extends RecyclerView.Adapter<T> {


    @Override
    public T onCreateViewHolder(ViewGroup parent, int viewType) {
        return null;
    }

    @Override
    public void onBindViewHolder(T holder, int position) {
        setAnimation(holder.itemView, position);
    }

    @Override
    public int getItemCount() {
        return 0;
    }

    protected int mLastPosition = -1;

    protected void setAnimation(View viewToAnimate, int position) {
        if (position > mLastPosition) {
            ScaleAnimation anim = new ScaleAnimation(0.0f, 1.0f, 0.0f, 1.0f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
            anim.setDuration(new Random().nextInt(501));//to make duration random number between [0,501)
            viewToAnimate.startAnimation(anim);
            mLastPosition = position;
        }
    }

}
0
EliaszKubala

Ohne Codierung.

Besuchen Sie Gist Link

  <?xml version="1.0" encoding="utf-8"?>
<layoutAnimation xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:animation="@anim/item_animation_fall_down"
    Android:animationOrder="normal"
    Android:delay="15%" />

<translate
    Android:fromYDelta="-20%"
    Android:toYDelta="0"
    Android:interpolator="@Android:anim/decelerate_interpolator"
    />

<alpha
    Android:fromAlpha="0"
    Android:toAlpha="1"
    Android:interpolator="@Android:anim/decelerate_interpolator"
    />

<scale
    Android:fromXScale="105%"
    Android:fromYScale="105%"
    Android:toXScale="100%"
    Android:toYScale="100%"
    Android:pivotX="50%"
    Android:pivotY="50%"
    Android:interpolator="@Android:anim/decelerate_interpolator"
    />

Verwendung in Layouts und Wiederholungsübersicht wie:

<Android.support.v7.widget.RecyclerView
            Android:id="@+id/recycler_view"
            Android:layout_width="match_parent"
            Android:layout_height="wrap_content"
            Android:layoutAnimation="@anim/layout_animation"
            app:layout_behavior="@string/appbar_scrolling_view_behavior" />
0
Na Ran