2016-02-25 50 views
8

Ho un adattatore RecyclerView con molte ViewHolder differenti. Uno dei ViewHolders contiene un ImageView, che deve essere in grado di scattare una foto, ridimensionarla, quindi visualizzarla. Per modularità, voglio che ViewHolder sia autonomo: non è l'attività principale che deve gestire tutto ciò che riguarda il processo di visualizzazione e visualizzazione delle foto. Anche il percorso del file è costante (non cambierà mai). Infatti, è /storage/emulated/0/com.company.app/myst/cat.jpg. Di conseguenza, ecco la mia implementazione del metodo onClick di ImageView.La fotocamera non sovrascrive la vecchia immagine se l'orientamento cambia

@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); 
    } 
} 

Quando resizeResaveAndDisplayPhoto è chiamato esegue il seguente 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); 
      } 
     } 
    } 
} 

Si può notare che ho bloccare l'orientamento prima di scattare la foto e sbloccarlo 10 secondi dopo la visualizzazione della foto. Quel trucco è parte della mia risoluzione dei problemi. Quindi ecco la situazione. Il sistema sopra descritto funziona molto bene. I problemi si verificano nel seguente caso

  • Dire che ho già una foto in ImageView ma voglio sostituirla.
  • Così clicco su ImageView per scattare una nuova foto.
  • Se ruoto il dispositivo per scattare la nuova foto, quando ritorno la visualizzazione della nuova foto brevemente prima che la vecchia foto ritorni.
  • Quindi mi blocco all'orientamento per vedere cosa stava succedendo. Ecco cosa ho trovato.
  • La nuova foto viene visualizzata finché si blocca l'orientamento. Non appena l'orientamento si sblocca (10 sec), la vecchia foto ritorna.
  • Se esco dall'attività e dai resi, la vecchia foto continua a essere visualizzata.
  • Se chiudo completamente l'app e quindi ritorno, quindi vedo la nuova foto.
+0

Quindi uso un terzo dei miei punti per porre questa domanda. Per favore, dare risposte significative. –

+0

stai affrontando questo problema solo sull'orientamento o solo l'immagine predefinita viene visualizzata continuamente? –

+0

Mostraci il codice per quando il 'Activity' viene prima creato o ricreato sul cambio di orientamento, dove carichi la bitmap dal file in' ImageView'. –

risposta

0

Quando il dispositivo viene ruotato, viene ricreata anche l'attività in esecuzione e il asyncTask ad esso collegato, causando probabilmente una perdita.

Probabilmente è necessario chiamare il asyncTask all'interno di un servizio invece in un'attività in modo che asyncTask sia collegato al ciclo di vita del servizio.

+0

La tua risposta manca il punto. Non spiega perché il contenuto del file torna alla foto precedente. Per favore, leggi tutta la domanda –

+0

la lingua precedente era troppo confusa. Quindi ho modificato il testo. –

+0

Non sono sicuro che la mia risposta risolva il problema, vero? Se lo fa, modifico la mia risposta cercando di spiegare perché il contenuto del file torna alla foto precedente, se non lo fa, non ha senso cercare di spiegarlo. – cherif