As iPhone developer Learning android development is bit difficult in understanding. Same thing I found when I was trying to create and use AsyncImageView in my project.
So there is few things seems much promising like or AQuery or LoopJ Smart Image View.
But I don’t like the way everything is treated out of the box. We should have something which we can control anytime and easily. Everything should be handled in one class. So I tried in my way to develop something that can be understandable easily. Simply I have extended FrameLayout and named it as AsyncImageView. Then I have added ImageView and ProgressBar.
Though I have used loopj to download image. here is snippets:
package com.logistic.async; import java.io.File; import java.io.InputStream; import org.apache.http.Header; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.util.AttributeSet; import android.util.Log; import android.view.Gravity; import android.view.View; import android.view.ViewGroup; import android.widget.FrameLayout; import android.widget.ImageView; import android.widget.ImageView.ScaleType; import android.widget.ProgressBar; import com.logistic.magazine.restclient.LIRestClient; import com.loopj.android.http.FileAsyncHttpResponseHandler; public class AsyncImageView extends FrameLayout { private static final String TAG = AsyncImageView.class.getName(); ProgressBar progressBar; Context c; InputStream input; public ImageView imageView; String fileName; String URL; public String strDefaultImage; public AsyncImageView(Context context, AttributeSet attrs) { super(context, attrs); c = context; progressBar = new ProgressBar(c, null, android.R.attr.progressBarStyleSmall); FrameLayout.LayoutParams params = new FrameLayout.LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT, Gravity.TOP | Gravity.LEFT); imageView = new ImageView(c); imageView.setScaleType(ScaleType.FIT_CENTER); //imageView.setBackgroundColor(color.darker_gray); addView(imageView, params); // params = new FrameLayout.LayoutParams( ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT, Gravity.CENTER_VERTICAL | Gravity.CENTER_HORIZONTAL); addView(progressBar, params); progressBar.setVisibility(View.INVISIBLE); } public void setDefaultImage() { int resID = getResources().getIdentifier(strDefaultImage, "drawable", c.getPackageName()); imageView.setImageResource(resID); } public AsyncImageView(Context context) { this(context, null); } public void downloadImage(String url) { URL = url; Bitmap myBitmap = null; //System.out.println("helo this is url -> " + URL); fileName = url.substring(url.lastIndexOf('/') + 1, url.length()); File cacheDir = getContext().getExternalCacheDir(); File f = new File(cacheDir, fileName); if (f.exists()) { System.out.println("getting image from folder " + f); myBitmap = BitmapFactory.decodeFile(f.getAbsolutePath()); imageView.setImageBitmap(myBitmap); // return myBitmap; } else { System.out.println("getting image from url" + f); progressBar.setVisibility(View.VISIBLE); LIRestClient.downloadFile(url, null, new FileAsyncHttpResponseHandler(f) { @Override public void onSuccess(int statusCode, File file) { Log.i(TAG, "onClick onSuccess :" + statusCode); Bitmap myBitmap = BitmapFactory.decodeFile(file.getAbsolutePath()); imageView.setImageBitmap(myBitmap); progressBar.setVisibility(View.GONE); } @Override public void onProgress(int bytesWritten, int totalSize) { int totProgress = (bytesWritten * 100) / totalSize; if (totProgress > 0) { // Log.i(TAG, "totProgress: " + totProgress); } } @Override public void onFailure(int statusCode, Header[] headers, Throwable e, File response) { response.delete(); Log.i(TAG, "onClick onFailure :" + statusCode+" "+e.getLocalizedMessage()); e.printStackTrace(); progressBar.setVisibility(View.GONE); int resID = getResources().getIdentifier(strDefaultImage, "drawable", c.getPackageName()); imageView.setImageResource(resID); } }); } } }
Simply it first checks for image in Cache Directory of application. If image will be found it will show that image directly otherwise it will try to download image from url.
To use in the project we have to just declare in xml anywhare just like below and then just need to access object and call downloadImage function.
<com.logistic.async.AsyncImageView android:id="@+id/imageView1" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_below="@+id/etUrl" android:layout_marginTop="5dp" android:background="@android:color/darker_gray" />
async = (AsyncImageView) findViewById(R.id.imageView1); async.strDefaultImage = "no_image"; async.downloadImage("image url");
that’s it. here is github link to download working example source code.