1

Working with ImageSwitcher in my app but I don't want the images to cross fade. I want to show one image then "fadeout" to black and "fadein" with the other image. But for some reason it keeps cross fading the two images. If any one could help I would greatly appreciate it.

Activity_intro.java

public class IntroActivity extends Activity implements ViewFactory {

    private static final String TAG = "IntroActivity";

    private final int[] images = { R.drawable.wheelpaper1, R.drawable.wheelpaper2};
    private int index = 0;
    private final int interval = 4000;
    private boolean isRunning = true;

    @Override
    public void onCreate(Bundle bundle) {
        super.onCreate(bundle);
        setContentView(R.layout.activity_intro);

        startAnimatedBackground();  

    }

    private void startAnimatedBackground() {
        Animation aniIn = AnimationUtils.loadAnimation(this,
                android.R.anim.fade_in);
        aniIn.setDuration(1500);
        Animation aniOut = AnimationUtils.loadAnimation(this,
                android.R.anim.fade_out);
        aniOut.setDuration(1500);

        final ImageSwitcher imageSwitcher = (ImageSwitcher) findViewById(R.id.imageSwitcher1);
        imageSwitcher.setInAnimation(aniIn);
        imageSwitcher.setOutAnimation(aniOut);
        imageSwitcher.setFactory(this);
        imageSwitcher.setImageResource(images[index]);

        final Handler handler = new Handler();
        Runnable runnable = new Runnable() {

            @Override
            public void run() {
                if (isRunning) {
                    index++;
                    index = index % images.length;
                    Log.d("Intro Screen", "Change Image " + index);
                    imageSwitcher.setImageResource(images[index]);
                    handler.postDelayed(this, interval);
                }
            }
        };
        handler.postDelayed(runnable, interval);

    }

    @Override
    public View makeView() {
        ImageView imageView = new ImageView(this);
        imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
        imageView.setLayoutParams(new ImageSwitcher.LayoutParams(
                LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
        return imageView;
    }

    @Override
    public void finish() {
        isRunning = false;
        super.finish();
    }
}
Barney
  • 2,355
  • 3
  • 22
  • 37
Warren0618
  • 93
  • 1
  • 7

1 Answers1

0

Well here's a suggestion.

I always find it helps to look to the source, see here for example.

You'll see that image switcher is really just a imageView specific view flipper. Now no methods are going to be exposed for what you want- it's not a terribly complex class.

So you could inherit from it to spin out your own- create a custom view and use that in your xml. I would suggest something like:

public class CustomImageSwitcher extends ImageSwitcher {

private Queue<Runnable> mAfterAnimationQueue = new LinkedList<Runnable>();

private final GradientDrawable blackDrawable; // just incase you want a gradient too...

public CustomImageSwitcher(Context context) {
    super(context);
    blackDrawable = new GradientDrawable(Orientation.BOTTOM_TOP, new int[] {
            getResources().getColor(android.R.color.black),
            getResources().getColor(android.R.color.black) }); 
}

public CustomImageSwitcher(Context context, AttributeSet attrs) {
    super(context, attrs);
    blackDrawable = new GradientDrawable(Orientation.BOTTOM_TOP,
            new int[] { getResources().getColor(android.R.color.black) });
}

public void postAfterAnim(Runnable runnable) {
    mAfterAnimationQueue.add(runnable);
}

protected void onFadeToBlackEnded() {
    while (!mAfterAnimationQueue.isEmpty()) {
        mAfterAnimationQueue.remove().run();
    }
}

private Animation.AnimationListener biDirectionalCustomListener = new AnimationListener() {

    @Override
    public void onAnimationEnd(Animation animation) {
        onFadeToBlackEnded();
        animation.reset();
    }

    @Override
    public void onAnimationRepeat(Animation animation) {
        ; // we only really want the end event!
    }

    @Override
    public void onAnimationStart(Animation animation) {
        ;
    }
};

// THIS ISN'T A COMPLETED EXAMPLE AS THIS WOULD UNSET ANY PREVIOUS ANIMATION
// LISTENERS
@Override
public void setInAnimation(Animation inAnimation) {
    inAnimation.setAnimationListener(biDirectionalCustomListener);
    super.setInAnimation(inAnimation);
}

// THIS ISN'T A COMPLETED EXAMPLE AS THIS WOULD UNSET ANY PREVIOUS ANIMATION
// LISTENERS
@Override
public void setOutAnimation(Animation outAnimation) {
    outAnimation.setAnimationListener(biDirectionalCustomListener);
    super.setOutAnimation(outAnimation);
}

// override the image switcher's methods

@Override
public void setImageResource(final int resid) {
    super.setImageDrawable(blackDrawable);
    postAfterAnim(new Runnable() {
        @Override
        public void run() {
            CustomImageSwitcher.super.setImageResource(resid);
        }
    });
}

// obviously override more if you want.... just change the method name

}

This is a bit of a late night sketch- some problems are that we don't properly proxy the animation coming in (you should or at least make it very clear it will be unset).

But the rough idea is that what you really want is to have an intermediate view in the view flipper that holds a simple black drawable and is an intermediary stage. Hope it is self explanatory.

On another note, in your example you might want to pull out a few of the objects you create per method and have them as fields as you're going to use them everytime- e.g. Handler.

As a final note, I really don't like using view flipper like this. You might find you can do everything with one image view if you override onDraw etc., but that's the start of another question, and not the end of this one.

Best wishes, hope this helps.

Tom
  • 1,773
  • 15
  • 23