Android gridview滚动糟糕的加载图片

时间:2016-03-11 17:12:25

标签: android image android-gridview picasso

我正在使用Picasso在Gridview和DBFlow中加载我的所有图像以保存在本地数据库中。但是当我第一次下载图像时,如果我在gridview中滚动,我会遇到问题。下一个图像具有先前的图像,并且1秒后加载好的图像。我必须滚动5次或更多次,当所有图像都加载时我没有这个问题但是第一次是。

您有想法优化我的代码吗?

的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"/>

项目网格

<?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>

活动

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());
            }
        }
    });
}

适配器

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;
}

2 个答案:

答案 0 :(得分:2)

在getView()里面放了这行

imageView.setImageDrawable(null);

由于视图回收,之前的图片即将到来。对于每个项目,您并不总是获得新视图,而是回收视图以节省内存。因此,一旦您滚动了最初可见的项目,您将获得已经在其中设置了图像的上一个项目的视图。所以你必须明确地删除它。

答案 1 :(得分:1)

我的猜测是,因为您未明确清除getView()中的imageView,所以当它被回收时,它会保留当前图像(IE - 当它被&#39;以convertView)传入。毕加索最终会打电话给onBitmapLoaded(),但在此之前,你已经离开了“老人”。图像。

尝试明确清除图像。