如何在 Android 中动态设置视图的位置?

我如何通过代码改变视图的位置? 就像改变它的 X,Y 位置一样。这可能吗?

264091 次浏览

设置此视图相对于其父视图的左侧位置:

view.setLeft(int leftPosition);

设置此视图相对于其父视图的正确位置:

view.setRight(int rightPosition);

设置此视图相对于其父视图的顶部位置:

view.setTop(int topPosition);

设置此视图相对于其父视图的底部位置:

view.setBottom(int bottomPositon);

上述方法用于设置视图与其父视图相关的位置。

You can try to use the following methods, if you're using HoneyComb Sdk(API Level 11).

view.setX(float x);

参数 x 是该视图的可视化 x 位置。

view.setY(float y);

参数 y 是此视图的可视 y 位置。

我希望这对你有所帮助。 :)

使用 RelativeLayout,将视图放入其中,从视图中获取 RelativeLayout.LayoutParams对象,并根据需要设置边距。然后在视图中调用 requestLayout()。这是我唯一知道的方法。

是的,您可以在 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);

对于任何低于蜂窝(API 级别11)你必须使用 setLayoutParams(...)

If you can limit your support to Honeycomb and up you can use the setX(...), setY(...), setLeft(...), setTop(...), etc.

我建议使用 setTranslationXsetTranslationY。我自己才刚刚开始,但这似乎是最安全和首选的移动视图的方式。我想这在很大程度上取决于你到底想做什么,但这对我的2D 动画效果很好。

有一个称为 九代机器人的库,它允许您使用蜂巢动画库的所有方式下到版本1。

这意味着您可以使用稍微不同的接口定义 left、 right、 transationX/Y。

它是这样运作的:

ViewHelper.setTranslationX(view, 50f);

您只需使用 ViewHelper 类中的静态方法,传递视图以及希望将其设置为哪个值。

Use LayoutParams. 如果使用 LinearLayout,则必须导入 android.widget。线性布局。LayoutParams,否则导入正确版本的 LayoutParams 以适应您正在使用的布局,否则将导致 ClassCastException,然后:

LayoutParams layoutParams = new LayoutParams(int width, int height);
layoutParams.setMargins(int left, int top, int right, int bottom);
imageView.setLayoutParams(layoutParams);

注意,你也可以使用 imageView.setLeft (int dim) ,但是这个 WO 不会设置组件的位置,它只会设置组件左边框的位置,其余的将保持在相同的位置。

For support to all API levels you can use it like this:

ViewPropertyAnimator.animate(view).translationYBy(-yourY).translationXBy(-yourX).setDuration(0);

已经有不同的有效答案,但似乎没有适当的建议在哪种情况下使用哪种方法,除了相应的 API 级别限制:

  • 如果可以等待布局周期,并且父视图组支持 MarginLayoutParams(或子类) ,则相应地设置 marginLeft/marginTop

  • 如果您需要立即并持久地更改位置(例如,对于 PopupMenu 锚) ,另外使用相同的坐标调用 layout(l, t, r, b)。这抢占了布局系统稍后将确认的内容。

  • 对于即时(临时)更改(例如动画) ,使用 setX()/setY()代替。在父级大小不依赖于 WRAP _ CHILDREN 的情况下,可以只使用 setX()/setY()

  • Never use setLeft() / setRight() / setBottom() / setTop(), see below.

Background: mLeft/mTop/mBottom/mRight字段通过布局()中相应的 LayoutParams 填充。布局由 Android 视图布局系统隐式和异步地调用。因此,设置 MarginLayoutParams似乎是最安全和最干净的方式设置的立场永久。然而,在某些情况下,异步布局延迟可能是一个问题,例如,当使用视图呈现一个光标时,它应该被重新定位,同时作为一个 PopupMenu 锚点。在这种情况下,打电话给 layout()对我来说很有用。

setLeft()setTop()的问题是:

  • 单独调用它们是不够的——您还需要调用 setRight()setBottom()以避免拉伸或缩小视图。

  • 这些方法的实现看起来相当复杂(= 做一些工作来说明每个方法引起的视图大小变化)

  • 它们似乎对输入字段造成了奇怪的问题: 软数字键盘有时不允许数字

setX()setY()在布局系统之外工作,相应的值被视为由布局系统确定的左/上/底/右值的附加偏移量,相应地移动视图。他们似乎已经添加了动画(其中一个立即的效果,而不是通过一个布局循环是必需的)。

I found that @Stefan Haustein comes very close to my experience, but not sure 100%. My suggestion is:

  • setLeft()/setRight()/setBottom()/setTop()有时不工作。
  • 如果你想 临时设置一个位置(例如做动画,不影响层次结构)时,添加并显示了视图,只是 使用 ABC0/setY()代替。(你可能想搜索更多在 difference ABC2 and setX())
  • And note that X, Y seem to be absolute, and it was supported by AbsoluteLayout which now is deprecated. Thus, you feel X, Y is likely not supported any more. And yes, it is, but only partly. It means if your 如果添加了 view,setX ()、 setY ()将完美地工作; otherwise, 什么时候 you try to 将视图添加到视图组布局中 (e.g FrameLayout, LinearLayout, RelativeLayout), you 必须设置 its LayoutParams with 左边,上边 instead (setX(), setY() in this case won't work sometimes).
  • 设置观点的位置由靠左和靠顶 是一个 不同步过程。所以是 需要一点时间来更新层次结构。如果你为它 设置边距后立即使用视图,你 可能会得到一个错误的价值

定位时要记住的一点是,每个视图都有一个相对于其父视图的索引。因此,如果您有一个线性布局与三个子视图,子视图将每个有一个索引: 0,1,2在上述情况下。

这允许您通过执行以下操作将视图添加到父视图的最后一个位置(或最后一个位置) :

int childCount = parent.getChildCount();
parentView.addView(newView, childCount);

或者,您可以使用以下代码替换视图:

int childIndex = parentView.indexOfChild(childView);
childView.setVisibility(View.GONE);


parentView.addView(newView, childIndex);

在 Kotlin,你可以这样做:

view
.animate()
.x(50f)
.y(100f)
.duration = 500L