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