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 :
- 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 .
- I do not want to use any library and maintain it.
- User can choose time interval to change wallpaper.
- 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