2011-08-14 24 views
6

Próbuję animować nowe elementy w moim ListView. Mam stabilne id-y, więc dokładnie wiem, który element animować. Problem pochodzi z mechanizmu odtwarzania ListView. Wywołuję funkcję startAnimation w widoku, gdy wiem, że dostałem ostatnio wstawiony element. Ale wtedy widok został poddany recyklingowi, wypełniony różnymi danymi. Powoduje to wyświetlenie interfejsu użytkownika w niewłaściwym wierszu. W pewnym momencie widok zawierał właściwe dane, ale potem został poddany recyklingowi. Potwierdziłem to za pomocą logcat. Czy istnieje sposób rozwiązania tego problemu?Animowane elementy listy w 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

Gdzie jesteś rozpoczęciem animacji? Myślę, że powinno to być na metodę getView() adaptera. – manelizzard

+0

Zaczynam tam. Kod dodany do pytania. – gmate

+0

Czy próbowałeś tworzyć nowe obiekty animacji za każdym razem, gdy "ustawiłeś" wiersz? Może dlatego, że używasz metody statycznej, zawsze odnosi się ona do tej samej animacji i zmienia się z jednego wiersza na drugi. – manelizzard

Odpowiedz

5

Animacja każdy dodany element metody getView swojej niestandardowej Adapter.

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; 
} 

I tym samym osiągnąć animację.

+2

, nigdy nie animuj w adapterze –

+9

@KorniltsevAnatoly więc gdzie i jak? –

1

Miałem podobny problem. Nie jestem w 100% pewien, czy to jest właściwa droga, ale możesz spróbować wyczyścić animację w widoku przed rozpoczęciem nowej, aby anulować resztki animacji z widoku z recyklingu. To mi pomogło.

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

Zapraszamy do obejrzenia biblioteki ListViewAnimations animować przedmioty ListView.

Zasadniczo, trzeba tylko dodać dwie kolejne linie mają swoje elementy animowane:

Przed:

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

Po:

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

+1 Naprawdę ładna biblioteka .Drobny niepokój, raz załadowany listview, muszę dodać dodatkowe elementy do wyświetlenia listy, gdy dodajesz dodatkowe elementy, potrzebuję animacji tych elementów (animuj tylko nowo dodane elementy podczas dodawania), czy ta pomoc jest dostępna w tej bibliotece? –

4

Jeśli używasz getView() prosty kod tutaj, (Nie ma potrzeby niestandardowej biblioteki)

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> 

referencyjny z tej strony: http://kylewbanks.com/blog/Implementing-Google-Plus-Style-ListView-Animations-on-Android

+1

Ta odpowiedź wymaga +1000 upomnień ... – Noman

Powiązane problemy