Reputation: 1657
I have listview at which I am trying to implement an async task that loads the image into the view inside the getView method of my adapter. I have succeeded in creating this however my problem is that since in the listview and the adapter the view gets recycled, there is a short period of time when the user scrolls the listview that the imageView located in the layout shows the image of the view at a previous position. It then shows the correct image. I have tried setting the imageView bitmap to null inside the getView method before the async task is called but it still behaves the same. How do I load an image into a view using an async task without having the previous image shown before the image is finished loading?
Upvotes: 2
Views: 3033
Reputation: 8357
I had the same problem, then I started using Square's Picasso , it's very simple and handles imageview recycling perfectly!
Upvotes: 1
Reputation: 720
In your adapter, you need to use a ViewHolder (to recycle views effectively) and set a tag (on the view) to bind the view to the correct image. You already know the position in the getView(...) callback.
Upvotes: 0
Reputation: 4220
hey follow few step to download image from server and show in your list view
Step 1. make this class in your project
OnImageDownloaded.java
public class OnImageDownloaded {
public OnImageDownloaded() {
try {
if (Environment.getExternalStorageState().equals(
Environment.MEDIA_MOUNTED)) {
File file = new File(Environment.getExternalStorageDirectory()
.getAbsolutePath() + File.separator + "your_Dir_name");
if (file.mkdirs()) {
}
} else {
Log.e("testing", "External Directory is not mounted");
}
} catch (Exception e) {
e.printStackTrace();
}
}
public void downloadTheImages(ArrayList<String> imageUrls) {
try {
new downloadingTheImages(imageUrls).execute();
} catch (Exception e) {
e.printStackTrace();
}
}
class downloadingTheImages extends AsyncTask<Void, Void, Void> {
ArrayList<String> imageUrls;
public downloadingTheImages(ArrayList<String> imageUrls) {
this.imageUrls = imageUrls;
}
@Override
protected Void doInBackground(Void... params) {
try {
for (int i = 0; i < imageUrls.size(); i++) {
if (imageUrls.get(i).equals("0")) {
} else
downloadTheImageIfRequired(imageUrls.get(i));
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
public void downloadTheImageIfRequired(String imageName) {
try {
String dirPath = Environment.getExternalStorageDirectory()
.getAbsolutePath()
+ File.separator
+ "your_Dir_name"
+ File.separator;
String CompleteFilePath = dirPath + imageName;
File f = new File(CompleteFilePath);
if (f.exists()) {
} else {
URL url = new URL(
"http image URL ::"
+ imageName);
URLConnection conexion = url.openConnection();
conexion.connect();
InputStream input = new BufferedInputStream(url.openStream());
OutputStream output = new FileOutputStream(CompleteFilePath);
byte data[] = new byte[1024];
int count;
while ((count = input.read(data)) != -1) {
output.write(data, 0, count);
}
output.flush();
output.close();
input.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
Step 2.
Check out how you get that image
private class getImage extends AsyncTask<Void, Void, String> {
Dialog dialog;
String url;
@Override
protected void onPreExecute() {
super.onPreExecute();
}
@Override
protected String doInBackground(Void... params) {
url = getResources().getString(R.string.baseurl) + "getNews";
JSONParser jParser = new JSONParser();
String json = jParser.getJSONFromUrl(url);
try {
JSONObject jobject = new JSONObject(json);
Log.e("testing", "url: " + url + " " + json);
int success = jobject.getInt("success");
Log.e("testing", "json length" + jobject.length());
for (int i = 0; i < jobject.length() - 1; i++) {
JSONObject jobj = jobject
.getJSONObject(Integer.toString(i));
if (success == 1) {
HashMap<String, String> hm = new HashMap<String, String>();
ArrayList<String> tempAl1 = new ArrayList<String>();
tempAl1.add(jobj.getString("image"));
if (tempAl1.size() > 0) {
new OnImageDownloaded().downloadTheImages(tempAl1);
}
Log.e("test", "image" + jobj.getString("image"));
hm.put(image, jobj.getString("image"));
aldata.add(hm);
}
}
} catch (JSONException e) {
e.printStackTrace();
}
return null;
}
@Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
if (dialog != null)
if (dialog.isShowing())
dialog.dismiss();
Custom_Adapter adapter = new Custom_Adapter (
(Activity) context, aldata);
lv.setAdapter(adapter);
}
}
Step 3.
Show that image in your adapter like this
call these methods in your getview in adaper
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = convertView;
view = null;
if (view == null) {
LayoutInflater inflator = context.getLayoutInflater();
view = inflator.inflate(R.layout.news_view, null);
final ViewHolder viewHolder = new ViewHolder();
initAll(view, viewHolder);
view.setTag(viewHolder);
}
ViewHolder holder = (ViewHolder) view.getTag();
fillAll(holder, position);
return view;
}
public void fillAll(final ViewHolder holder, final int position) {
String dirPath = Environment.getExternalStorageDirectory()
.getAbsolutePath()
+ File.separator
+ "your_Dir_name"
+ File.separator;
String CompleteFilePath = dirPath + allData.get(position).get("image");
File f = new File(CompleteFilePath);
if (f.exists()) {
Log.e("testingTag", "if part");
holder.ivimage.setVisibility(View.VISIBLE);
catchOutOfMemory(holder.ivimage, CompleteFilePath);
} else {
Log.e("testingTag", "else part");
holder.ivimage.setVisibility(View.GONE);
}
Log.e("test", "image" + allData.get(position).get("image"));
}
void catchOutOfMemory(ImageView iv, String path) {
try {
iv.setImageURI(Uri.parse(path));
} catch (OutOfMemoryError e) {
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 8;
Bitmap preview_bitmap = BitmapFactory.decodeFile(path, options);
iv.setImageBitmap(preview_bitmap);
}
}
thats all thanks
Upvotes: 1