iOSのUITableViewのスワイプやセルの並び替えみたいな挙動をAndroidで実現するための「ListViewAnimations」というライブラリがあります。
下記のリポジトリに、ListViewAnimationsのDynamicListViewを実装したものを公開しておきました。GitHubの実装がそのままなのであまり参考にならないかもしれませんが、ダウンロードして実行すれば動きます。
ListViewAnimationsの導入
適当に作成したプロジェクトのapp/build.gradle
にListViewAnimations関係のライブラリを諸々追加しておきます。
dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) testCompile 'junit:junit:4.12' compile 'com.android.support:appcompat-v7:23.3.0' compile 'com.jakewharton:butterknife:6.1.0' compile 'com.nhaarman.listviewanimations:lib-core:3.1.0@aar' compile 'com.nhaarman.listviewanimations:lib-manipulation:3.1.0@aar' compile 'com.nhaarman.listviewanimations:lib-core-slh:3.1.0@aar' compile 'com.nineoldandroids:library:2.4.0' }
MainActivity#onCreate(Bundle)
でlistViewに対してAdapterを設定します。
/* Setup the adapter */ listAdapter = new ListAdapter(this); SimpleSwipeUndoAdapter simpleSwipeUndoAdapter = new SimpleSwipeUndoAdapter(listAdapter, this, new OnDismissCallback() { @Override public void onDismiss(@NonNull ViewGroup listView, @NonNull int[] reverseSortedPositions) { } }); AlphaInAnimationAdapter animAdapter = new AlphaInAnimationAdapter(simpleSwipeUndoAdapter); animAdapter.setAbsListView(listView); assert animAdapter.getViewAnimator() != null; animAdapter.getViewAnimator().setInitialDelayMillis(300); listView.setAdapter(animAdapter); /* Enable drag and drop functionality */ listView.enableDragAndDrop(); listView.setDraggableManager(new TouchViewDraggableManager(R.id.list_row_draganddrop_touchview)); listView.setOnItemMovedListener(new OnItemMovedListener() { @Override public void onItemMoved(int originalPosition, int newPosition) { // リストの並び替え後に実行される } }); listView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() { @Override public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) { if (listView != null) { listView.startDragging(position); return true; } return false; } });
OnItemMovedListener#onItemMoved(int,int)
はリストでの並び替え後に実行されます。ここでは何も処理していませんが、実際のアプリ開発ではこのタイミングでデータベースを書き換えると良いかもしれません。
セルを長押しして(ホールドして)、ドラッグアンドドロップでセルを移動させることができるようになりました。
トラブルシューティング
導入にあたって大きな問題のないListViewAnimationsですが、GitHubの指定通りに実装していると実行時にクラッシュしてしまいました。
D/Error: ERR: stack=java.lang.NoClassDefFoundError: Failed resolution of: [Lcom/nineoldandroids/animation/Animator; at com.nhaarman.listviewanimations.appearance.AnimationAdapter.animateViewIfNecessary(AnimationAdapter.java:174) at com.nhaarman.listviewanimations.appearance.AnimationAdapter.getView(AnimationAdapter.java:145) at android.widget.AbsListView.obtainView(AbsListView.java:2347) at android.widget.ListView.measureHeightOfChildren(ListView.java:1270) at android.widget.ListView.onMeasure(ListView.java:1182) at android.view.View.measure(View.java:17547) at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5535) at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1436)
GitHubのページに書いている通りだと内部的に使用しているライブラリが足りていないみたいです。app/build.gradle
にcom.nineoldandroids:libraryを追加しておく必要があります。
dependencies { // ... compile 'com.nhaarman.listviewanimations:lib-core:3.1.0@aar' compile 'com.nhaarman.listviewanimations:lib-manipulation:3.1.0@aar' compile 'com.nhaarman.listviewanimations:lib-core-slh:3.1.0@aar' compile 'com.nineoldandroids:library:2.4.0' }