2016-07-16 107 views
5

Questa è una situazione difficile da descrivere, quindi per favore portami con me. Mi è stato chiesto di fare una programmazione 'segni dei pullman' un po 'come questo:Android - disegno ImageView precisamente sulla parte superiore della vista esistente nel livello più profondo

enter image description here

Tuttavia, nel mio caso ho bisogno di 'tirare' alcune delle immagini sottostanti per la parte anteriore e visualizzarle in un colore diverso per farli risaltare. Non riesco a determinare quale sarà il 'frame' di queste immagini prima del tempo di esecuzione. Il mio approccio è di aggiungere una vista semiopaca nera (che io chiamo una "tenda") che copre l'intero schermo, e quindi aggiungere le immagini di cui ho bisogno come sottoview della tenda con un colore diverso. EDIT Questa parte è facile e non sto chiedendo aiuto per questo (motivo per cui il suggerimento che questo è un duplicato della domanda suggerita non è corretto).

Non credo di poter utilizzare bringToFront() o setTranslationZ() perché questi metodi non porteranno il ImageView fino in fondo alla mia tenda. Quindi, quello che sto cercando di fare è ottenere il 'frame' esatto della vista dell'immagine (la sua x, y, larghezza e altezza) relativo allo schermo generale e quindi provare ad aggiungere la nuova vista dell'immagine usando lo stesso disegnabile con la stessa cornice.

È anche importante sapere che la "vista" sottostante è in realtà composta da più viste (incluso un cassetto scorrevole), motivo per cui ho bisogno di ottenere le coordinate relative allo schermo. Spero che abbia senso.

Sono in grado di disegnare il nuovo ImageView come visualizzazione secondaria della tenda con il colore corretto, ma la posizione e la dimensione dell'immagine sono lontane. Come posso disegnare questo nuovo ImageView esattamente sopra quello precedente?

Sono aperto anche ad altre strategie (poiché questa sembra non funzionare). Grazie per tutto l'aiuto.

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 

    ... 

    ViewTreeObserver vto = mRootview.getViewTreeObserver(); 
    vto.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { 
     @Override 
     public void onGlobalLayout() { 

      mRootview.getViewTreeObserver().removeOnGlobalLayoutListener(this); 

      mDrawerLayout.openDrawer(Gravity.LEFT); 

      RelativeLayout curtain = addOpaqueCurtainToRootView(); 
      int frame[] = getFrameOfExistingImageView(); 
      addNewImageViewOnTopOfEverything(curtain, frame); 
     } 
    }); 
} 

private RelativeLayout addOpaqueCurtainToRootView() { 
    RelativeLayout curtain = new RelativeLayout(context); 
    RelativeLayout.LayoutParams curtainParams = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.MATCH_PARENT); 
    curtain.setLayoutParams(curtainParams); 
    curtain.setBackgroundColor(Color.argb(179, 0, 0, 0)); //70% opaque 
    mRootview.addView(curtain); 
    return curtain; 
} 

private int[] getFrameOfExistingImageView() { 
    // proving that I have a reference to the original image 
    mCurrentImage.setColorFilter(Color.rgb(255, 0, 0)); 

    int array[] = new int[2]; 
    mCurrentImage.getLocationOnScreen(array); 
    Log.d(TAG, "width: " + Integer.toString(array[0])); 
    Log.d(TAG, "height: " + Integer.toString(array[1])); 
    Log.d(TAG, "x: " + Float.toString(mCurrentImage.getX())); 
    Log.d(TAG, "y: " + Float.toString(mCurrentImage.getY())); 

    int frame[] = new int[4]; // x,y,width,height 
    frame[0] = (int)mCurrentImage.getX(); 
    frame[1] = (int)mCurrentImage.getY(); 
    frame[2] = array[0]; 
    frame[3] = array[1]; 
    return frame; 
} 

private void addNewImageViewOnTopOfEverything(RelativeLayout curtain, int[] frame) { 
    ImageView iv = new ImageView(context); 
    iv.setImageResource(R.drawable.imgView); 
    iv.setColorFilter(Color.rgb(255, 255, 255)); 
    iv.setX(frame[0]); 
    iv.setY(frame[1]); 
    iv.setLayoutParams(new RelativeLayout.LayoutParams(frame[2], frame[3])); 

    curtain.addView(iv); 
} 
+0

