AndroidのListViewでアニメーションしながらセルを増やす

前回はセルを消したので、今回はセルを増やしてみた。

けど、セルを縮まった状態から大きくしてっていうのはどうにもうまくいかなかった。
結局ちょっと違う気がするけど、Stack Overflow で見つけた Bitmap を作ってそれをずらす方法にした。


[2013/03/15 updated]
引っ張って更新もやってみたよ!

Bitmapを作成して貼り付けてずらすとそれっぽい

昨日のセルを縮めるのと同じ様にアニメーションさせようとしたのだけど、どうしてもチラっと挿入後の画面が表示されてからアニメーションになってしまう…。
notifyDataSetChanged() して getView で返す View はちゃんと縮んだものを渡してるんだけどな〜。


というわけで、他の方法を探したら Stack Overflow でこんなん見つけた。

ここの一番下にある方法がこんな感じ

1. ListView の上に ListView をコピーした Bitmap を被せる。
2. ListView に新しいセルを Adapter.insert(cell, 0);
3. ListView の内容はセルが増えた内容になる。
4. 1.で ListView に被せた Bitmap を1行分下へアニメーション。
5. アニメーションが終わったら Bitmap を廃棄。


実際にやってみたのは、被せる Bitmap は ImageView として最初から Layout に置いておいて View.GONE で見えなくしておく。
で、ListView の Bitmap のコピーを ImageView にセットしたら View.VISIBLE で見える様にする。
アニメーションが終わったら、また View.GONE で見えなくしてる。


コードにするとこんな感じ。

private void addNewCell(MyCell cell) {
	Bitmap bitmap = getListViewBitmap();
	final ImageView imageView = (ImageView) findViewById(R.id.bitmapImageView);
	imageView.setImageBitmap(bitmap);
//	imageView.setBackgroundDrawable(new BitmapDrawable(getResources(), bitmap));
	imageView.setVisibility(View.VISIBLE);

	View cellView = mListView.getChildAt(0);
	TranslateAnimation transanim = new TranslateAnimation(0, 0, 0, cellView.getHeight());
	transanim.setDuration(ANIMATION_DURATION);
	transanim.setAnimationListener(new AnimationListener() {
		@Override
		public void onAnimationEnd(Animation animation) {
			imageView.setVisibility(View.GONE);
		}
		@Override public void onAnimationRepeat(Animation animation) {}
		@Override public void onAnimationStart(Animation animation) {}
	});

	mMyAnimListAdapter.insert(cell, 0);
	imageView.startAnimation(transanim);
}

private Bitmap getListViewBitmap() {
	mListView.setDrawingCacheEnabled(true);
	Bitmap bitmap = mListView.getDrawingCache();
	Bitmap bitmap1 = Bitmap.createBitmap(bitmap);
	mListView.setDrawingCacheEnabled(false);
	return bitmap1;
}

今回は ListView の一番上にのみセルを増やすことを考えているので、セルを増やす位置は常に 0番目。
なので、上から下へのアニメーションだけ考えれば良いけど、任意の位置に入れる時は下から上のアニメーションも用意しないといけない。(1番下に挿入の時用)


ところで、オリジナルのコードもここにあるコードも、どちらも取得できる Bitmap は背景が抜けているものになる。
なのでそのままでアニメーションすると、背景にある新しい状態の ListView が見えながら被さっている ImageView が移動するのでとっても間抜け。
どうやったら背景まで含めて Bitmap を作れるのかわからなかったので、結局 ImageView の背景を #ffececec で塗りつぶしてしまった…。
そしたら ListView の背景って画面上部と下部で微妙にグラデーションかかってて違うみたいで、切り替わりの時に若干の明るさの違いが気になるかもしれない。


というわけで、出来上がったセルを加えるアニメーション。

まぁそれっぽくは見えるかな。


サンプルのコードは GitHub に置いておいた。