Получите ширину родительского макета
Android Studio 2.0 beta 6
Я пытаюсь использовать ViewPropertyAnimator для перемещения ImageView (ivSettings)
внутри панели инструментов, так что это 20dp справа и 20dp сверху, откуда текущее местоположение. И переместить ImageView (ivSearch)
20dp слева и сверху.
ImageViews содержатся в Toolbar
,
Это начальное состояние, и я хочу переместить значки в верхние углы на панели инструментов.
Я использую код, чтобы получить ширину, а затем вычесть значение, чтобы получить значение ivSettings, равное 20 dp справа.
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();
Однако, попробовав это на другом размере экрана, я не могу получить точный расчет ширины. Есть ли лучший способ сделать это?
Большое спасибо за любые предложения
2 ответа
Вы должны быть в состоянии использовать translationX
а также translationY
свойства для достижения желаемого эффекта. Эти свойства действуют как смещения от исходных координат X и Y вида.
По сути, translationX сместит a View вправо для положительного значения и влево для отрицательного значения из его координаты X. Точно так же translationY смещает View в нижнюю часть для положительных значений и top для отрицательных значений из своей координаты Y.
Возвращаясь к вашему вопросу, я предполагаю, что конечной позицией, которую вы хотите достичь, является верхний левый угол для значка поиска и верхний правый угол для значка настроек с добавлением нуля для каждого вида.
Для значка поиска я предлагаю вам начать с размещения его в верхнем левом углу панели инструментов. Затем установите для translationX и translationY значение 20p. Это должно разместить значок поиска в том же месте, что и ваше изображение. Чтобы переместить значок поиска в верхнем левом углу, все, что вам нужно сделать, это анимировать перевод X & Y от 20 дп до 0 дп.
Повторите то же самое для значка настроек, но установите translationX на -20dp и translationY на 20dp. Таким образом, он будет размещен в той же позиции, что и ваше изображение. Анимируйте оба значения до 0, чтобы добиться желаемой анимации.
Вот код анимации для справки.
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());
Самое замечательное в этом подходе заключается в том, что вам больше не нужно знать размеры родителя. Все, что вас волнует, это смещения, которые вы указали с помощью translationX
а также translationY
,
Я считаю, что проблема в том, что методы Animator ожидают, что значения будут в необработанных пиксельных значениях. Похоже, код будет работать только так, как вы собираетесь на экране средней плотности. Например, для экрана hdpi потребуется 30 пикселей, а не 20 пикселей в том же месте. На экранах с более высокой плотностью код в том виде, в котором он существует, подталкивает значки ближе к краям...
Это означает, что нам нужно преобразовать ожидаемое значение dp в необработанные значения пикселей и использовать их для анимации. Существует удобный метод для преобразования dp в px, чтобы он был корректным на каждом устройстве. Я предполагаю, что вы хотите, чтобы левая сторона шестерни находилась на 160dp от правой (обратите внимание, я специально говорю, что левая сторона шестерни, потому что значение 160dp также должно включать ширину изображения шестерни, так как свойство x слева от изображения). Так 160dp = ширина изображения шестерни + желаемое расстояние до правого края. Предположим, у вас есть ресурс 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();
Также проверьте смещения (заполнение) шестерни и значок поиска перед перемещением, поскольку это, вероятно, также повлияет на конечный результат.