将图像动态添加到gridview会导致内存不足错误

时间:2016-06-03 09:55:15

标签: android gridview

我正在尝试将图像添加到网格视图中。网格视图如下所示:

import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import java.io.File;
import java.util.ArrayList;

/**
 * Created by Khan on 29/05/2016.
 */
public class GridViewAdapter extends BaseAdapter {
    private Context context;
    ArrayList<String> imageTitles = new ArrayList<String>();
    ArrayList<Drawable> images = new ArrayList<Drawable>();
    ArrayList<File> files = new ArrayList<File>();

    public GridViewAdapter(Context context, ArrayList<Drawable> images, ArrayList<String> imageTitles,ArrayList<File> files) {
        this.images = images;
        this.context = context;
        this.imageTitles = imageTitles;
        this.files = files;
    }

    @Override
    public int getCount() {
        return imageTitles.size();
    }

    @Override
    public Object getItem(int position) {
        return position;
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(final int position, View convertView, ViewGroup parent) {
        View row = convertView;
        ViewHolder holder = null;


        LayoutInflater inflater = ((Activity) context).getLayoutInflater();
        row = inflater.inflate(R.layout.grid_item_layout, parent, false);
        holder = new ViewHolder();
        holder.imageTitle = (TextView) row.findViewById(R.id.text);
        holder.image = (ImageView) row.findViewById(R.id.image);
        holder.imageButton = (ImageButton)row.findViewById(R.id.deleteImageButton);


        holder.imageTitle.setText(imageTitles.get(position));
        holder.image.setImageDrawable(images.get(position));


        holder.imageButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

               try
               {

                   AlertDialog.Builder builder = new AlertDialog.Builder(context);
                   builder.setMessage("Are you sure to delete image " + imageTitles.get(position) + "?")
                           .setCancelable(false)
                           .setPositiveButton("Yes", new DialogInterface.OnClickListener() {
                               public void onClick(DialogInterface dialog, int id) {
                                   if (files.get(position).delete()) {
                                       Toast.makeText(context, "The image is deleted successfully.", Toast.LENGTH_LONG).show();
                                       images.remove(position);
                                       files.remove(position);
                                       imageTitles.remove(position);

                                       notifyDataSetChanged();
                                   }

                               }
                           })
                           .setNegativeButton("No", new DialogInterface.OnClickListener() {
                               public void onClick(DialogInterface dialog, int id) {
                                   dialog.cancel();
                               }
                           });
                   AlertDialog alert = builder.create();
                   alert.show();


               }
               catch (Exception e)
               {
                   e.printStackTrace();

//                   Log.d("DELETE","Something went wrong");

               }

            }
        });



//        what happens when user clicks  on one of the images

        holder.image.setOnClickListener(new
            View.OnClickListener() {
                @Override
                public void onClick(View v)
                {
                    try {

                        Intent intent = new Intent();
                        intent.setAction(Intent.ACTION_VIEW);
                        intent.setDataAndType(Uri.parse("file://" +files.get(position).toString()), "image/*");
                        context.startActivity(intent);

//                        context.startActivity(new Intent(Intent.ACTION_VIEW, )); /** replace with your own uri */

                    }
                    catch (Exception e)
                    {
                        e.printStackTrace();
//                        Log.d("GridView Adpater","The file path is" + files.get(position).toString());

                    }
                }
            });


        return row;
    }

    static class ViewHolder {
        TextView imageTitle;
        ImageView image;
        ImageButton imageButton;
    }


}

现在,我正在使用此方法从我的设备获取图像:

public void getImages()
    {
        File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(
                Environment.DIRECTORY_PICTURES), "AppsEye");
        if(mediaStorageDir.exists())
        {
            String[] strings = mediaStorageDir.list();
            imageTitles = new ArrayList<String>(Arrays.asList(strings));
//            Log.d(TAG, "the files are: " + imageTitles);

        }
        try
        {
            for(File file : mediaStorageDir.listFiles())
            {
                files.add(file);
                images.add(BitmapDrawable.createFromPath(file.getAbsolutePath()));
            }
        }
        catch (Exception e)
        {
            e.printStackTrace();
//            Log.d(TAG,"Got some exceptoin ");
        }
    }

使用以下方式设置适配器:

        gridView = (GridView)view.findViewById(R.id.gridView);
//        Log.d(TAG,"I am gallery");
        getImages();


        gridViewAdapter = new GridViewAdapter(getActivity(),images,imageTitles,files);

        gridView.setAdapter(gridViewAdapter);

        return view;

上述代码的问题在于,在运行时,向images添加大量图像会使运行时间内存出错。

                images.add(BitmapDrawable.createFromPath(file.getAbsolutePath()));

因此,为了避免上述问题,我需要逐一向gridview添加图像。我怎样才能做到这一点?请帮我解决这个问题。

1 个答案:

答案 0 :(得分:0)

您不应将图像作为drawable传递给适配器。相反,您可以使用传递的文件来加载图像。您需要使用PicassoGlide之类的图像加载器来避免OutOfMemory异常或延迟滚动。

使用毕加索的例子:

Picasso.with(context).load(files.get(position)).into(holder.image);

而不是:

holder.image.setImageDrawable(images.get(position));