【问题标题】:OnBindViewHolder not called unless I save a file first除非我先保存文件,否则不会调用 OnBindViewHolder
【发布时间】:2020-10-19 15:52:47
【问题描述】:

更新 #2

感谢 AgentP 提示我的问题。我已通过在 showImages() 中进行此更改来解决此问题:

(还创建了一个全局引用字段字符串路径;在同一个活动中):

    private void showImages(){
    
        // Added following two lines :
        ContextWrapper cw = new ContextWrapper(this); // + added
        path = cw.getDir("files", Context.MODE_PRIVATE).toString(); // + added
    
        //  String path = DrawingActivity.path; // - removed
        allFilesPaths = new ArrayList<>();
        allFilesPaths = listAllFiles(path);
    
        RecyclerView recyclerView = (RecyclerView) findViewById(R.id.galleryRecycleViewId);
        recyclerView.setHasFixedSize(true);
    
        RecyclerView.LayoutManager layoutManager = new GridLayoutManager(getApplicationContext(), 3);
        recyclerView.setLayoutManager(layoutManager);
    
        ArrayList<Cell> cells = prepareData();
        ImageAdapter adapter = new ImageAdapter(getApplicationContext(), cells);
        recyclerView.setAdapter(adapter);
    
    }

更新

显然我有一个仅在保存图像方法中设置的静态字符串。它的目的是为 show images 方法提供图像文件夹路径。我现在正在尝试通过其他方式为我的 showImages() 方法提供路径。


我有一个画廊活动,它显示来自具有回收器视图的文件夹中的图像。

当我启动我的应用程序时,尽管文件夹中有图像,但画廊是空的。

当我进入我的绘图活动时,保存图像并返回到画廊活动,它会毫无问题地显示所有图像。

我在 onbindviewholder 方法中放置了一个日志,它只在我保存图像后执行。

图像适配器缺少哪些功能来查看现有文件以及图像保存如何使其在执行时找到它们?

(我还记得当我编写保存图像的方法时它想让我做 @SuppressLint("WrongThread") ,但现在没有它它也可以工作)

打开画廊而不在绘图活动中保存文件时的调试信息:

  • ClassLoader 引用了未知路径:/data/app/com.example.myapp-2/lib/x86_64
  • 在 Android 4.1 之前,方法 android.graphics.PorterDuffColorFilter androidx.vectordrawable.graphics.drawable.VectorDrawableCompat.updateTintFilter(android.graphics.PorterDuffColorFilter, android.content.res.ColorStateList, android.graphics.PorterDuff$Mode) 会错误重写了 android.graphics.drawable.Drawable 中的 package-private 方法
  • 拒绝重新初始化以前失败的类 java.lang.Class
  • D/OpenGLRenderer:使用 EGL_SWAP_BEHAVIOR_PRESERVED:真
  • I/OpenGLRenderer:初始化 EGL,1.4 版
  • W/OpenGLRenderer:无法选择带有 EGL_SWAP_BEHAVIOR_PRESERVED 的配置,正在重试而不...

在 Gallery Activity 中显示图片的方法:

    List <Cell> allFilesPaths;
        
        // on create calls show images after checking if read storage permission is good
        
     private void showImages(){
            // this is the current problem line , 
            // I need a way to give path of my image folder to this method
            // Check SaveImage() method below to see how it is initially set
            // path is a global static field inside drawing activity
            String path = DrawingActivity.path;
            allFilesPaths = new ArrayList<>();
            allFilesPaths = listAllFiles(path);
    
            RecyclerView recyclerView = (RecyclerView) findViewById(R.id.galleryRecycleViewId);
            recyclerView.setHasFixedSize(true);
    
            RecyclerView.LayoutManager layoutManager = new GridLayoutManager(getApplicationContext(), 3);
            recyclerView.setLayoutManager(layoutManager);
    
            ArrayList<Cell> cells = prepareData();
            ImageAdapter adapter = new ImageAdapter(getApplicationContext(), cells);
            recyclerView.setAdapter(adapter);
    
        }
    
        private ArrayList<Cell> prepareData(){
            ArrayList<Cell> allImages = new ArrayList<>();
            for (Cell c : allFilesPaths){
                Cell cell = new Cell();
                cell.setTitle(c.getTitle());
                cell.setPath(c.getPath());
                allImages.add(cell);
            }
            return allImages;
        }
    
        private List<Cell> listAllFiles(String pathName){
            List<Cell> allFiles = new ArrayList<>();
            if(pathName != null){
                File file = new File(pathName);
                File[] files = file.listFiles();
                if(files != null){
                    for (File f : files){
                        Cell cell = new Cell();
                        cell.setTitle(f.getName());
                        cell.setPath(f.getAbsolutePath());
                        allFiles.add(cell);
                    }
                }
            }
            return allFiles;
        }

