获取父布局的宽度
Get the width of the parent layout
Android Studio 2.0 beta 6
我正在尝试使用 ViewPropertyAnimator 将 ImageView (ivSettings)
移动到工具栏内,使其距右侧 20dp,距顶部 20dp,从当前位置开始。并将 ImageView (ivSearch)
从左侧和顶部移动 20dp。
imageView 包含在 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();
但是,在不同的屏幕尺寸上尝试过后,我无法得到准确的宽度计算结果。有更好的方法吗?
非常感谢任何建议
我认为问题在于 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();
在移动之前还要检查齿轮和搜索图标的偏移量(填充),因为这也可能会影响最终结果。
您应该可以使用 translationX
和 translationY
属性来达到您想要的效果。这些属性充当视图原始 X 和 Y 坐标的偏移量。
本质上,translationX 会将视图从其 X 坐标向右移动以获得正值,向左移动以获得负值。类似地,translationY 将视图从其 Y 坐标移向底部以获得正值,将视图移向顶部以获得负值。
关于你的问题,我假设你想要到达的最终位置是搜索图标的左上角,以及设置图标的右上角,每个视图的填充为零。
对于搜索图标,我建议您先将其放在工具栏的左上角。然后将 translationX 和 translationY 都设置为 20p。这应该将搜索图标放在与您的图像相同的位置。要将搜索图标移动到左上角,您只需将 translationX 和 Y 从 20dp 动画化到 0dp。
对设置图标重复相同的操作,但将 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
指定的偏移量。
Android Studio 2.0 beta 6
我正在尝试使用 ViewPropertyAnimator 将 ImageView (ivSettings)
移动到工具栏内,使其距右侧 20dp,距顶部 20dp,从当前位置开始。并将 ImageView (ivSearch)
从左侧和顶部移动 20dp。
imageView 包含在 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();
但是,在不同的屏幕尺寸上尝试过后,我无法得到准确的宽度计算结果。有更好的方法吗?
非常感谢任何建议
我认为问题在于 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();
在移动之前还要检查齿轮和搜索图标的偏移量(填充),因为这也可能会影响最终结果。
您应该可以使用 translationX
和 translationY
属性来达到您想要的效果。这些属性充当视图原始 X 和 Y 坐标的偏移量。
本质上,translationX 会将视图从其 X 坐标向右移动以获得正值,向左移动以获得负值。类似地,translationY 将视图从其 Y 坐标移向底部以获得正值,将视图移向顶部以获得负值。
关于你的问题,我假设你想要到达的最终位置是搜索图标的左上角,以及设置图标的右上角,每个视图的填充为零。
对于搜索图标,我建议您先将其放在工具栏的左上角。然后将 translationX 和 translationY 都设置为 20p。这应该将搜索图标放在与您的图像相同的位置。要将搜索图标移动到左上角,您只需将 translationX 和 Y 从 20dp 动画化到 0dp。
对设置图标重复相同的操作,但将 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
指定的偏移量。