Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/189.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何使用AsyncTask、RecyclerView和RecyclerView.Adapter将手机中的图像获取到我的RecyclerView中?_Java_Android - Fatal编程技术网

Java 如何使用AsyncTask、RecyclerView和RecyclerView.Adapter将手机中的图像获取到我的RecyclerView中?

Java 如何使用AsyncTask、RecyclerView和RecyclerView.Adapter将手机中的图像获取到我的RecyclerView中?,java,android,Java,Android,我正在尝试将手机中的图像加载到我的recyclerview中 到目前为止,我已经创建了一个recyclerview.adapter和一个gridlayoutmanager,并将它们连接到我的recyclerview。我可以成功地检索图像的完整路径,并使用异步任务将它们添加到适配器中 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState);

我正在尝试将手机中的图像加载到我的recyclerview中

到目前为止,我已经创建了一个recyclerview.adapter和一个gridlayoutmanager,并将它们连接到我的recyclerview。我可以成功地检索图像的完整路径,并使用异步任务将它们添加到适配器中

 @Override
 protected void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_gallery);

    settingUp();
    run();

}


public void settingUp(){

    //setting up recycler view
    recyclerView = findViewById(R.id.imageGallery);
    recyclerView.setHasFixedSize(true);

    //setting up recyclerview layout manager
    RecyclerView.LayoutManager layoutManager = new      GridLayoutManager(getApplicationContext(),2);
    recyclerView.setLayoutManager(layoutManager);

    //setting up recyclerview adapter
    adapter = getInstance(getApplicationContext());

    recyclerView.setAdapter(adapter);

    // instance of load task
    loadTask = new LoadTask();
}

private void run() {

    if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, STORAGE_PERMISSION_CODE);
    }
    else
    {
        loadTask.execute();
    }
}

 /**
 * Loads the images into the cursor using a background thread
 */

private class LoadTask extends AsyncTask<Void,Void, Cursor>
{

    // images are loaded into the cursor here, in the background.
    @Override
    protected Cursor doInBackground(Void... voids) {
        loadImagesIntoCursor();
        return imageCursor;
    }

    // this method runs after doInBackground finishes
    @Override
    protected void onPostExecute(Cursor cursor) {
        transferImagesToAdapter(cursor);
    }
}

//*********************************************************************************************************

/**
 * Loads all the Images from external storage into the cursor.
 */
private void loadImagesIntoCursor()
{
    imageCursor = getContentResolver().query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, new String[]{MediaStore.Images.Media.DATA}, null, null,
            MediaStore.Images.Media.DATE_ADDED + " DESC");
}

 private void transferImagesToAdapter(Cursor imageCursor)
{
    String path;
    if(imageCursor != null)
    {
        imageCursor.moveToFirst();
        while (!imageCursor.isAfterLast()){
            path =       imageCursor.getString(imageCursor.getColumnIndex(MediaStore.Images.Media.DATA));
            adapter.add(path);
            imageCursor.moveToNext();
        }
        imageCursor.close();

    }

}

/** MY ADAPTER CLASS **/

class ImageAdapter extends RecyclerView.Adapter<ImageAdapter.ImageViewHolder>{

private ArrayList<String> images;
//private static ImageAdapter singleton = null;
Context context;

public ImageAdapter(Context context, ArrayList<String> paths)
{
    images = paths;
    this.context = context;
}

public ImageAdapter(Context context)
{

    this.context = context;
}



//--------- OVERRIDE METHODS ---------------------------------------------
@NonNull
@Override
public ImageViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
    View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.cell_layout,parent);
    return new ImageViewHolder(view);
}

@Override
public void onBindViewHolder(@NonNull ImageViewHolder holder, int position) {
    holder.image.setScaleType(ImageView.ScaleType.CENTER_CROP);
    // load image into image holder view using picasso library
    Picasso.with(context).load(images.get(position)).into(holder.image);
}

@Override
public int getItemCount() {
    return images.size();
}

//------------------------------------------------------------------------

public void add(String path){
    this.images.add(path);
}

//------------------------------------------------------------------------

public class ImageViewHolder extends RecyclerView.ViewHolder{
    protected ImageView image;
    public ImageViewHolder(View view){
        super(view);
        this.image = view.findViewById(R.id.img);
    }
}
@覆盖
创建时受保护的void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_gallery);
设置();
run();
}
公共无效设置(){
//设置回收器视图
recyclerView=findViewById(R.id.imageGallery);
recyclerView.setHasFixedSize(true);
//设置recyclerview布局管理器
RecycleView.LayoutManager LayoutManager=新的GridLayoutManager(getApplicationContext(),2);
recyclerView.setLayoutManager(layoutManager);
//设置recyclerview适配器
适配器=getInstance(getApplicationContext());
recyclerView.setAdapter(适配器);
//加载任务的实例
loadTask=新的loadTask();
}
私家车{
if(Build.VERSION.SDK\u INT>=Build.VERSION\u code.M){
requestPermissions(新字符串[]{Manifest.permission.READ_EXTERNAL_STORAGE},STORAGE_permission_CODE);
}
其他的
{
loadTask.execute();
}
}
/**
*使用背景线程将图像加载到光标中
*/
私有类LoadTask扩展了AsyncTask
{
//图像在这里加载到光标中,在背景中。
@凌驾
受保护的光标背景(无效…无效){
将图像加载到ocursor();
返回图像光标;
}
//此方法在doInBackground完成后运行
@凌驾
受保护的void onPostExecute(游标){
transferImagesToAdapter(光标);
}
}
//*********************************************************************************************************
/**
*将所有图像从外部存储器加载到光标中。
*/
私有void loadImagesIntoCursor()文件
{
imageCursor=getContentResolver().query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,新字符串[]{MediaStore.Images.Media.DATA},null,null,
MediaStore.Images.Media.DATE_已添加+“DESC”);
}
私有void transferImagesToAdapter(游标imageCursor)
{
字符串路径;
如果(imageCursor!=null)
{
imageCursor.moveToFirst();
而(!imageCursor.isAfterLast()){
path=imageCursor.getString(imageCursor.getColumnIndex(MediaStore.Images.Media.DATA));
adapter.add(路径);
imageCursor.moveToNext();
}
imageCursor.close();
}
}
/**我的适配器类**/
类ImageAdapter扩展了RecyclerView.Adapter{
私有数组列表图像;
//私有静态ImageAdapter singleton=null;
语境;
公共ImageAdapter(上下文、ArrayList路径)
{
图像=路径;
this.context=上下文;
}
公共ImageAdapter(上下文)
{
this.context=上下文;
}
//---------重写方法---------------------------------------------
@非空
@凌驾
public ImageViewHolder onCreateViewHolder(@NonNull ViewGroup父级,int-viewType){
View=LayoutFlater.from(parent.getContext()).flate(R.layout.cell\u layout,parent);
返回新的ImageViewHolder(视图);
}
@凌驾
public void onBindViewHolder(@NonNull ImageViewHolder,int位置){
holder.image.setScaleType(ImageView.ScaleType.CENTER\U裁剪);
//使用毕加索库将图像加载到图像保持器视图中
毕加索.with(context).load(images.get(position)).into(holder.image);
}
@凌驾
public int getItemCount(){
返回图像。size();
}
//------------------------------------------------------------------------
公共void添加(字符串路径){
this.images.add(路径);
}
//------------------------------------------------------------------------
公共类ImageViewHolder扩展了RecyclerView.ViewHolder{
保护图像查看图像;
公共图像视图持有者(视图){
超级(视图);
this.image=view.findviewbyd(R.id.img);
}
}
}

但是,在添加ImagePath之后,我不知道是什么触发了适配器中的onCreateViewHolder和onBindViewHolder方法,该适配器将在recyclerview中显示我的图像。
请帮忙

