2016-03-08 13 views
12
Android Studio 2.0 beta 6 

Sto cercando di utilizzare ViewPropertyAnimator per spostare un ImageView (ivSettings) all'interno di una barra degli strumenti in modo che sia 20dp da destra e 20dp dall'alto, dalla posizione corrente è. E sposta il ImageView (ivSearch) 20dp da sinistra e in alto.ottenere la larghezza del layout genitore

Le immagini sono contenute in un Toolbar.

Questo è lo stato iniziale e voglio spostare le icone negli angoli superiori all'interno della barra degli strumenti.

enter image description here

Il codice che sto usando è questo per ottenere la larghezza e quindi sottrarre un valore per ottenere i ivSettings di essere 20dp da destra.

final DisplayMetrics displayMetrics = new DisplayMetrics(); 
getActivity().getWindowManager().getDefaultDisplay().getMetrics(displayMetrics); 
final float widthPx = displayMetrics.widthPixels; 

ivSearch.animate() 
    .setInterpolator(new AccelerateInterpolator()) 
    .x(20) 
    .y(20) 
    .setDuration(250) 
    .start(); 

ivSettings.animate() 
    .setInterpolator(new AccelerateInterpolator()) 
    .x(widthPx - 160) 
    .y(20) 
    .setDuration(250) 
    .start(); 

Tuttavia, dopo aver provato questo su diverse dimensioni dello schermo non riesco a ottenere il calcolo della larghezza esatta. C'è un modo migliore per farlo?

Molte grazie per qualsiasi suggerimento

+0

Prova a utilizzare la larghezza dalla barra degli strumenti. – Piyush

+0

Ho impostato la larghezza su "match_parent", quindi toolbar.getWidth() restituirà sempre 0. – ant2009

+0

Stai convertendo dp in pixel o larghezzaPx - 160 l'espressione per il calcolo della larghezza su ciascun dispositivo? – Piyush

risposta

7

Dovresti essere in grado di utilizzare le proprietà translationX e translationY per ottenere l'effetto desiderato. Queste proprietà agiscono come offset dalle coordinate X e Y originali della vista.

Essenzialmente la traduzioneX sposta la vista a verso destra per un valore positivo e lascia un valore negativo dalla sua coordinata X. Analogamente la traduzioneY sposta la vista verso il basso per i valori positivi e superiori per i valori negativi dalla sua coordinata Y.

Venendo alla tua domanda, presumo che la posizione finale che vuoi raggiungere sia l'angolo in alto a sinistra per l'icona di ricerca, e l'angolo in alto a destra per l'icona delle impostazioni con padding zero per ogni vista.

Per l'icona di ricerca suggerisco di iniziare posizionandola nell'angolo in alto a sinistra della barra degli strumenti. Quindi imposta sia la traduzioneX che la traduzioneY a 20p. Questo dovrebbe posizionare l'icona di ricerca nella stessa posizione dell'immagine. Per spostare la tua icona di ricerca in alto a sinistra, tutto ciò che devi fare è animare la traduzioneX & Y da 20dp a 0 dp.

Ripetere lo stesso per l'icona delle impostazioni, ma impostare translationX su -20dp e translationY su 20dp. In questo modo verrà posizionato nella stessa posizione dell'immagine. Animare entrambi i valori su 0 per ottenere l'animazione desiderata.

Ecco il codice di animazione per riferimento.

ivSearch.animate() 
    .setInterpolator(new AccelerateInterpolator()) 
    .translationX(0) // Takes value in pixels. From 20dp to 0dp 
    .translationY(0) // Takes value in pixels. From 20dp to 0dp 
    .setDuration(250) 
    .start(); 

ivSettings.animate() 
    .setInterpolator(new AccelerateInterpolator()) 
    .translationX(0) // Takes value in pixels. From -20dp to 0dp 
    .translationY(0) // Takes value in pixels. From 20dp to 0dp 
    .setDuration(250) 
    .start(); 

// To get pixels from dp 
float px = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, getResources().getDisplayMetrics()); 

Il bello di questo approccio è che non è più necessario conoscere le dimensioni del genitore. Tutto quello che ti interessa sono gli offset che hai specificato tramite translationX e translationY.

5

Credo che il problema è che i metodi Animator si aspettano i valori di essere in valori di pixel prime. Sembra che il codice funzioni solo se lo desideri su uno schermo a media densità. Per esempio. Uno schermo HDPI richiederebbe 30px invece di 20px per trovarsi nella stessa posizione. Su più alti schermi di densità del codice come esiste spingerebbe le icone più vicine ai bordi ...

Ciò significa che abbiamo bisogno di tradurre il valore di dp atteso in valori di pixel prime e usare quelli per l'animazione. C'è un metodo pratico per convertire dp in px in modo che sia corretto su ogni dispositivo. Suppongo che tu voglia che il lato sinistro della marcia sia 160dp da destra (Nota, sto specificando specificamente il lato sinistro della marcia perché il valore 160dp dovrebbe includere anche la larghezza dell'immagine dell'ingranaggio quando la proprietà x è dalla sinistra dell'immagine). Quindi 160dp = larghezza dell'immagine dell'ingranaggio + distanza del margine destro desiderata. Supponiamo di avere una risorsa chiamata ic_gear: Drawable drawable = getResources(). GetDrawable (R.drawable.ic_gear); float bitmapWidth = getIntrinsicWidth();

float rawPX20DPValue = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 20, getResources().getDisplayMetrics()); 

float rawPXLeftOffset = rawPX20DPValue + bitmapWidth; 

ivSearch.animate() 
    .setInterpolator(new AccelerateInterpolator()) 
    .x(rawPX20DPValue) 
    .y(rawPX20DPValue) 
    .setDuration(250) 
    .start(); 


ivSettings.animate() 
    .setInterpolator(new AccelerateInterpolator()) 
    .x(widthPx - rawPXLeftOffset) 
    .y(rawPX20DPValue) 
    .setDuration(250) 
    .start(); 

controllo anche sulle compensazioni (padding) della marcia e icona di ricerca prima che la mossa come che probabilmente influenzerà il risultato finale pure.

+0

Il valore 160 era qualcosa con cui stavo solo giocando. Quello che sto cercando di fare è animare entrambe le immagini in modo che quella di sinistra sia 20 pp dalla sinistra della barra degli strumenti, e quella di destra sarà 20 pp dalla destra della barra degli strumenti. Per quello di destra, quello che stavo cercando di fare è calcolare la larghezza totale della barra degli strumenti e quindi sottrarre un valore per renderlo 20dp dal margine destro. Spero che tu capisca di più ora. Grazie. – ant2009

+0

@ ant2009 L'ho aggiornato per darti il ​​calcolo della dimensione dell'immagine. Si noti che se si dispone di riempimento su ImageView, sarà necessario aggiungerlo nel calcolo. Fammi sapere se hai bisogno di ulteriore aiuto :) –