2011-08-14 6 views
6

내 ListView에서 새 항목에 애니메이션을 적용하려고합니다. 나는 id-s가 안정적이어서 어떤 요소가 움직일 지 정확히 알고있다. 문제는 ListView의 재활용 메커니즘에서 비롯됩니다. 내가 최근에 삽입 된 요소를 알고있는 경우 View에서 startAnimation을 호출합니다. 그런 다음보기가 재활용되어 다른 데이터로 채워집니다. 잘못된 행에 애니메이션을 적용하는 UI가 발생합니다. 어떤 시점에서보기는 올바른 데이터를 보유하고 있었지만 재활용되었습니다. 나는 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

당신이 애니메이션을 시작? 나는 그것이 어댑터의 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 정말 좋은 라이브러리. 추가 항목을 listview에 추가 할 때 항목을 추가 할 때 해당 항목을 애니메이션으로 추가해야합니다 (추가하는 동안 새로 추가 한 항목 만 애니메이션으로 표시).이 라이브러리에서 지원합니까? –

4

당신의 getView를 사용하는 경우() 간단한

기본적으로, 당신은 당신의 품목이 애니메이션이 두 개 라인을 추가해야 여기에 코드, (사용자 정의 라이브러리 필요 없음)

0 이 사이트에서
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