Possibile duplicato di [Come creare attività trasparenti in Android?] (Http://stackoverflow.com/questions/16332064/how-to-create-transparent-activity-in-android) – user5599807

+1

provare [questo] (http : // pastebin.com/dg4CXx0f) – pskink

+0

@ user5599807 - non un duplicato. Quel post richiede solo una domanda molto semplice, che è come disegnare una vista con uno sfondo semitrasparente. Lo sto già facendo (facilmente). La mia domanda riguarda come posizionare viste secondarie su quella nuova vista in una posizione precisa e con una dimensione precisa. – Alex

risposta

0

L'ho capito. Ho avuto due problemi di base.

In primo luogo, stavo ottenendo il telaio del ImageView tutto sbagliato. Avevo bisogno di ottenere le coordinate sinistra e superiore e anche l'altezza e la larghezza dell'immagine dopo che è stata disegnata. Questo è come mi sto facendo che (In realtà sto conversione a sinistra, in alto, a destra, in basso, ma il resto è facile):

private int[] getFrameOfImageView(ImageView imageView) { 

    int array[] = new int[2]; 
    imageView.getLocationOnScreen(array); 

    int frame[] = new int[4]; 

    frame[0] = array[0]; // left 
    frame[1] = array[1]; // top 
    frame[2] = array[0] + imageView.getWidth(); // right 
    frame[3] = array[1] + imageView.getHeight(); // bottom 

    return frame; 
} 

Poi, ho creato una nuova classe per fare il disegno. Questa è la più grande differenza dal mio OP. Inizialmente, stavo pensando che avrei potuto aggiungere questo come nuovo ImageView e impostare il suo LayoutParams per posizionarlo dove volevo. Invece, ho finito con Paint e Canvas a fare il disegno, il dimensionamento e il posizionamento:

public class CanvasPainter extends View { 

    Context mContext; 
    Drawable mDrawable; 

    int mFrame[]; 
    int left; 
    int top; 
    int right; 
    int bottom; 
    int width; 
    int height; 

    private final int LEFT = 0; 
    private final int TOP = 1; 
    private final int RIGHT = 2; 
    private final int BOTTOM = 3; 

    public CanvasPainter(Context context, int frame[], Drawable drawable) { 
     super(context); 

     mContext = context; 
     mFrame = frame; 
     mDrawable = drawable; 

     left = frame[LEFT]; 
     top = frame[TOP]; 
     right = frame[RIGHT]; 
     bottom = frame[BOTTOM]; 
     width = right - left; 
     height = bottom - top; 

    } 

    public void onDraw(Canvas canvas) { 
     Paint paint = new Paint(); 
     paint.setStyle(Paint.Style.FILL); 


     Bitmap b = ((BitmapDrawable) mDrawable).getBitmap(); 
     Bitmap bitmapResized = Bitmap.createScaledBitmap(b, width, height, false); 

     canvas.drawBitmap(bitmapResized, left, top, paint); 
    } 
} 

Quindi, mettere questo insieme, tutto si organizza da onCreate() come questo;

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 

    ... 

    mDrawerLayout.openDrawer(Gravity.LEFT); 

    ViewTreeObserver vto = mRootview.getViewTreeObserver(); 
    vto.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { 
     @Override 
     public void onGlobalLayout() { 

      mRootview.getViewTreeObserver().removeOnGlobalLayoutListener(this); 

      RelativeLayout curtain = addOpaqueCurtainToRootView(); 
      int frame[] = getFrameOfExistingImageView(); 
      Drawable d = ContextCompat.getDrawable(context, R.drawable.imgView); 
      CanvasPainter canvasPainter = new CanvasPainter(context, mCurrentImg, frame, d); 
      curtain.addView(canvasPainter); 
     } 
    }); 
} 

potrebbe essere un po 'di un problema di oscuro, ma spero che questo aiuta qualcuno.