2011-08-14 90 views
6

我嘗試在ListView中爲新項目添加動畫。我有穩定的id-s,所以我確切知道哪個元素需要動畫。問題來自ListView的回收機制。當我知道我有最近插入的元素時,我在視圖上調用startAnimation。但隨後,視圖得到了回收,充滿了不同的數據。 結果在用戶界面動畫錯誤的行。在某個時候,該觀點持有正確的數據,但隨後被回收。我通過logcat證實了這一點。 有什麼辦法可以解決這個問題嗎?在ListView中動畫列表項目

編輯:

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

你在哪裏開始的動畫?我認爲它應該在Adapter的getView()方法上。 – manelizzard

+0

我確實從那裏開始。代碼添加到問題中。 – gmate

+0

每次「設置」行時,您是否嘗試過創建新的動畫對象?也許因爲你使用的是靜態方法,它總是引用相同的動畫,並且它從一行變到另一行。 – manelizzard

回答

5

動畫在定製適配器的getView方法各添加元素。

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

從而實現動畫。

+2

不適配器 –

+9

@KorniltsevAnatoly所以在哪裏以及如何不斷動畫? –

1

我有類似的問題。我不是100%確定這是否是正確的方法,但您可以嘗試清除視圖上的動畫,然後再開始新動畫以從回收視圖中取消剩餘的動畫。這幫助了我。

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

看看ListViewAnimations庫來激活你的ListView項目。

基本上,你只需要添加兩行有你的項目的動畫:

前:

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

後:

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

+1真的很好庫。小的關注,一旦列表視圖加載,我需要添加額外的項目列表視圖,添加額外的項目時,我需要這些項目進行動畫(添加動畫只有新添加的項目),在這個庫中是否支持? –

4

如果使用getView()的簡單這裏的代碼, (不需要定製庫)

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> 

從這個網站參考:http://kylewbanks.com/blog/Implementing-Google-Plus-Style-ListView-Animations-on-Android

+1

這個答案需要+1000 upvotes ... – Noman