If i have really big grid say with 500 items and i scroll really fast Glide asynch load obviously lags (that is the as expected) , but as soon as scrolling stops Glide tries to load urls in the one grid cell one by one multiple times.
I am sure there is elegant solution that you can suggest and pardon my ignorance here.
One idea was to use viewholder and set a position variable which can be checked by glide each time before loading.but i am not sure where i can do that in Glide , in requestlistener?
thanks for help
Thanks for the report! Can you paste the line(s) of the code you're using to load images with Glide? In theory Glide does cancel old loads before starting new ones, so it's definitely a bug in the current implementation if you're seeing multiple images being loaded into a single view on top of each other after you stop scrolling.
A code sample or failing test case would also be super helpful, though I know that's more time consuming to do.
Hi Sam ,
Thanks for quick response.
I double checked stuff and ended up making a simple sample project and used Glide for gridview with 500 images (200x200) .I am attaching here the whole project.
As long as i scroll gradually there are obviously no issues, but when i fling very fast (couple of times) gridview reaches the end of image list and starts loading multiple images in each view which is on screen.
I tried doing tests on WIFI and Mobile data but i guess it doesnt matter after the first run after which images are already cached.
some Code here:
MyActivity.java
package com.example.Demo;
import android.app.Activity;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.GridView;
import android.widget.ImageView;
import com.bumptech.glide.Glide;
import java.util.HashMap;
public class MyActivity extends Activity {
/**
* Called when the activity is first created.
*/
private HashMap<Integer, String> imagebucket = new HashMap<Integer, String>();
private LayoutInflater layoutInflater ;//= getLayoutInflater();
private TestAdapter testAdapter;
GridView gridView;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.test);
testAdapter=new TestAdapter();
layoutInflater=getLayoutInflater();
gridView = (GridView) findViewById(R.id.grid1);
gridView.setAdapter(testAdapter);
// testAdapter.notifyDataSetChanged();
}
public class TestAdapter extends BaseAdapter {
@Override
public int getCount() {
return urls.length;
}
@Override
public Object getItem(int position) {
return urls[position];
}
@Override
public long getItemId(int position) {
return 0;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View tempView = convertView;
ViewHolder viewHolder;
if (tempView == null) {
viewHolder = new ViewHolder();
tempView = (ViewGroup) layoutInflater.inflate(R.layout.test_item, parent, false);
ImageView imageView = (ImageView) tempView.findViewById(R.id.gridcell);
ViewGroup.LayoutParams params = imageView.getLayoutParams();
int height = ((GridView) parent).getColumnWidth();
params.width = height;
params.height = height;
viewHolder.imageView = imageView;
tempView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) tempView.getTag();
}
String url = (String) getItem(position);
viewHolder.imageView.setTag(position);
if (url != null)
Glide.load(url).placeholder(R.drawable.ic_placeholder).centerCrop().into(viewHolder.imageView);
return tempView;
}
}
public static class ViewHolder {
ImageView imageView;
}
private String [] urls={"" };
//Cleared the URLS as they are not mine.But i have 500 images here of average size 200x200
}
test_item.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent" android:id="@+id/gridcell"
android:background="@android:color/background_dark"/>
</LinearLayout>
test.xml (main layout)
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<GridView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="@+id/grid1"
android:gravity="center"
android:numColumns="3"
android:stretchMode="columnWidth"
android:verticalSpacing="1dp"
android:horizontalSpacing="1dp"
android:textFilterEnabled="false"
android:fastScrollAlwaysVisible="false"
android:clickable="false"/>
</RelativeLayout>
Thanks for the code, really helpful. The offending line is:
viewHolder.imageView.setTag(position);
Glide expects to be able to find some state in the tag of an image view it's loading images into. It's currently supposed to log a warning if it finds something other than its own data, but that doesn't appear to be working. Since failing to find the data causes things to be broken, I'm going to change the log line to an exception.
In the meantime you can fix this problem by not setting a tag on the image view you pass to glide. You can find a link to the complete sample project based on your code here: https://drive.google.com/folderview?id=0B438DjwLvMp6NkJWcEZjeGpHMk0&usp=sharing.
In the long run I'd love to use set tag with an id, but doing so now would prevent me from being able to release Glide as a jar and would require everyone to include it as a library project instead.
That did the trick !! .
Just on leaving it (setTag()) out for the users to track recycling or some flags, i was doing something similar when working with check-boxes to track multi-selects in listView, but that's not the only solution or scenario i am sure.
Raising an exception would be of great help.
Thanks for this real fast library and quick response and code.
Just pushed a commit to add the assertion. Thanks for the report and the code to help debug this, much appreciated!
@sjudd Realy nice solution! Could you explane principle of this operation more detail?
Most helpful comment
Thanks for the code, really helpful. The offending line is:
Glide expects to be able to find some state in the tag of an image view it's loading images into. It's currently supposed to log a warning if it finds something other than its own data, but that doesn't appear to be working. Since failing to find the data causes things to be broken, I'm going to change the log line to an exception.
In the meantime you can fix this problem by not setting a tag on the image view you pass to glide. You can find a link to the complete sample project based on your code here: https://drive.google.com/folderview?id=0B438DjwLvMp6NkJWcEZjeGpHMk0&usp=sharing.
In the long run I'd love to use set tag with an id, but doing so now would prevent me from being able to release Glide as a jar and would require everyone to include it as a library project instead.