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

próbuję użyć ViewPropertyAnimator przenieść ImageView (ivSettings) wewnątrz paska tak, że jest 20dp z prawej strony i 20dp od góry, ze jest aktualna lokalizacja. I przenieś ImageView (ivSearch) 20dp od lewej i od góry.Get szerokość układu nadrzędnego

Obrazy są zawarte w Toolbar.

To jest stan początkowy i chcę przenieść ikony do górnych rogów wewnątrz paska narzędzi.

enter image description here

Kod używam jest to, aby uzyskać szerokość i odejmujemy wartość, aby uzyskać ivSettings być 20dp z prawej strony.

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(); 

Jednak po wypróbowaniu tego na innym rozmiarze ekranu nie mogę uzyskać dokładnej kalkulacji szerokości. Czy jest lepszy sposób na zrobienie tego?

Wielkie dzięki za wszelkie sugestie

+0

Spróbuj zamiast tego użyć szerokości z paska narzędzi. – Piyush

+0

Ustawiłem szerokość na 'match_parent', więc toolbar.getWidth() zawsze zwróci 0. – ant2009

+0

Czy konwertujesz dp na piksel, czy też widthPx - 160 to wyrażenie do obliczania szerokości na każdym urządzeniu? – Piyush

Odpowiedz

7

Powinieneś być w stanie używać właściwości translationX i translationY, aby uzyskać pożądany efekt. Te właściwości działają jako przesunięcia względem oryginalnych współrzędnych X i Y widoku.

Zasadniczo tłumaczenieX przesunie widok w prawo, aby uzyskać wartość dodatnią, a następnie pozostawić wartość ujemną z jego współrzędnej X. Podobnie transly przesuwa widok w kierunku dolnym dla dodatnich i górnych dla ujemnych wartości z jego współrzędnej Y.

Wychodząc do pytania, zakładam, że ostateczna pozycja, którą chcesz osiągnąć, to lewy górny róg ikony wyszukiwania oraz prawy górny róg ikony ustawień z zerowym wypełnieniem dla każdego widoku.

Dla ikony wyszukiwania sugeruję zacząć od umieszczenia jej w lewym górnym rogu paska narzędzi. Następnie ustaw zarówno tłumaczenieX, jak i tłumaczenieY na 20p. To powinno umieścić ikonę wyszukiwania w tym samym miejscu, co obraz. Aby przenieść ikonę wyszukiwania w lewym górnym rogu, wszystko, co musisz zrobić, to animować tłumaczenieX & Y z 20dp na 0 dp.

Powtórz to samo dla ikony ustawień, ale ustaw translacjęX na -20dp i tłumaczenieY na 20dp. W ten sposób zostanie umieszczony w tej samej pozycji, co obraz. Ożyw obie wartości do 0, aby uzyskać żądaną animację.

Oto kod animacji dla odniesienia.

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()); 

Wspaniałą cechą tego podejścia jest to, że nie trzeba już znać wymiarów rodzica. Wszystko, co Cię interesuje, to przesunięcia, które określiłeś za pomocą translationX i translationY.

5

Uważam, że problemem jest to, że metody Animator oczekują wartości będzie w surowych wartości pikseli. Wygląda na to, że kod działałby tylko tak, jak planujesz na ekranie o średniej gęstości. Na przykład. Ekran hdpi wymagałby umieszczenia w tej samej lokalizacji 30 pikseli zamiast 20 pikseli. Na ekranach o wyższej gęstości kod, jaki istnieje, przesuwa ikony bliżej krawędzi ...

To oznacza, że ​​musimy przetłumaczyć oczekiwaną wartość dp na nieprzetworzone wartości pikseli i użyć ich do animacji. Jest przydatna metoda konwersji dp na px, tak aby była poprawna na każdym urządzeniu. Zakładam, że chcesz, aby lewy bok biegu był 160dp od prawej (uwaga mówię konkretnie o lewej stronie biegu, ponieważ wartość 160dp powinna również zawierać szerokość obrazu koła zębatego, ponieważ właściwość x jest z lewej strony obrazu). Tak więc 160dp = szerokość obrazu przekładni + pożądana odległość prawego marginesu. Powiedzmy, że masz zasób o nazwie 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(); 

również sprawdzić na offsetu (dopełnienia) przekładni i ikoną wyszukiwania przed przeprowadzką jako że prawdopodobnie będzie wpływać na wynik końcowy, jak również.

+0

Wartość 160 była czymś, z czym właśnie się bawiłem. Próbuję zrobić animację obu obrazów, aby jeden z lewej strony był 20dp od lewej strony paska narzędzi, a prawa z 20dp od prawej strony paska narzędzi. Jeśli chodzi o prawo, to, co próbowałem zrobić, to obliczyć całkowitą szerokość paska narzędzi, a następnie odjąć wartość, aby była równa 20pp od prawego marginesu. Mam nadzieję, że teraz zrozumiesz więcej. Dzięki. – ant2009

+0

@ ant2009 Zaktualizowałem go, aby uzyskać obliczenia rozmiaru obrazu. Zauważ, że jeśli masz dopełnienie na ImageView, musisz dodać to również do obliczeń. Daj mi znać, jeśli potrzebujesz dalszej pomocy :) –

Powiązane problemy