In any programming language a same goal can be achieved through many ways . I am going to discuss how to replace a countdown timer with handler for changing images dynamically on android .

What I needed was the following :

  1. I have  android assets folder with several images and I want to load  every time a different image from this  to  one of my ImageViews of application .
  2. I do not want to use any library and maintain it.
  3. User can choose time interval to change wallpaper.
  4. Clicking on image slideshow should close the activity

 

Using a countdown timer we can load  random images  into a ImageView for indefinite period of time . I was using countdown timer something like below for the same .

In OnCreate method

//set full screen  wallpaper   and hide including nav bar and status bar

requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().getDecorView().setSystemUiVisibility(
 View.SYSTEM_UI_FLAG_LAYOUT_STABLE
         | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
         | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
         | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
         | View.SYSTEM_UI_FLAG_FULLSCREEN
         | View.SYSTEM_UI_FLAG_IMMERSIVE);


 setContentView(R.layout.activity_wallpaper);

 

//get images from assets sub directory “visuals”  and adding to a array list

AssetManager assetManager = getAssets();


try {
    String[] imgPath = assetManager.list("visuals");
    mlist  = new ArrayList<>();

    for (int i = 0; i< imgPath.length; i++) {
     mlist.add(imgPath[i]); 
  
}



imageSlider = (ImageView) findViewById(R.id.imageslider);
changeimage(imageslider);


//Close the wallpaper activity if user clicks on imageview
imageSlider.setOnClickListener(new View.OnClickListener() {

    public void onClick(View v) {
//clicking on wallpaper image should close the activity
       finish();
    }
});



//getting duration from preferences
//default time interval is 3 seconds 
//user is allowed to set more than 3 seconds.
              time = 3000;
 MyPrefManager pref = new MyPrefManager(getApplicationContext()); 

            if ((int) TimeUnit.SECONDS.toMillis(pref.getWallpaperTimer()) > 0){

                 time = (int) TimeUnit.SECONDS.toMillis(pref.getWallpaperTimer());


            }

Now this is the time to choose wether to use countdown timer or handler.

I was using countdown timer with this following method .

ct = new CountDownTimer(time,1000)
{
int i=0;
@Override
public void onTick(long millisUntilFinished) {}
@Override public void onFinish() {
changeimage(imageslider);
i++;
if(i== mlist.size()-1) i=0; start(); }
}.start();

 

//Always cancle the timer when activity stops. 

   @Override
 public void onStop() {
super.onStop();
if (ct!=null) {
ct.cancel();
 ct = null;
 }
}
 Above countdown timer creates a new thread . So for changing a images ( UI related) we do not want 
to use a new thread instead , we use handler which runs on main thread.
You can replace countdowntimer with handler like below.

 h = new Handler();
    r = new Runnable() {
        @Override
        public void run() {

            changeimage(imageslider);
            h.postDelayed(this, time);
        }
    };
    h.post(r);
    

} catch (IOException e) {
    Log.e("sreekanth", e.getMessage());
}

@Override

public void onStop() {

super.onStop();

h.removeCallbacks(r);

}

 

 



I am using glide to load images . By default Glide uses  RGB_565 (16 bit depth)
which may reduce image quality . To load original image with glide, I ma using PREFER_ARGB_8888 option.
Also note that I shuffle the image array list to get a real random image every time.
private void changeImage(ImageView iv) {

//shuffle the list to get random image
   Collections.shuffle(mlist);

    final Context context = getApplication().getApplicationContext();

    if (isValidContext(context)) {
        Glide.with(getApplicationContext())
                .load(Uri.parse("file:///android_asset/visuals/" + mlist.get(0)))
                //keep glide image quality best
                .format(DecodeFormat.PREFER_ARGB_8888)
                .override(Target.SIZE_ORIGINAL)
                .into(iv);



    }

public static boolean isValidContext(final Context context) {
    if (context == null) {
        return false;
    }
    if (context instanceof Activity) {
        final Activity activity = (Activity) context;
        if (activity.isDestroyed() || activity.isFinishing()) {
            return false;
        }
    }
    return true;
}

 

 


0 Comments

Leave a Reply

Your email address will not be published.