Анимировать элементы списка в ListView - PullRequest
7 голосов
/ 14 августа 2011

Я пытаюсь анимировать новые элементы в моем ListView.У меня есть стабильные идентификаторы, поэтому я точно знаю, какой элемент нужно анимировать.Проблема заключается в механизме утилизации ListView.Я вызываю startAnimation для View, когда знаю, что получил недавно вставленный элемент.Но затем представление было переработано, заполнено различными данными.Это приводит к тому, что пользовательский интерфейс анимирует не ту строку.В какой-то момент представление содержало правильные данные, но затем было переработано.Я подтвердил это через logcat.Есть ли способ решить эту проблему?

РЕДАКТИРОВАТЬ:

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

Ответы [ 4 ]

5 голосов
/ 26 марта 2015

Если вы используете простой код 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

5 голосов
/ 20 января 2012

Анимируйте каждый добавленный элемент в методе 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;
}

И, таким образом, добиться анимации.

3 голосов
/ 01 августа 2013

Посмотрите библиотеку 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);
1 голос
/ 09 апреля 2013

У меня была похожая проблема. Я не уверен на 100%, если это правильный путь, но вы можете попробовать очистить анимацию в представлении перед запуском нового, чтобы отменить любую оставшуюся анимацию из переработанного представления. Это помогло мне.

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