简体   繁体   中英

GridView scrolling is not smooth android

I have this gridview which loads images from sd card........problem is the scrolling is not at all smooth and i have no idea whats wrong with it......can someone one help me out with it??

private Cursor cursor;
private int columnIndex;
private GridView gridView;
ProgressDialog pd;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    gridView = (GridView) findViewById(R.id.gridview);


    new LoadImages().execute();


/**
 * Adapter for our image files.
 */
public class ImageAdapter extends BaseAdapter {

    private Context context;

    public ImageAdapter(Context localContext) {
        context = localContext;
    }

    public int getCount() {
        return cursor.getCount();
    }
    public Object getItem(int position) {
        return position;
    }
    public long getItemId(int position) {
        return position;
    }
    public View getView(int position, View convertView, ViewGroup parent) {
        ImageView picturesView;
        if (convertView == null) {
            picturesView = new ImageView(context);
            picturesView.setScaleType(ImageView.ScaleType.FIT_CENTER);
            picturesView.setPadding(5, 5, 5, 5);
            picturesView.setLayoutParams(new GridView.LayoutParams(80, 80));
        }
        else {
            picturesView = (ImageView)convertView;

        }


            // Move cursor to current position
            cursor.moveToPosition(position);
            // Get the current value for the requested column
            int imageID = cursor.getInt(columnIndex);
            // Set the content of the image 
           picturesView.setImageBitmap(MediaStore.Images.Thumbnails.getThumbnail(context.getContentResolver(),
                    imageID, MediaStore.Images.Thumbnails.MINI_KIND, null));

        return picturesView;
    }
}

I have no idea how this function works as a background task!!!! It just works!! any insight???

private void LoadImagesFromSDCard(){

    sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.parse("file://" + Environment.getExternalStorageDirectory())));    //to update the database or rescan the database to get the captured image
    //delay given for the sdcard to reload as per the above statement
        try {
            Thread.sleep(300L);   
        }
        catch (Exception e) {}
        // Set up an array of the Thumbnail Image ID column we want
        String[] projection = {MediaStore.Images.Media._ID};
        // Create the cursor pointing to the SDCard
        cursor = managedQuery( MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
                projection, // Which columns to return
                null,       // Return all rows
                null,
                MediaStore.Images.Media._ID);
        // Get the column index of the Media Image ID
        columnIndex = cursor.getColumnIndexOrThrow(MediaStore.Images.Media._ID);

}

And this is my asynctask...

class LoadImages extends AsyncTask<String, String, String> {
    ProgressDialog progDailog = new ProgressDialog(PrintBrushActivity.this);
    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        progDailog.setMessage("Loading.....");
        progDailog.setIndeterminate(false);
        progDailog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
        progDailog.show();
    }
    @Override
    protected String doInBackground(String... aurl) {
        //do something while spinning circling show
        LoadImagesFromSDCard();

        return null;
    }
    @Override
    protected void onPostExecute(String unused) {
        super.onPostExecute(unused);
        gridView.setAdapter(new ImageAdapter(PrintBrushActivity.this));
        progDailog.dismiss();
    }
}
}

In my gallery I use MediaStore.Images.Thumbnails.MICRO_KIND instead of MediaStore.Images.Thumbnails.MINI_KIND .

I also use a cache , that is to say, a HashMap where I save the loaded thumbnails and if I need to show again the same thumbnail I load it from cache and not generate it again. My cache is this:

cache = new HashMap<Integer, SoftReference<Bitmap>>();

where in Integer position is saved the image id and in SoftReference position the thumbnail bitmap. This 2 things make my app smoother.

Good luck!

I had the same problem, I saw this answer in other thread, I try it and it was considerably better.

https://stackoverflow.com/a/7624088/3419242

In short, create a ListView and then create the columns yourself programmatically, this way you are creating the GridView . The main problem is on the Gridview that came in the SDK, its a bit slow

you could use Android-Universal-Image-Loader-master library like this

public View getView(int position, View convertView, ViewGroup parent) {
            ImageView picturesView;
            final ProgressBar spinner = (ProgressBar)findViewById(R.id.loading_image_fromsdcard);
            if (convertView == null) {
                picturesView = new ImageView(context);
                picturesView.setScaleType(ImageView.ScaleType.CENTER_CROP);
                picturesView.setLayoutParams(new LayoutParams(250, 250));


            }
            else {
                picturesView = (ImageView)convertView;
            }
            // Move cursor to current position
            cursor.moveToPosition(position);
            // Get the current value for the requested column
            int imageID = cursor.getInt(columnIndex);
            // Set the content of the image based on the provided URI
            //picturesView.setImageURI(Uri.withAppendedPath( MediaStore.Images.Thumbnails.EXTERNAL_CONTENT_URI, "" + imageID));
            imageLoader.displayImage(Uri.withAppendedPath( MediaStore.Images.Thumbnails.EXTERNAL_CONTENT_URI, "" + imageID).toString(), picturesView, options, new SimpleImageLoadingListener() {
                @Override
                public void onLoadingStarted(String imageUri, View view) {
                    spinner.setVisibility(View.VISIBLE);
                }
                @Override
                public void onLoadingFailed(String imageUri, View view, FailReason failReason) {
                    String message = null;
                    switch (failReason.getType()) {
                        case IO_ERROR:
                            message = "Input/Output error";
                            break;
                        case DECODING_ERROR:
                            message = "Image can't be decoded";
                            break;
                        case NETWORK_DENIED:
                            message = "Downloads are denied";
                            break;
                        case OUT_OF_MEMORY:
                            message = "Out Of Memory error";
                            break;
                        case UNKNOWN:
                            message = "Unknown error";
                            break;
                    }
                    Toast.makeText(Sdcard.this, message, Toast.LENGTH_SHORT).show();
                    spinner.setVisibility(View.GONE);
                }
                @Override
                public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
                    spinner.setVisibility(View.GONE);
                }
            });
            return picturesView;
        }
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM