2011-08-14 24 views
6

Intento animar nuevos elementos en mi ListView. Tengo id-s estable, así que sé exactamente qué elemento animar. El problema proviene del mecanismo de reciclaje de ListView. Llamo a startAnimation en la vista cuando sé que tengo un elemento insertado recientemente. Pero luego, la vista se recicló y se llenó de datos diferentes. Resulta en la interfaz de usuario que anima la fila incorrecta. En algún momento, la vista contenía los datos correctos, pero luego se recicló. Confirmé esto a través de Logcat. ¿Hay alguna manera de resolver esto?Animar elementos de la lista en ListView

EDIT:

public ExpensCursorAdapter(Context context, Cursor c, boolean autoRequery, 
     CopyOnWriteArraySet<String> fadeAnimateTags) { 
    super(context, c, autoRequery); 
    this.mFadeAnimTags = fadeAnimateTags; 
} 

@Override 
public boolean hasStableIds() { 
    return true; 
} 

@Override 
public void bindView(View view, Context context, Cursor cursor) { 
    setup(view, context, cursor); 
} 

private void setup(View view, Context context, Cursor cursor) { 
    final String id = cursor.getString(4); 
    if (LOCAL_LOGV) Log.v(TAG, String.format("Create item for %s. Received view: %s", id, view.toString())); 
    view.setTag(id); 
    final TextView dateText = (TextView) view.findViewById(R.id.date); 
    final TextView timeText = (TextView) view.findViewById(R.id.time); 
    final TextView title = (TextView) view.findViewById(R.id.title); 
    final TextView amount = (TextView) view.findViewById(R.id.amount); 
    final Date date = new Date(cursor.getLong(0)); 
    title.setText(cursor.getString(1)); 
    dateText.setText(dFormat.format(date)); 
    timeText.setText(tFormat.format(date)); 
    amount.setText(String.format("%d Ft", cursor.getInt(2))); 
    if (cursor.getInt(3) == 1) { 
     timeText.setTextColor(Color.LTGRAY); 
     title.setTextColor(Color.LTGRAY); 
     dateText.setTextColor(Color.LTGRAY); 
     amount.setTextColor(Color.LTGRAY); 
    } else { 
     timeText.setTextColor(Color.BLACK); 
     title.setTextColor(Color.BLACK); 
     dateText.setTextColor(Color.BLACK); 
     amount.setTextColor(Color.BLACK); 
    } 
    if (mFadeAnimTags.contains(id)) { 
    view.setAnimation(AnimationUtils.loadAnimation(context, R.anim.fade)); 
    mFadeAnimTags.remove(id); 
    } 

} 

@Override 
public View newView(Context context, Cursor cursor, ViewGroup parent) { 
    final LayoutInflater inflater = LayoutInflater.from(context); 
    View view = inflater.inflate(R.layout.expense_list_item, parent, false); 
    setup(view, context, cursor); 
    return view; 
} 
+0

Dónde ¿Estás comenzando la animación? Creo que debería estar en el método getView() del Adaptador. – manelizzard

+0

empiezo allí. Código agregado a la pregunta. – gmate

+0

¿Ha intentado crear nuevos objetos de animación cada vez que "configura" la fila? Tal vez porque está utilizando un método estático, siempre hace referencia a la misma animación y cambia de una fila a otra. – manelizzard

Respuesta

5

animar cada elemento añadido en el método getView de su adaptador personalizado.

public View getView(int position, View convertView, ViewGroup parent) { 

    View v = convertView; 

    if (v == null) { 
     LayoutInflater vi = (LayoutInflater) getActivity() 
      .getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
     v = vi.inflate(R.layout.simple_list_item_1, null); 
    } 

    ListData o = list.get(position); 
    TextView tt = (TextView) v.findViewById(R.id.toptext); 

    tt.setText(o.content); 

    Log.d("ListTest", "Position : "+position); 

    if(flag == false) { 
     Animation animation = AnimationUtils.loadAnimation(getActivity(), R.anim.slide_top_to_bottom); 
     v.startAnimation(animation); 
    } 
    return v; 
} 

Y así lograr la animación.

+2

no anime nunca en el adaptador –

+9

@KorniltsevAnatoly ¿dónde y cómo? –

1

Tuve un problema similar. No estoy 100% seguro de si este es el camino correcto, pero puedes intentar borrar la animación de la vista antes de comenzar una nueva para cancelar cualquier animación sobrante de la vista reciclada. Esto me ayudó.

if(flag == false) { 
    v.clearAnimation(); 
    Animation animation = AnimationUtils.loadAnimation(getActivity(), R.anim.slide_top_to_bottom); 
    v.startAnimation(animation); 
} 
3

Tener un vistazo a la biblioteca ListViewAnimations para animar a sus elementos de ListView.

Básicamente, sólo se tendría que agregar dos líneas más para tener sus elementos animados:

Antes:

MyListAdapter mAdapter = new MyListAdapter(this, getItems()); 
getListView().setAdapter(mAdapter); 

Después:

MyListAdapter mAdapter = new MyListAdapter(this, getItems()); 
AlphaInAnimationAdapter alphaInAnimationAdapter = new AlphaInAnimationAdapter(mAdapter); 
alphaInAnimationAdapter.setAbsListView(getListView()); 
getListView().setAdapter(alphaInAnimationAdapter); 
+0

+1 Biblioteca realmente agradable. Pequeña preocupación, una vez que listview cargó, necesito agregar elementos adicionales para mostrar, al agregar elementos adicionales, necesito que los elementos sean animados (animar solo los elementos recién agregados al agregarlos), ¿eso admite en esta biblioteca? –

4

Si utiliza getView() sencilla código aquí, (No necesita biblioteca personalizada)

private int lastPosition = -1; 

@Override 
public View getView(int position, View convertView, ViewGroup parent) { 
//Load your view, populate it, etc... 
View view = ...; 

Animation animation = AnimationUtils.loadAnimation(getContext(), (position > lastPosition) ? R.anim.up_from_bottom : R.anim.down_from_top); 
view.startAnimation(animation); 
lastPosition = position; 

return view; 
} 

up_from_bottom.xml

<?xml version="1.0" encoding="utf-8"?> 
<set xmlns:android="http://schemas.android.com/apk/res/android" 
android:shareInterpolator="@android:anim/decelerate_interpolator"> 
<translate 
    android:fromXDelta="0%" android:toXDelta="0%" 
    android:fromYDelta="100%" android:toYDelta="0%" 
    android:duration="400" /> 
</set> 

down_from_bottom.xml

<?xml version="1.0" encoding="utf-8"?> 
<set xmlns:android="http://schemas.android.com/apk/res/android" 
android:shareInterpolator="@android:anim/decelerate_interpolator"> 
<translate 
    android:fromXDelta="0%" android:toXDelta="0%" 
    android:fromYDelta="-100%" android:toYDelta="0%" 
    android:duration="400" /> 
</set> 

Referencia de este sitio: http://kylewbanks.com/blog/Implementing-Google-Plus-Style-ListView-Animations-on-Android

+1

Esta respuesta necesita +1000 votos positivos ... – Noman

Cuestiones relacionadas