After a brutal day of running into many Android bugs and
misdocumentations, I’ve finally figured out how to create a slideshow of
images for Android, with each imaging fading to the next. This is not
unlike AnimationDrawable, except with a smoother and slower transition between images.
First, you need a resource file with something like this in it. The FrameLayout is the clever bit: it stacks everyone of its children on top of each other.
First, you need a resource file with something like this in it. The FrameLayout is the clever bit: it stacks everyone of its children on top of each other.
<FrameLayout android:id="@+id/frame" android:layout_width="wrap_content" android:layout_height="wrap_content" > <ImageView android:id="@+id/slide_1" android:layout_gravity="center_vertical" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <ImageView android:id="@+id/slide_2" android:layout_gravity="center_vertical" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </FrameLayout>Then you need code that looks like this:
public class TopListActivity extends Activity { private static class AnimationAlphaTimer extends TimerTask implements Animation.AnimationListener { TopListActivity topList; Vector<BitmapDrawable> images; int count = 0; public AnimationAlphaTimer(TopListActivity _topList) { this.topList = _topList; this.images = new Vector<BitmapDrawable>(); for (int i = 0; ; i++) { // LOAD IMAGES HERE } if (this.images.size() > 0) { this.topList.slide_0.setBackgroundDrawable(this.images.get(0)); if (this.images.size() > 1) { this.topList.slide_1.setBackgroundDrawable(this.images.get(1)); } } this.count = 1; } public void launch() { if (this.images.size() >= 2) { (new Timer(false)).schedule(this, 100); } } @Override public void run() { this.doit(); this.cancel(); } private void doit() { if ((this.count % 2) == 0) { AlphaAnimation animation = new AlphaAnimation(1.0f, 0.0f); animation.setStartOffset(3000); animation.setDuration(3000); animation.setFillAfter(true); animation.setAnimationListener(this); this.topList.slide_1.startAnimation(animation); } else { AlphaAnimation animation = new AlphaAnimation(0.0f, 1.0f); animation.setStartOffset(3000); animation.setDuration(3000); animation.setFillAfter(true); animation.setAnimationListener(this); this.topList.slide_1.startAnimation(animation); } } public void onAnimationEnd(Animation animation) { if ((this.count % 2) == 0) { this.topList.slide_1.setBackgroundDrawable( this.images.get((this.count + 1) % (this.images.size())) ); } else { this.topList.slide_0.setBackgroundDrawable( this.images.get((this.count + 1) % (this.images.size())) ); } this.count++; this.doit(); } public void onAnimationRepeat(Animation animation) { } public void onAnimationStart(Animation animation) { } } @Override public void onResume() { super.onResume(); (new AnimationAlphaTimer(this)).launch(); } }The “create a Timer trick” in
onResume
is courtesy of Diego Torres. If you just try to run the animation, it’s likely just to choke
No comments:
Post a Comment