java - Gridview 适配器无法从外部存储读取,奇怪的循环迭代

标签 java android gridview

我从 Google 文档中获得了一个基本的 Gridview 示例,该示例运行良好。

我还有一些代码,以 ArrayList 形式提供结果,其中包含 Android 外部存储中最后创建的图片的位图(已授予 list 中的权限),并且该代码在其他项目上也运行良好。

当我将这些概念合并到一个简单的应用程序中时,代码根本不起作用, Activity 保持为空,直到应用程序崩溃。不过我注意到一些有趣的事情:有一个 for 循环,它通过 int 容量定义了迭代次数,但在 Logcat 中我可以看到该循环中的迭代次数超过了声明的 int 值,基本上这就是应用程序崩溃的原因(越界异常)。

所以我遇到了这两个问题并坐了几个小时......这是我的代码:

MainActivity.java

    package com.example.patryk.hellogridview;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.GridView;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        GridView gridview = findViewById(R.id.gridview);
        gridview.setAdapter(new ImageAdapter(this));

        gridview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            public void onItemClick(AdapterView<?> parent, View v,
                                    int position, long id) {
                Toast.makeText(MainActivity.this, "" + position,
                        Toast.LENGTH_SHORT).show();
            }
        });
    }

PhotosReader.java

    package com.example.patryk.hellogridview;

import android.content.Context;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.provider.MediaStore;
import android.util.Log;

import java.util.ArrayList;

public class PhotosReader {

    private int capacity = 5;
    private ArrayList<Bitmap> photos = new ArrayList<Bitmap>(capacity);

    public int getCapacity() {
        return capacity;
    }
    public void setCapacity(int capacity) {
        this.capacity = capacity;
    }
    public void setPhotos(ArrayList<Bitmap> photos) {
        this.photos = photos;
    }

    public PhotosReader() {
    }

    public ArrayList<Bitmap> getPhotos(Context context) {
        String[] projection = new String[]{
                MediaStore.Images.ImageColumns._ID,
                MediaStore.Images.ImageColumns.DATA,
                MediaStore.Images.ImageColumns.BUCKET_DISPLAY_NAME,
                MediaStore.Images.ImageColumns.DATE_TAKEN,
                MediaStore.Images.ImageColumns.MIME_TYPE
        };
        Cursor cursor = context.getContentResolver().query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, projection, null,
                null, MediaStore.Images.ImageColumns.DATE_TAKEN + " DESC");

        cursor.moveToFirst();
        for(int i = 1; i<=capacity; i++){
            photos.add(BitmapFactory.decodeFile(cursor.getString(1)));
            cursor.moveToNext();
            Log.d("photos.add", "iteration");
        }
        return photos;
    }

    public Bitmap getPhotosBitmap(ArrayList photos, int position){
        Bitmap bm = (Bitmap) photos.get(position);
        return bm;
    }



}

ImageAdapter.java

    package com.example.patryk.hellogridview;

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

public class ImageAdapter extends BaseAdapter {
    private Context mContext;

    public ImageAdapter(Context c) {
        mContext = c;
    }

    public int getCount() {
        return 0;
    }

    public Object getItem(int position) {
        return null;
    }

    public long getItemId(int position) {
        return 0;
    }

    // create a new ImageView for each item referenced by the Adapter
    public View getView(int position, View convertView, ViewGroup parent) {
        ImageView imageView;
        if (convertView == null) {
            // if it's not recycled, initialize some attributes
            imageView = new ImageView(mContext);
            imageView.setLayoutParams(new GridView.LayoutParams(85, 85));
            imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
            imageView.setPadding(8, 8, 8, 8);
        } else {
            imageView = (ImageView) convertView;
        }

        PhotosReader PR = new PhotosReader();
        imageView.setImageBitmap(PR.getPhotosBitmap(PR.getPhotos(mContext), position));
        return imageView;
    }

}

最佳答案

ImageAdapter 中的此函数不应返回 0。它应返回您想要在网格中显示的图像数量,因此在您的情况下应返回 capacity。 GridView 假设有 0 个内容要显示

public int getCount() {
        return 0;
}

将其更改为

public int getCount() {
        return capacity;
}
<小时/>

实际上,正确的方法是使用 ImageAdapter(context,photoReader)ImageAdapter 构造函数传递 PhotoReader 对象,并然后在getCount()函数中使用photoReader.getCapacity()

关于java - Gridview 适配器无法从外部存储读取,奇怪的循环迭代,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48242223/

相关文章:

java - bean实例化失败;嵌套异常是 java.lang.NoClassDefFoundError : org/springframework/core/io/Resource - using spring-core. 4_2_5

android - 测试intent是否可用

jquery - 当高度设置为自动时,如何使 gridview 显示两个滚动条

java - 如何防止 Apache CXF 发送响应消息?

java - Eclipse Formatter - 忽略 if 条件中的内容

Java 构造函数未正确初始化

java - 重新启动 Activity 后的 NPE

java - 将 SQLite 数据库以 mdb 或 accdb 数据库格式从 Android 手机导出到我的系统

c# - Gridview 被调用两次

android - 为什么android GridView项目里面的按钮无法点击?