2013-03-11 20 views
10

Attualmente sto sviluppando un'applicazione Android che visualizza più immagini (come ImageView's) impilate l'una sull'altra. Ecco come gli strati sono attualmente configurati: stratoCome impedire il metodo onClick sulla parte trasparente di ImageView caricato con PNG

  • Priorità: scale l'intero schermo, devono essere selezionabili
  • livello di primo piano: scale l'intero schermo, deve essere cliccabile, contiene trasparenza che permette all'utente di vedere parte del livello di sfondo

Il problema che devo affrontare è con il livello in primo piano. Sto assegnando il metodo onClick() alla vista di immagini, ma il metodo viene chiamato sia che colpiscano la parte dell'immagine che è visibile sia la parte che contiene la trasparenza. Voglio solo che venga chiamato il metodo ImageView onClick() in primo piano quando l'utente fa clic su una porzione di tale visualizzazione che non è trasparente.

questo è ciò che lo scenario assomiglia:

enter image description here

Le linee diagonali rappresentano la porzione trasparente dell'immagine in primo piano. Se un utente tocca questo spazio, voglio che acceda all'immagine di sfondo invece dell'immagine in primo piano. Grazie per l'assistenza che puoi fornire.

Ecco la soluzione ho implementato (Grazie a risposta qui sotto):

//ontouchlistener - gets X and Y from event 
private void setClick(View view) 
{ 
    view.setOnTouchListener(new View.OnTouchListener() 
    { 
     public boolean onTouch(View v, MotionEvent event) 
     { 
      int imageId = getImageId((int)event.getX(), (int)event.getY()); 
      if (imageId >= 0) 
       performActions(imageId); 
      return false; 
     } 
    }); 
} 

//get the ID of the first imageview (starting from foreground, 
//working backwards) which contains a non-transparent pixel 
private int getImageId(int x, int y) 
{ 
    ViewGroup parent = (ViewGroup) findViewById(R.id.relative_layout); 
    for (int a = parent.getChildCount()-1; a >= 0; a--) 
    { 
     if (parent.getChildAt(a) instanceof ImageView) 
      if (!checkPixelTransparent((ImageView)parent.getChildAt(a), x, y)) 
       return parent.getChildAt(a).getId(); 
    } 
    return -1; 
} 

//get bitmap from imageview, get pixel from x, y coord 
//check if pixel is transparent 
private boolean checkPixelTransparent(ImageView iv, int x, int y) 
{ 
    Bitmap bitmap = ((BitmapDrawable) iv.getDrawable()).getBitmap(); 
    if (Color.alpha(bitmap.getPixel(x, y)) == 0) 
     return true; 
    else 
     return false; 
} 
+2

cercare di non avere una parte trasparente. ritaglia l'immagine per rimuovere le parti trasparenti se puoi – njzk2

+0

grazie per il tuo commento, ma alcune delle immagini in primo piano sono molto complesse e non possono essere ritagliate – sngreco

+0

quindi devi guardare dentro i pixel dell'immagine e confrontare con trasparente – njzk2

risposta

28

This one sample rende l'area trasparente di ImageView non selezionabile.

ImageView:

ImageView imgView= (ImageView) findViewById(R.id.color_blue); 
imgView.setDrawingCacheEnabled(true); 
imgView.setOnTouchListener(changeColorListener); 

OnTouchListener:

private final OnTouchListener changeColorListener = new OnTouchListener() { 

    @Override 
    public boolean onTouch(View v, MotionEvent event) { 
     Bitmap bmp = Bitmap.createBitmap(v.getDrawingCache()); 
     int color = bmp.getPixel((int) event.getX(), (int) event.getY()); 
     if (color == Color.TRANSPARENT) 
      return false; 
     else { 
      //code to execute 
      return true; 
     } 
    } 
}; 
+1

So che questo è vecchio, ma questa è un'ottima risposta. Mi hai aiutato così tanto! – Phil3992

+3

Se si desidera utilizzarlo come OnClick, è necessario aggiornare // codice da eseguire se (event.getAction() == MotionEvent.ACTION_UP) {/ * codice da eseguire * /}. – Mateu

+2

ho dovuto aggiungere v.buildDrawingCache(), se non è stata sollevata una npe – Borja

3

Se l'immagine in primo piano non è solo un rettangolo, ma un'immagine complessa e si ha realmente bisogno che il tocco è pixel -precise, è possibile utilizzare

http://developer.android.com/reference/android/view/View.OnTouchListener.html

foregroundImage.setOnTouchListener(new View.OnTouchListener(){...}); 

Lo MotionEvent nella richiamata conterrà il tipo di azione eseguita (ad es. Ritocco) e la posizione esatta.

Se si conosce la dimensione esatta dell'immagine in primo piano così come viene visualizzata, è possibile capire quale pixel è stato cliccato, quindi controllare se l'alfa del pixel è 0. Oppure potrebbe essere necessario applicare un ridimensionamento se l'immagine è stato ridimensionato. Ciò potrebbe risultare piuttosto complicato poiché, a seconda delle dimensioni dello schermo e delle proporzioni, l'immagine potrebbe essere stata ridimensionata/posizionata in modo diverso. Ciò dipende anche dai layout che stavi usando.

Per il controllo del valore del pixel è necessario conservare in memoria l'oggetto Bitmap che contiene anche i dati dell'immagine in primo piano.

Francamente, dubito che avresti davvero bisogno di tutta quella precisione a meno che l'immagine in primo piano non abbia davvero una forma molto irregolare.

+0

Fammi vedere se capisco - Usa OnTouchListener per determinare il pixel selezionato, quindi controlla l'alfa del pixel in tutte le immagini a partire dal fronte all'indietro – sngreco

+0

grazie per l'aiuto iseeall, ho aggiornato la mia domanda con la soluzione i costruito dalla tua risposta – sngreco

Problemi correlati