android - make - recyclerview dependency
Cómo animar elementos RecyclerView cuando aparecen (9)
Animé el desvanecimiento de los elementos de
Recyclerview
cuando aparecieron por primera vez como se muestra en el siguiente código.
Quizás esto sea de utilidad para alguien.
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);
}
También puede reemplazar
setFadeAnimation()
con el siguiente
setScaleAnimation()
para animar la apariencia de los elementos al escalarlos desde un punto:
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);
}
El código anterior tiene algunas verrugas en cuanto a que al desplazar los elementos
RecyclerView
siempre se desvanecen o escalan.
Si lo desea, puede agregar código para permitir que la animación suceda cuando se cree el fragmento o la actividad que contiene
RecyclerView
(por ejemplo, obtenga la hora del sistema en la creación y solo permita la animación durante los primeros milisegundos de FADE_DURATION).
¿Cómo puedo animar los elementos de RecyclerView cuando aparecen?
El animador de elementos predeterminado solo anima cuando se agregan o eliminan datos después de que se hayan establecido los datos del reciclador. Estoy desarrollando nuevas aplicaciones y no tengo ni idea de por dónde empezar.
¿Alguna idea de cómo lograr esto?
Animar elementos en la vista de reciclaje cuando están unidos en el adaptador podría no ser la mejor idea, ya que puede hacer que los elementos en la vista de reciclaje se animen a diferentes velocidades. En mi caso, el artículo al final de la vista del reciclador se anima a su posición más rápido que los que están en la parte superior, ya que los que están en la parte superior tienen que viajar más, por lo que se ve desordenado.
El código original que usé para animar cada elemento en la vista del reciclador se puede encontrar aquí:
http://frogermcs.github.io/Instagram-with-Material-Design-concept-is-getting-real/
Pero copiaré y pegaré el código en caso de que se rompa el enlace.
PASO 1: configure esto dentro de su método onCreate para asegurarse de que la animación solo se ejecute una vez:
if (savedInstanceState == null) {
pendingIntroAnimation = true;
}
PASO 2: Deberá poner este código en el método donde desea iniciar la animación:
if (pendingIntroAnimation) {
pendingIntroAnimation = false;
startIntroAnimation();
}
En el enlace, el escritor está animando los iconos de la barra de herramientas, por lo que lo puso dentro de este método:
@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;
}
PASO 3: Ahora escriba la lógica para 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();
}
Mi alternativa preferida:
Prefiero animar toda la vista del reciclador en lugar de los elementos dentro de la vista del reciclador.
Los PASOS 1 y 2 siguen siendo los mismos.
En el PASO 3, tan pronto como su llamada API regrese con sus datos, comenzaría la animación.
private void startIntroAnimation() {
recyclerview.setTranslationY(latestPostRecyclerview.getHeight());
recyclerview.setAlpha(0f);
recyclerview.animate()
.translationY(0)
.setDuration(400)
.alpha(1f)
.setInterpolator(new AccelerateDecelerateInterpolator())
.start();
}
Esto animaría toda su vista de reciclador para que vuele desde la parte inferior de la pantalla.
Cree este método en su adaptador de vista de reciclaje
private void setZoomInAnimation(View view) {
Animation zoomIn = AnimationUtils.loadAnimation(context, R.anim.zoomin);// animation file
view.startAnimation(zoomIn);
}
Y finalmente agregue esta línea de código en onBindViewHolder
setZoomInAnimation(holder.itemView);
Hecho simple con XML solamente
res / anim / layout_animation.xml
<?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%" />
res / anim / item_animation_fall_down.xml
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="500">
<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"
/>
</set>
Úselo en diseños y vistas de lista como:
<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" />
Puede agregar un
android:layoutAnimation="@anim/rv_item_animation"
a
RecyclerView
así:
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layoutAnimation="@anim/layout_animation_fall_down"
/>
gracias por el excelente artículo aquí: https://proandroiddev.com/enter-animation-using-recyclerview-and-layoutanimation-part-1-list-75a874a5d213
Solo extiende su adaptador como a continuación
public class RankingAdapter extends AnimatedRecyclerView<RankingAdapter.ViewHolder>
Y agregue un súper método a onBindViewHolder
@Override
public void onBindViewHolder(ViewHolder holder, final int position) {
super.onBindViewHolder(holder, position);
Es una forma automatizada de crear un adaptador animado como "Basheer AL-MOMANI"
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;
}
}
}
Un buen lugar para comenzar es este: https://github.com/wasabeef/recyclerview-animators/blob/master/animators/src/main/java/jp/wasabeef/recyclerview/adapters/AnimationAdapter.java
Ni siquiera necesita la biblioteca completa, esa clase es suficiente. Entonces, si solo implementas tu clase de Adaptador dando un animador como este:
@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);
}
verá elementos que aparecen desde la parte inferior a medida que se desplazan, evitando también el problema con el desplazamiento rápido.
Creé
animación a partir de
la respuesta
de
pbm
con poca
modification
para que la aninmation se ejecute solo una vez
en la otra palabra, la
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;
}
}
y en
onBindViewHolder
llama a la función
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
holder.getTextView().setText("some text");
// call Animation function
setAnimation(holder.itemView, position);
}
EDITAR:
De acuerdo con la documentación del ItemAnimator :
Esta clase define las animaciones que tienen lugar en los elementos a medida que se realizan cambios en el adaptador.
Entonces, a menos que agregue sus elementos uno por uno a su
RecyclerView
y actualice la vista en cada iteración, no creo que
ItemAnimator
sea la solución a su necesidad.
A continuación, le mostramos cómo puede animar los elementos
RecyclerView
cuando aparecen con un Adaptador personalizado:
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;
}
}
}
Y su custom_item_layout se vería así:
<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>
Para obtener más información sobre CustomAdapters y
RecyclerView
, consulte esta
capacitación en la documentación oficial
.
Problemas en el desplazamiento rápido
El uso de este método podría causar problemas con el desplazamiento rápido. La vista se puede reutilizar mientras se realiza la animación. Para evitar eso, es recomendable borrar la animación cuando se separa.
@Override
public void onViewDetachedFromWindow(final RecyclerView.ViewHolder holder)
{
((CustomViewHolder)holder).clearAnimation();
}
En CustomViewHolder:
public void clearAnimation()
{
mRootLayout.clearAnimation();
}
Vieja respuesta:
Eche un vistazo al repositorio de Gabriele Mariotti , estoy bastante seguro de que encontrará lo que necesita. Proporciona ItemAnimators simples para RecyclerView, como SlideInItemAnimator o SlideScaleItemAnimator.