在我的图像适配器内部:

private ArrayList<Cell> galleryList;
private Context context;
private static final String TAG = "ImageAdapter";

public ImageAdapter(Context context, ArrayList<Cell> galleryList) {
    this.context = context;
    this.galleryList = galleryList;
}

@NonNull
@Override
public ImageAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
    View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.cell, parent, false);
    return new ImageAdapter.ViewHolder(view);
}

@Override
public void onBindViewHolder(@NonNull ImageAdapter.ViewHolder holder, final int position) {
    holder.img.setScaleType(ImageView.ScaleType.CENTER_CROP);
    Log.d(TAG, "onBindViewHolder: " + galleryList.size());
    setImageFromPath(galleryList.get(position).getPath(), holder.img);
    holder.img.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            String path = galleryList.get(position).getPath();
            Intent intent = new Intent(context ,ImagePreview.class);
            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            intent.putExtra("imagePath",path);
            context.startActivity(intent);
        }
    });

}

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


public class ViewHolder extends RecyclerView.ViewHolder {
    private ImageView img;

    public ViewHolder(@NonNull View itemView) {
        super(itemView);
        img = (ImageView) itemView.findViewById(R.id.img);
    }
}

private void setImageFromPath(String path, ImageView image){
    File imgFile = new File(path);

    try {
            Bitmap myBitmap = BitmapFactory.decodeStream(new FileInputStream(imgFile));
            image.setImageBitmap(myBitmap);
            //            ImageView imageView = (ImageView)findViewById(R.id.imageViewSelect);
            //            imageView.setImageBitmap(bitmap);
    }catch (FileNotFoundException e){
        e.printStackTrace();
    }
}

绘图活动中保存图像的方法:

   public void saveImage() {
       ContextWrapper cw = new ContextWrapper(getContext());
       String filename = "img" + System.currentTimeMillis();
       File directory = cw.getDir("files", Context.MODE_PRIVATE);
       path = cw.getDir("files", Context.MODE_PRIVATE).toString();
       File myPath = new File(directory, filename + ".jpg");

       FileOutputStream fileOutputStream = null;
       try {
           fileOutputStream = new FileOutputStream(myPath);
           bitmap.compress(Bitmap.CompressFormat.PNG, 100, fileOutputStream);
       }catch(Exception e){
           e.printStackTrace();
       }finally {
           try {
               fileOutputStream.flush();
               fileOutputStream.close();
           }catch (IOException e){
               e.printStackTrace();
           }
       }
   }

【问题讨论】:

  • 什么是 DrawingActivity.path ?它有什么价值?
  • 我想你可能刚刚解决了我的问题.. 这是一个静态字段,一旦我保存图像就会设置。 path = cw.getDir("文件", Context.MODE_PRIVATE).toString();显然,除非我调用此方法,否则它永远不会设置。我想我应该找到一种方法让它以某种方式全局设置..
  • 我已经解决了这个问题,感谢您的帮助:)。注意到我在更新中的更改。
  • General Wau 如果您找到问题的答案,请将其添加为答案...即自己回答您自己的问题并接受它。这样其他人就会知道它已解决,并且将来也会帮助其他人。顺便说一句,欢迎您,祝您编码愉快:)
  • 不妨自己回答,这样我就可以将其标记为解决方案。你暗示了这个问题:)如果它增加了信用或积分等..

标签: java android image android-recyclerview


【解决方案1】:

确保showImages() 中的变量DrawingActivity.path 在其中有一些值。它可能没有正确初始化。

【讨论】:

    【解决方案2】:

    尝试将其放入 ViewHolder 类构造函数中

    setImageFromPath(galleryList.get(getLayoutPosition()).getPath(), holder.img);
    

    【讨论】:

    • 我通过实例化上下文包装器然后从中获取文件夹路径来修复它。然后我直接在 show images 方法中喂它。 path = cw.getDir("文件", Context.MODE_PRIVATE).toString();我也尝试了您的建议,但由于某种原因问题仍然存在:)
    猜你喜欢
    • 1970-01-01
    • 2014-10-19
    • 2021-05-16
    • 1970-01-01
    • 1970-01-01
    • 2019-06-08
    • 2013-03-24
    • 2013-03-17
    • 2013-03-02
    相关资源
    最近更新 更多