2011-08-14 17 views
6

ListViewで新しい項目をアニメーション化しようとしました。安定したid-sがあるので、どの要素をアニメーション化するか正確に分かります。問題は、ListViewのリサイクルメカニズムから発生します。最近挿入された要素があることがわかったら、ViewでstartAnimationを呼び出します。しかし、その後、ビューはリサイクルされ、異なるデータで満たされました。 UIが誤った行にアニメーション表示されます。ある時点で、ビューは適切なデータを保持していましたが、リサイクルされました。私はlogcat経由でこれを確認しました。 これを解決する方法はありますか?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

?私はそれがアダプタの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メソッドを使用する場合は()シンプル

基本的に、あなただけのあなたの項目がアニメーション持っているために、2つの以上の行を追加する必要がありますコードはこちら (カスタムライブラリは不要)

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

関連する問題