我如何通过代码改变视图的位置?比如改变它的X、Y位置。这是可能的吗?
若要在Honeycomb(API Level 11)及以下版本中使用,您需要使用setLayoutParams(...)
。
如果您只需支持Honeycomb及更高版本,则可以使用setX(...)
,setY(...)
,setLeft(...)
,setTop(...)
等方法。
是的,在Android中可以动态设置视图的位置。同样地,在XML文件中的LinearLayout
中有一个ImageView
,因此您可以通过LayoutParams
设置其位置。但请确保根据XML文件中采用的布局来使用LayoutParams
。 根据所采用的布局,有不同的LayoutParams
。
以下是设置代码:
LayoutParams layoutParams=new LayoutParams(int width, int height);
layoutParams.setMargins(int left, int top, int right, int bottom);
imageView.setLayoutParams(layoutParams);
如果您可以等待布局周期,并且父视图组支持MarginLayoutParams
(或其子类),请相应地设置marginLeft
/ marginTop
。
如果您需要立即和持久地更改位置(例如用于弹出菜单锚点),请使用相同的坐标调用layout(l, t, r, b)
。这将预先阻止布局系统稍后确认的操作。
对于立即(临时)更改(例如动画),请使用setX()
/ setY()
。在父大小不依赖于WRAP_CHILDREN的情况下,仅使用setX()
/ setY()
可能是可以接受的。
永远不要使用setLeft()
/ setRight()
/ setBottom()
/ setTop()
,请参见下文。
背景: mLeft
/ mTop
/ mBottom
/ mRight
字段从layout()中的相应LayoutParams中填充。布局由Android视图布局系统隐式异步调用。因此,设置MarginLayoutParams
似乎是设置位置的最安全和最清洁的方法。但是,在某些情况下,例如使用View渲染光标,并且它应该同时重新定位并作为弹出菜单锚点,异步布局滞后可能会成为问题。在这种情况下,对我而言,调用layout()
效果很好。
setLeft()
和setTop()
的问题是:
仅调用它们是不够的 - 您还需要调用setRight()
和setBottom()
以避免拉伸或缩小视图。
这些方法的实现看起来相对复杂(=执行一些工作以考虑它们引起的视图大小更改)
它们似乎会导致输入字段出现奇怪的问题:EditText软数字键盘有时不允许输入数字
setX()
和setY()
在布局系统之外工作,并且相应的值被视为布局系统确定的左/上/下/右值的附加偏移量,相应地移动视图。它们似乎是为动画添加的(需要立即生效而不经过布局周期)。
setLayoutParams
和new FrameLayout.LayoutParams(width, height)
来设置marginLeft
,从而实现布局。 - lucidbrot有一个名为NineOldAndroids的库,它允许您在所有版本中使用Honeycomb动画库,从版本一开始。
这意味着您可以使用略微不同的接口定义左、右、translationX/Y等参数。
以下是它的工作原理:
ViewHelper.setTranslationX(view, 50f);
你只需要使用ViewHelper类中的静态方法,传递要设置的视图和值即可。
我建议使用 setTranslationX
和 setTranslationY
。虽然我自己也只是刚刚开始学习这个,但这似乎是移动视图最安全和首选的方法。我猜这很大程度取决于你具体要做什么,但对于我的2D动画效果而言,这种方法运作良好。
如果你正在使用 HoneyComb Sdk(API Level 11),你可以尝试使用以下方法。
view.setX(float x);
参数x是此视图的水平位置。
view.setY(float y);
y参数是视图在y轴上的位置。
希望对您有所帮助。:)
如果需要支持所有API级别,您可以像这样使用它:
ViewPropertyAnimator.animate(view).translationYBy(-yourY).translationXBy(-yourX).setDuration(0);
将此视图的左侧位置相对于其父级设置:
view.setLeft(int leftPosition);
将此视图相对于其父视图设置正确的位置:
view.setRight(int rightPosition);
设置此视图相对于其父视图的顶部位置:
view.setTop(int topPosition);
将此视图相对于其父视图设置底部位置:
view.setBottom(int bottomPositon);
使用LayoutParams。 如果您正在使用LinearLayout,则必须导入android.widget.LinearLayout.LayoutParams,否则导入适合您所使用的布局的正确版本的LayoutParams,否则将会引起ClassCastException,然后:
LayoutParams layoutParams = new LayoutParams(int width, int height);
layoutParams.setMargins(int left, int top, int right, int bottom);
imageView.setLayoutParams(layoutParams);
在 Kotlin 中,您可以按以下方式完成:
view
.animate()
.x(50f)
.y(100f)
.duration = 500L