Android 从SD卡查询图像并将其显示在GridView中

Android 从SD卡查询图像并将其显示在GridView中,android,android-fragments,android-gridview,android-recyclerview,android-cursorloader,Android,Android Fragments,Android Gridview,Android Recyclerview,Android Cursorloader,我正试图解决这个问题。我有一些代码,它使用游标装入器从SD卡查询图像,并在SimpleCursorAdapter的帮助下在GridView中显示它们。我在网上遵循了一些示例,并通读了文档。我知道我有一部分是对的。代码运行时没有任何错误,但是我无法在网格上显示缩略图。以下是到目前为止我得到的代码: GalleryFragment.java public class GalleryFragment extends Fragment { private SimpleCursorAdapter

我正试图解决这个问题。我有一些代码,它使用游标装入器从SD卡查询图像,并在SimpleCursorAdapter的帮助下在GridView中显示它们。我在网上遵循了一些示例,并通读了文档。我知道我有一部分是对的。代码运行时没有任何错误,但是我无法在网格上显示缩略图。以下是到目前为止我得到的代码:

GalleryFragment.java

public class GalleryFragment extends Fragment {

    private SimpleCursorAdapter adapter;
    public static final int PHOTO_LIST_ID = 0x01;

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_gallery, container, false);
        // Bind adapter to grid
        setupCursorAdapter();
        // Initialize the loader with a special ID and the defined callbacks
        getLoaderManager().initLoader(PHOTO_LIST_ID,
                new Bundle(), imageLoader);
        GridView gridView = (GridView) view.findViewById(R.id.gridView);
        gridView.setAdapter(adapter);
        return view;

    }

    private void setupCursorAdapter() {
        String[] from = {MediaStore.Images.Thumbnails.DATA};
        int[] to = {R.id.imageView};
        adapter = new SimpleCursorAdapter(getActivity().getBaseContext(),
                R.layout.gallery_image_item,
                null, from, to,
                0);
    }

    private LoaderManager.LoaderCallbacks<Cursor> imageLoader =
            new LoaderManager.LoaderCallbacks<Cursor>() {

                @Override
                public Loader<Cursor> onCreateLoader(int id, Bundle args) {
                    // Define the columns to retrieve
                    String[] projection = {MediaStore.Images.Thumbnails._ID,
                        MediaStore.Images.Thumbnails.DATA};
                    return new CursorLoader(getActivity(),
                            MediaStore.Images.Thumbnails.EXTERNAL_CONTENT_URI,
                            projection, null, null, null);
                }

                @Override
                public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
                    adapter.swapCursor(data);
                }

                @Override
                public void onLoaderReset(Loader<Cursor> loader) {
                    adapter.swapCursor(null);
                }
            };
}
公共类GalleryFragment扩展了片段{
专用SimpleCursorAdapter适配器;
公共静态最终内部照片列表ID=0x01;
@可空
@凌驾
CreateView上的公共视图(布局、充气机、视图组容器、捆绑包保存状态){
视图=充气机。充气(R.layout.fragment_gallery,container,false);
//将适配器绑定到网格
setupCursorAdapter();
//使用特殊ID和定义的回调初始化加载程序
getLoaderManager().initLoader(照片列表ID,
新Bundle(),imageLoader);
GridView GridView=(GridView)view.findviewbyd(R.id.GridView);
setAdapter(适配器);
返回视图;
}
私有void setupCursorAdapter(){
字符串[]from={MediaStore.Images.Thumbnails.DATA};
int[]to={R.id.imageView};
适配器=新的SimpleCursorAdapter(getActivity().getBaseContext(),
R.layout.gallery\u图像\u项目,
空,从,到,
0);
}
私有LoaderManager.LoaderCallbacks imageLoader=
新建LoaderManager.LoaderCallbacks(){
@凌驾
公共加载器onCreateLoader(int-id,Bundle-args){
//定义要检索的列
String[]projection={MediaStore.Images.Thumbnails.\u ID,
MediaStore.Images.Thumbnails.DATA};
返回新的游标装入器(getActivity(),
MediaStore.Images.Thumbnails.EXTERNAL\u CONTENT\u URI,
投影,空,空,空);
}
@凌驾
public void onLoadFinished(加载器、光标数据){
适配器。swapCursor(数据);
}
@凌驾
公共void onLoaderReset(加载器){
适配器.swapCursor(空);
}
};
}
fragment_gallery.xml

<LinearLayout 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"
    tools:context="edu.sfsu.csc780.pictachio.GalleryFragment">

    <GridView
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:id="@+id/gridView"
        android:numColumns="auto_fit"
        android:verticalSpacing="10dp"/>

</LinearLayout>

gallery_image_item.xml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">


    <ImageView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:id="@+id/imageView"
        android:padding="10dp"
        android:adjustViewBounds="true"
        android:contentDescription="ImageView" />
</FrameLayout>


我在很多地方读到,RecyclerView是推荐的方法,而不是GridView。我试过了,但我不知道该为它创建什么样的模型。在此方面的任何帮助都将不胜感激。谢谢。

我不明白如何使用getLoaderManager()和initLoader()获取图像。一种方法是从SQLite数据库获取它们。正确的谷歌文档是@。我提供了一个使用该查询方法的示例代码。然而,我从来没有在安卓系统中获得过图像

Uri uri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
String[] cols = new String[]{
                MediaStore.Images.Media.DATA,  // get the image
};
//String where = MediaStore.Images.Media.DATA;

Cursor cursor = getContentResolver().query(uri, cols, null, null, null);
if(cursor.moveToFirst()) {
   int column_image = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
   res = cursor.getString(column_image);
}
cursor.close();
注:

  • query
    ()的第三和第四个参数用于过滤返回的数据
  • 游标
    对象是从查询返回的,可以遍历它,上面列出了示例代码
  • 另一个有趣的方法是使用@of classEnvironment。我用它来查找特定目录中的文件。这种技术实际上可能更快,因为它在特定目录中搜索,而不是查询数据库。但是,可能存在不希望出现的权限问题,尤其是SD卡
尝试一下,让我们知道会发生什么。

最好的方法是使用库。这很简单。只需将库依赖项添加到项目中,然后将下面的行添加到类中。适配器已准备就绪,您可以为gridview设置它

RecentImages ri = new RecentImages();
ImageAdapter adapter = ri.getAdapter(MainActivity.this);

它有一些选项可以定制您对图像的查询。

这个问题中的代码对我很有用,我让它运行是为了回答这个问题(不过使用了一个库):很有趣。我还没有考虑过使用库来实现这一点。谢谢分享。我没有看到可以在目录中获取图像的代码。我会给你一个代码示例。谢谢。我试试看。有没有办法将获取的图像绑定到RecyclerView视图持有者?@vshl,RecyclerView只是一个GUI组件/类。这与获取图像无关。您仍然可以从数据库或本机文件系统获取图像。我看没有别的办法了。