Reputation: 4981
I'm using Picasso to load all my images in a Gridview and DBFlow to save in the Local database. But I have a problem when I download the images for the first time and if I'm scrolling in the gridview. The next images have the previous images and 1 second later the good image is loaded. I have to scroll 5 times or more and when all images is loaded I don't have this problem but for the first time yes.
Have you an idea to optimize my code ?
Gridview
<?xml version="1.0" encoding="utf-8"?>
<GridView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/gridview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:columnWidth="130dp"
android:numColumns="auto_fit"
android:verticalSpacing="10dp"
android:horizontalSpacing="10dp"
android:stretchMode="columnWidth"
android:gravity="center"
android:background="@color/colorAppBackground"/>
Item Grid
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="130dp">
<ImageView
android:id="@+id/iv_thumbnail"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:adjustViewBounds="true"
android:scaleType="centerCrop"/>
<TextView
android:id="@+id/text_thumb"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:gravity="center"
android:textColor="@android:color/white"
android:background="#99000000"/>
</RelativeLayout>
Activity
public class GalleryActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_gallery);
Bundle bundle = getIntent().getExtras();
int idAccount = bundle.getInt("idAccount");
callAdminPictures(idAccount);
}
public void callAdminPictures(final int idAccount){
// Build REST Adapter
Retrofit restAdapter = new Retrofit.Builder()
.baseUrl(Globals.SERVER_NAME)
.addConverterFactory(SimpleXmlConverterFactory.create())
.build();
// Create the App Service
ApplicationService appService = restAdapter.create(ApplicationService.class);
// Call Get admin pictures WS
Call<AdminPictures> getAdminPicturesWS = appService.getAdminPictures(idAccount);
getAdminPicturesWS.enqueue(new Callback<AdminPictures>() {
@Override
public void onResponse(Call<AdminPictures> call, Response<AdminPictures> response) {
AdminPictures apResponse = response.body();
List<PictureInfos> pictureInfos = apResponse.getPicturesList();
for (PictureInfos infos : pictureInfos) {
if (infos.exists()) {
infos.update();
} else {
infos.save();
}
}
List<PictureInfos> tablePictureInfos = new Select()
.from(PictureInfos.class)
.where(PictureInfos_Table.idAccount.is("" + idAccount))
.orderBy(PictureInfos_Table.idPicture, false)
.queryList();
GridView gridView = (GridView) findViewById(R.id.gridview);
gridView.setAdapter(new ImageAdapter(GalleryActivity.this, tablePictureInfos));
gridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Toast.makeText(GalleryActivity.this, "" + position, Toast.LENGTH_SHORT).show();
}
});
}
@Override
public void onFailure(Call<AdminPictures> call, Throwable t) {
if (t.getMessage() != null) {
Log.e("AdminPictures WS Fail", t.getMessage());
}
}
});
}
Adapter
public class ImageAdapter extends BaseAdapter {
private Context mContext;
private LayoutInflater mLayoutInflater;
private List<PictureInfos> mPInfoList;
private boolean mToSave;
public ImageAdapter(Context context, List<PictureInfos> pInfoList) {
mContext = context;
mPInfoList = pInfoList;
mLayoutInflater = LayoutInflater.from(context);
}
@Override
public int getCount() {
return mPInfoList.size();
}
@Override
public Object getItem(int position) {
return null;
}
@Override
public long getItemId(int position) {
return 0;
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
View view;
final ImageView imageView;
final TextView legend;
if(convertView == null){
view = mLayoutInflater.inflate(R.layout.thumbnail_gallery, parent, false);
}else{
view = convertView;
}
imageView = (ImageView) view.findViewById(R.id.iv_thumbnail);
legend = (TextView) view.findViewById(R.id.text_thumb);
final File file = new File(mContext.getExternalFilesDir(Environment.DIRECTORY_PICTURES), mPInfoList.get(position).getFilename());
mToSave = !file.exists();
Target target = new Target() {
@Override
public void onBitmapLoaded(final Bitmap bitmap, Picasso.LoadedFrom from) {
if(mToSave) {
new Thread(new Runnable() {
@Override
public void run() {
try {
FileOutputStream fileOutput = new FileOutputStream(file);
Log.i("catch", mPInfoList.get(position).getFilename());
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fileOutput);
fileOutput.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
}
imageView.setImageBitmap(bitmap);
if (mPInfoList.get(position).getFilename() != null) {
legend.setText(mPInfoList.get(position).getLegend());
}
}
@Override
public void onBitmapFailed(Drawable errorDrawable) {
}
@Override
public void onPrepareLoad(Drawable placeHolderDrawable) {
}
};
String pic = Globals.SERVER_NAME+Globals
.ACCOUNT_SERVER_PATH+mPInfoList
.get(position).getFolderPath()+"/"+
VgzTools.addSuffix(mPInfoList.get(position).getFilename(), "-thumb");
imageView.setTag(target);
if(!file.exists()){
Picasso.with(mContext)
.load(pic)
.into(target);
mToSave = true;
}else{
Picasso.with(mContext)
.load(file)
.into(target);
mToSave = false;
}
return view;
}
Upvotes: 0
Views: 1168
Reputation: 5375
Inside getView() put this line
imageView.setImageDrawable(null);
The previous image is coming because of view recycling. For each item you don't always get a new view, instead views are recycled to save memory. So once you scrolled the initially visible items, you will get the view from previous item which already has image set in it. So you have to remove it explicitly.
Upvotes: 2
Reputation: 3188
My guess is that because you're not explicitly clearing the imageView in your getView()
, it's retaining the current image when it's recycled (IE - when it's passed in as convertView
). Picasso will eventually call onBitmapLoaded()
, but until then, you're left with the 'old' image.
Try explicitly clearing the image.
Upvotes: 1