更新RecyclerView列表项需要做两件事

  • 更新适配器内的数据列表
  • 通知数据集更改

  • 回收器视图
    回收器视图适配器
    是两个不同的东西。只需将数据添加到
    适配器
    中,除了充实
    适配器
    对象之外,什么也做不了

    必须告知
    回收器视图
    适配器的数据状态已更改,
    回收器视图
    应从
    适配器
    中提取更新的数据

    有两种方法可以做到这一点:

  • 适配器的数据源中输入所有数据更改后调用方法
  • 使用
  • 上述技术之间的区别在于,
    notifyDataSetChanged
    将数据完全重置为当前数据源的数据,而
    DiffUtil
    只更改已更新的数据,而不更改未更改的数据

    因此,如果您的数据源大约有1000个对象,并且您只更改了其中一个对象,那么最好使用
    DiffUtils
    ,因为
    notifyDataSetChanged
    会影响性能

    此外,问题是,如果有许多映像,将存在严重的性能瓶颈,因为即使添加一个映像,整个数据源也将被重新加载,并且它位于循环中的事实会加剧问题。因此,移动
    适配器。notifyDataSetChanged()在循环外调用。我假设您有一个
    列表
    o
     private void transferImagesToAdapter(Cursor imageCursor)
    {
        String path;
        if(imageCursor != null)
        {
            imageCursor.moveToFirst();
            while (!imageCursor.isAfterLast()){
                path =       imageCursor.getString(imageCursor.getColumnIndex(MediaStore.Images.Media.DATA));
                adapter.add(path); // If it update data list in your adapter then fine.
                adapter.notifyDataSetChanged(); // It will do all the callbacks and update your screen.
    
                imageCursor.moveToNext();
            }
            imageCursor.close();
    
        }
    
    }
    
     @Override
     protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        run();
        setContentView(R.layout.activity_gallery);
        settingUp();
    }
    
    
    public void settingUp(){
    
        //setting up recycler view
        recyclerView = findViewById(R.id.imageGallery);
    
        //setting up recyclerview layout manager
        RecyclerView.LayoutManager layoutManager = new      GridLayoutManager(getApplicationContext(),2);
        recyclerView.setLayoutManager(layoutManager);
    
        // instance of load task
        loadTask = new LoadTask();
    }
    
    private void run() {
    
        if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, STORAGE_PERMISSION_CODE);
        }
      }
    
     /**
     * Loads the images into the cursor using a background thread
     */
    
    private class LoadTask extends AsyncTask<Void,Void, List<String>
    { 
    
        // images are loaded into the cursor here, in the background.
        @Override
        protected List<String> doInBackground(Void... voids) {
            return getAllImages();
        }
    
        // this method runs after doInBackground finishes
        @Override
        protected void onPostExecute(List<String imagesList>) {
            ImageAdapter imageAdapter = new ImageAdapter(getActivity, magesList);
            recyclerview.setAdapter(imageAdapter);
        }
    }
    
    //*********************************************************************************************************
    
    /**
     * Loads all the Images from external storage into the cursor.
     */
    private void getAllImages()
    {
       List<String> imagesList = new ArrayList<>();
       Cursor imageCursor = getContentResolver().query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, new String[]{MediaStore.Images.Media.DATA}, null, null,
                MediaStore.Images.Media.DATE_ADDED + " DESC");
        if(imageCursor != null)
        {
            imageCursor.moveToFirst();
            while (!imageCursor.isAfterLast()){
    
        String path = imageCursor.getString(imageCursor.getColumnIndex(MediaStore.Images.Media.DATA));
                imagesList.add(path);
                imageCursor.moveToNext();
            }
            imageCursor.close();
    
        }
        return imagesList;
    }
    
    /** MY ADAPTER CLASS **/
    
    class ImageAdapter extends RecyclerView.Adapter<ImageAdapter.ImageViewHolder>{
    
    private List<String> images;
    Context context;
    
    public ImageAdapter(Context context, List<String> paths)
    {
        this.images = paths;
        this.context = context;
    }
    
    //--------- OVERRIDE METHODS ---------------------------------------------
    @NonNull
    @Override
    public ImageViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.cell_layout,parent);
        return new ImageViewHolder(view);
    }
    
    @Override
    public void onBindViewHolder(@NonNull ImageViewHolder holder, int position) {
        holder.image.setScaleType(ImageView.ScaleType.CENTER_CROP);
        // load image into image holder view using picasso library
        Picasso.with(context).load(images.get(position)).into(holder.image);
    }
    
    @Override
    public int getItemCount() {
        return images.size();
    }
    
    public class ImageViewHolder extends RecyclerView.ViewHolder{
        protected ImageView image;
        public ImageViewHolder(View view){
            super(view);
            this.image = view.findViewById(R.id.img);
        }
    }