简体   繁体   中英

Image cannot be displayed in GridView?

I build a simple app with ImageView and GridView. I load images from an internet resource. The app can display an image (I tested with ImageView ), but It cannot display all images in the list.

I tested the following:

  1. Class DownloadImage worked normally.
  2. The ImageAdapter is ok too.

However, images still cannot be loaded on GridView . No need external libraries (Picasso, Glide...) .

Here is activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/colorPrimary"
    tools:context=".MainActivity">

    <GridView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:verticalSpacing="10dp"
        android:horizontalSpacing="10dp"
        android:id="@+id/gridview"/>

</ScrollView>

Here is DownloadImage.java

package com.example.imageviewer;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.widget.ImageView;

import java.io.InputStream;
import java.net.URL;

public class DownloadImage extends AsyncTask<String, Void, Bitmap> {
    ImageView imageview;

    public DownloadImage(ImageView imageview){
        this.imageview = imageview;
    }

    @Override
    protected Bitmap doInBackground(String... strings) {
        String url = strings[0];
        Bitmap result = null;
        try{
            InputStream in = new URL(url).openConnection().getInputStream();
            result = BitmapFactory.decodeStream(in);
        }catch(Exception e){
            e.printStackTrace();
        }
        return result;
    }

    @Override
    protected void onPostExecute(Bitmap bitmap) {
        imageview.setImageBitmap(bitmap);
    }
}

Here is ImageAdapter.java

package com.example.imageviewer;

import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;

public class ImageAdapter extends BaseAdapter {
    private Context context;
    private String[] imagelist;

    public ImageAdapter(Context context, String[] imagelist) {
        this.context = context;
        this.imagelist = imagelist;
    }

    @Override
    public int getCount() {
        return imagelist.length;
    }

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

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

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ImageView imagview;
        if(convertView==null)
            imagview = new ImageView(context);
        else
            imagview = (ImageView)convertView;
        new DownloadImage(imagview).execute(imagelist[position]);
        return imagview;
    }
}

Here is MainActivity.java

package com.example.imageviewer;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.GridView;

public class MainActivity extends AppCompatActivity {

    GridView gridview;
    String[] urls = {
            "https://sarahraven.images.blucommerce.com/sarahraven/product/261037_2.jpg",
            "https://ngb.org/wp-content/uploads/2018/09/longfield.gardens.Sept_.jpg"
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        gridview = findViewById(R.id.gridview);
        ImageAdapter imageadapter = new ImageAdapter(getApplicationContext(), urls);
        gridview.setAdapter(imageadapter);
        gridview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {

            }
        });
    }
}

Here is the logcat:

10-11 08:41:27.040 10544-10544/? I/art: Not late-enabling -Xcheck:jni (already on)
10-11 08:41:27.458 10544-10544/com.example.imageviewer W/art: Before Android 4.1, method android.graphics.PorterDuffColorFilter androidx.vectordrawable.graphics.drawable.VectorDrawableCompat.updateTintFilter(android.graphics.PorterDuffColorFilter, android.content.res.ColorStateList, android.graphics.PorterDuff$Mode) would have incorrectly overridden the package-private method in android.graphics.drawable.Drawable
10-11 08:41:27.646 10544-10544/com.example.imageviewer I/art: Rejecting re-init on previously-failed class java.lang.Class<androidx.core.view.ViewCompat$OnUnhandledKeyEventListenerWrapper>
10-11 08:41:27.669 10544-10544/com.example.imageviewer I/art: Rejecting re-init on previously-failed class java.lang.Class<androidx.core.view.ViewCompat$OnUnhandledKeyEventListenerWrapper>
10-11 08:41:27.767 10544-10557/com.example.imageviewer I/art: Background sticky concurrent mark sweep GC freed 2403(236KB) AllocSpace objects, 0(0B) LOS objects, 22% free, 874KB/1135KB, paused 2.275ms total 159.898ms
10-11 08:41:28.360 10544-10563/com.example.imageviewer D/OpenGLRenderer: Render dirty regions requested: true
10-11 08:41:28.419 10544-10544/com.example.imageviewer D/Atlas: Validating map...
10-11 08:41:28.764 10544-10563/com.example.imageviewer I/OpenGLRenderer: Initialized EGL, version 1.4
10-11 08:41:28.833 10544-10563/com.example.imageviewer D/EGL_emulation: eglCreateContext: 0x7f8131b44740: maj 3 min 0 rcv 3
10-11 08:41:28.865 10544-10563/com.example.imageviewer D/EGL_emulation: eglMakeCurrent: 0x7f8131b44740: ver 3 0 (tinfo 0x7f8131b11260)
10-11 08:41:28.880 10544-10563/com.example.imageviewer E/eglCodecCommon: glUtilsParamSize: unknow param 0x00008cdf
10-11 08:41:28.880 10544-10563/com.example.imageviewer E/eglCodecCommon: glUtilsParamSize: unknow param 0x00008824
10-11 08:41:28.884 10544-10563/com.example.imageviewer D/OpenGLRenderer: Enabling debug mode 0
10-11 08:41:28.985 10544-10563/com.example.imageviewer D/EGL_emulation: eglMakeCurrent: 0x7f8131b44740: ver 3 0 (tinfo 0x7f8131b11260)
10-11 08:41:29.019 10544-10544/com.example.imageviewer I/Choreographer: Skipped 33 frames!  The application may be doing too much work on its main thread.

Thanks in advance!

I do not recommend writing your own image downloader whereas there are some libraries like Glide and Picasso that are already available for this purpose.

In your case, the problem might be, the ImageView s are taking some time to download the images first. Hence, I think you really should use Glide or Picasso to load your images into your ImageView s inside the GridView .

I use Glide in most of the cases and its pretty simple to use and integrate. You do not have to write your DownloadImage class on your own. Just the following code snippet will do.

 Glide
    .with(context)
    .load(url)
    .into(imagview);

To integrate Glide, just add the following dependency in your build.gradle file, you are good to go!

repositories {
  mavenCentral()
  google()
}

dependencies {
  implementation 'com.github.bumptech.glide:glide:4.10.0'
  annotationProcessor 'com.github.bumptech.glide:compiler:4.10.0'
}

I hope that helps!

In case you are not comfortable with using external libraries, you need to implement the behavior that Glide implemented by yourself!

You need to lazy load the images when necessary. In a GridView the images are loaded on demand when visible. I recommend looking into the scroll options so that you can differentiate when there is a fling or a slight scroll. It's a bit tricky. I recommend looking into this answer .

The error is caused by putting a GridView inside a ScrollView . Basically, GridView contains a scrollable widget inside it. Just remove the ScrollView and it works normally.

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