2016-02-25 58 views
8

我有一个RecyclerView适配器,它具有许多不同的ViewHolders。其中一个ViewHolders包含一个ImageView,它需要能够拍照,调整大小,然后显示它。对于模块性,我希望ViewHolder是独立的:它不是父级活动应该处理与照片拍摄和显示过程有关的所有事情。此外,文件路径是不变的(它永远不会改变)。实际上,它是/storage/emulated/0/com.company.app/myst/cat.jpg。因此,这里是我实现ImageView的onClick方法。如果方向改变,相机不会覆盖旧图像

@Override 
public void onClick(View v) { 
    final FragmentManager fm = ((MyActivity) getContext()).getSupportFragmentManager(); 
    Fragment auxiliary = new Fragment() { 
     @Override 
     public void onActivityResult(int requestCode, int resultCode, Intent data) { 
      resizeResaveAndDisplayPhoto(); 
      super.onActivityResult(requestCode, resultCode, data); 
      fm.beginTransaction().remove(this).commit(); 
     } 
    }; 
    fm.beginTransaction().add(auxiliary, "FRAGMENT_TAG").commit(); 
    fm.executePendingTransactions(); 

    Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); 
    if (null != takePictureIntent.resolveActivity(view.getContext().getPackageManager())) { 
     ((MyActivity)view.getContext()).setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); 
     takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(photoFile)); 
     auxFragment.startActivityForResult(takePictureIntent, Constants.REQUEST_CODE_PHOTO); 
    } 
} 

resizeResaveAndDisplayPhoto把它叫做执行下面的AsyncTask

public static class ResizeThenLoadImageTask extends AsyncTask<String, Void, Bitmap> { 

    private final WeakReference<ImageView> imageViewWeakReference; 
    private final WeakReference<File> fileWeakReference; 
    private final WeakReference<Context> weakContext; 
    private final int reqHeight; 
    private final int reqWidth; 

    public ResizeThenLoadImageTask(Context context, ImageView imageView, File file, int reqHeight, int reqWidth) { 
     weakContext = new WeakReference<Context>(context); 
     imageViewWeakReference = new WeakReference<>(imageView); 
     fileWeakReference = new WeakReference(file); 
     this.reqHeight = reqHeight; 
     this.reqWidth = reqWidth; 
    } 

    @Override 
    public Bitmap doInBackground(String... params) { 
     File file = fileWeakReference.get(); 
     Bitmap bitmap = null; 
     if (null != file) { 
      bitmap = ImageUtils.reduceImageSize(file, reqHeight, reqWidth); 
      ImageUtils.saveBitmapToGivenFile(bitmap, file); 
     } 
     return bitmap; 
    } 

    @Override 
    public void onPostExecute(Bitmap bitmap) { 
     if (null != imageViewWeakReference && null != fileWeakReference) { 
      ImageView imageView = imageViewWeakReference.get(); 
      File file = fileWeakReference.get(); 
      if (null != imageView) { 
       if (null != bitmap) { 
        imageView.setImageBitmap(bitmap); 
       } 
       else { 
        imageView.setImageResource(R.drawable.photo); 
       } 
       imageView.postDelayed(new Runnable() { 
        @Override 
        public void run() { 
         if (null != weakContext.get()) { 
          ((MyActivity) weakContext.get()).setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED); 
         } 
        } 
       }, 10000); 
      } 
     } 
    } 
} 

您可能注意到,我拍摄照片之前锁定的方位和显示照片后解锁10秒。那个技巧是我的疑难解答的一部分。所以情况就是这样。上述系统工作得很好。在以下情况下发生问题

  • 说我已经在ImageView中有一张照片,但想要替换它。
  • 所以我点击ImageView拍摄一张新照片。
  • 如果我旋转设备拍摄新照片,然后在旧照片返回之前短暂返回新的照片显示。
  • 所以我锁定方向,看看发生了什么。这是我发现的。
  • 只要我锁定方向,新照片就会显示。一旦方向解锁(10秒),旧照片就会返回。
  • 如果我离开活动和退货,旧照片仍在显示。
  • 如果我完全关闭应用程序然后返回,那么我会看到新照片。
+0

所以我用了三分之一的要点来问这个问题。请给出有意义的答案。 –

+0

您是否仅面向此方向或仅始终显示默认图像? –

+0

向我们展示何时首次创建“活动”或在方向更改时重新创建的代码,其中您将位图从文件加载到“ImageView”中。 –

回答

0

当设备旋转时,会重新创建运行活动以及连接到它的asyncTask,可能会导致泄漏。

您可能需要在服务内部调用asyncTask,而不是在活动中,以便将asyncTask附加到服务的生命周期。

+0

你的答案忽略了一点。它并不能解释为什么文件内容会回滚到前一张照片。请阅读整个问题。 –

+0

以前的语言太混乱了。所以我编辑了文本。 –

+0

我不确定我的答案是否能解决您的问题,是吗?如果是这样,我会编辑我的答案,试图解释为什么文件内容会回滚到前一张照片,如果没有,它没有意义尝试解释它。 – cherif