32

これを使用して ListView アイテムの削除をアニメーション化しようとしています:

    mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> adapterView, final View view, final int i, long l) {
            view.animate().setDuration(500).x(-view.getWidth()).alpha(0f);
            adapter.remove(tasks.get(i));
            adapter.notifyDataSetChanged();
        }
    });

それは動作しません。私は基本的に、この投稿の上部から 4 番目の回答のアドバイスに従いました。

Android ListView 行の追加または削除をアニメーション化する方法

ただし、アニメーションが発生している間、画面からスライドしたアイテムの下にあるアイテムも何らかの理由で削除されるため、面白い描画やリサイクルなどが行われています。質問者が最終的に正しいとマークした答えは、残念ながら Android のソース全体に対する RTFM です。私はそこに目を通しましたが、エミュレートしようとしている JellyBean に通知プルダウンが見つかりません。

ティア。ジョン

4

4 に答える 4

39

アイデア:ユーザーが行を選択したときにアニメーションを開始します。アニメーションが完了したら、アダプタから行を削除します。次のコードは、選択した行をアニメーション化します。

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    final ListView listView = (ListView) findViewById(R.id.listView1);
    final ArrayList<String> values = new ArrayList<String>();
    values.add("Android");
    values.add("iPhone");
    values.add("WindowsMobile");
    values.add("Blackberry");
    values.add("Windows7");

    final ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
            android.R.layout.simple_list_item_1, android.R.id.text1, values);
    listView.setAdapter(adapter);

    final Animation animation = AnimationUtils.loadAnimation(this,
            R.anim.slide_out);
    animation.setAnimationListener(new AnimationListener() {
        @Override
        public void onAnimationStart(Animation animation) {
        }

        @Override
        public void onAnimationRepeat(Animation animation) {
        }

        @Override
        public void onAnimationEnd(Animation animation) {
            adapter.remove(adapter.getItem(selectedRow));
            adapter.notifyDataSetChanged();
        }
    });

    listView.setOnItemClickListener(new OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View view,
                int position, long id) {
            Toast.makeText(getApplicationContext(),
                    " " + values.get(position), Toast.LENGTH_LONG).show();
            view.startAnimation(animation);
            selectedRow = position;

        }

    });
}

slide_out.xmlファイル:

<?xml version="1.0" encoding="utf-8"?>
 <set xmlns:android="http://schemas.android.com/apk/res/android" >  
    <translate 
        android:fromYDelta="0%" 
        android:toYDelta="100%"  
        android:duration="@android:integer/config_mediumAnimTime"/>  
</set> 
于 2012-11-12T15:05:36.967 に答える
34

美しい解決策を見つけました: https://github.com/paraches/ListViewCellDeleteAnimation

ビデオはこちら: http://www.youtube.com/watch?v=bOl5MIti7n0

「パラチ」に感謝します;)

編集

Android バージョン 22.0.0 の時点で、 newandroid.support.v7.widget.RecyclerViewは の後継として利用できますListView。標準の追加/削除/更新アニメーションは、すぐに使用できます。ウィジェットのアニメーションも簡単にカスタマイズできます (カスタム アニメーションはほとんどありません)。

カスタム アイテム アニメーションが必要な場合は、 からListViewに切り替えることを強くお勧めします。RecyclerView

于 2013-03-31T15:32:18.713 に答える
4

Chet Haase が DevBytes ( https://www.youtube.com/watch?v=8MIfSxgSHIs )で指摘しているように、これはすべて機能しますが、transientState フラグを追加することを忘れないでください。

彼のコードから:

// Here's where the problem starts - this animation will animate a View object.
                    // But that View may get recycled if it is animated out of the container,
                    // and the animation will continue to fade a view that now contains unrelated
                    // content.
                    ObjectAnimator anim = ObjectAnimator.ofFloat(view, View.ALPHA, 0);
                    anim.setDuration(1000);
                    if (setTransientStateCB.isChecked()) {
                        // Here's the correct way to do this: if you tell a view that it has
                        // transientState, then ListView ill avoid recycling it until the
                        // transientState flag is reset.
                        // A different approach is to use ViewPropertyAnimator, which sets the
                        // transientState flag internally.
                        view.setHasTransientState(true);
                    }
                    anim.addListener(new AnimatorListenerAdapter() {
                        @Override
                        public void onAnimationEnd(Animator animation) {
                            cheeseList.remove(item);
                            adapter.notifyDataSetChanged();
                            view.setAlpha(1);
                            if (setTransientStateCB.isChecked()) {
                                view.setHasTransientState(false);
                            }
                        }
                    });
                    anim.start();
于 2013-06-03T11:12:18.553 に答える
1

ListView の更新時に上から下へのスライド アニメーションを使用しました。使用したコードは次のとおりです。

 adapter.notifyDataSetChanged();
 Animation animation = AnimationUtils.loadAnimation(
                    getApplication(), R.anim.slide_top_to_bottom);
 getListView().startAnimation(animation);
 getListView().setSelection(0);

および slide_top_to_bottom.xml (res/animフォルダ内に保存)

<?xml version="1.0" encoding="utf-8"?>

<set xmlns:android="http://schemas.android.com/apk/res/android"   android:interpolator="@android:anim/accelerate_interpolator">
<translate android:fromYDelta="-100%" android:toXDelta="0" android:duration="100" />
<alpha android:fromAlpha="0.0" android:toAlpha="1.0" android:duration="50" />
</set>

編集: これを試してください:

mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, final View view, final int i, long l) {

    ValueAnimator fader = ObjectAnimator.ofFloat(view, "alpha", 1, 0);
    AnimatorSet animation = new AnimatorSet();
    animation.addListener(new AnimatorListener() {
        @Override
        public void onAnimationStart(Animator animation) {

        }
        @Override
        public void onAnimationRepeat(Animator animation) {
        }
        @Override
        public void onAnimationEnd(Animator animation) {

        }
        @Override
        public void onAnimationCancel(Animator animation) {
        }
    });
    ((AnimatorSet) animation).play(fader);
    animation.setDuration(500);
    animation.start();
    adapter.remove(tasks.get(i));
    adapter.notifyDataSetChanged();
}
});
于 2012-09-26T06:25:31.437 に答える