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

时间:2011-06-30 13:39:39

标签: android layout view

如何通过代码更改视图的位置?喜欢改变它的X,Y位置。有可能吗?

13 个答案:

答案 0 :(得分:110)

对于Honeycomb(API Level 11)以下的任何内容,您必须使用setLayoutParams(...)

如果您可以限制对Honeycomb的支持,可以使用setX(...)setY(...)setLeft(...)setTop(...)

答案 1 :(得分:42)

是的,您可以在Android中动态设置视图的位置。同样,您的xml文件ImageView中有一个LinearLayout。因此,您可以通过LayoutParams设置其位置。但请确保根据您的布局采取LayoutParams xml文件。根据所采用的布局,有不同的LayoutParams

以下是要设置的代码:

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

我希望你能有所帮助。

答案 2 :(得分:25)

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

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

    < / LI>
  • 如果您需要立即且持久地更改位置(例如,对于PopupMenu锚点),请另外使用相同的坐标调用layout(l, t, r, b)。这预示着布局系统稍后会确认的内容。

  • 对于即时(临时)更改(例如动画),请改用setX() / setY()。如果父母大小不依赖于WRAP_CHILDREN,则可以完全使用setX() / setY()

  • 从不使用setLeft() / setRight() / setBottom() / setTop(),请参阅下文。

<强>背景mLeft / mTop / mBottom / mRight字段从layout()中的相应LayoutParams填充。 Android视图布局系统隐式和异步调用布局。因此,设置MarginLayoutParams似乎是永久设置位置的最安全,最干净的方法。然而,在某些情况下,异步布局滞后可能是一个问题,例如,当使用View来渲染光标时,它应该被重新定位并同时作为PopupMenu锚点。在这种情况下,调用layout()对我来说很好。

setLeft()setTop()的问题是:

  • 单独打电话是不够的 - 您还需要拨打setRight()setBottom()以避免拉伸或缩小视图。

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

  • 它们似乎会导致输入字段出现奇怪问题:EditText soft numeric keyboard sometimes does not allow digits

setX()setY()在布局系统之外工作,相应的值被视为布局系统确定的左/上/下/右值的附加偏移量,移动视图因此。它们似乎已添加到动画中(无需经过布局循环即可立即生效)。

答案 3 :(得分:18)

有一个名为NineOldAndroids的库,它允许您将Honeycomb动画库一直使用到第一版。

这意味着您可以使用稍微不同的界面定义left,right,translationX / Y.

以下是它的工作原理:

ViewHelper.setTranslationX(view, 50f);

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

答案 4 :(得分:15)

我建议使用setTranslationXsetTranslationY。我自己只是刚刚开始这个,但这些似乎是移动视图最安全和首选的方式。我想这很大程度上取决于你究竟想要做什么,但这对于2D动画来说非常有用。

答案 5 :(得分:12)

如果您使用的是HoneyComb Sdk(API级别11),则可以尝试使用以下方法。

view.setX(float x);

参数x是该视图的视觉x位置。

view.setY(float y);

参数y是该视图的视觉y位置。

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

答案 6 :(得分:5)

要支持所有API级别,您可以使用it,如下所示:

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

答案 7 :(得分:4)

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

view.setLeft(int leftPosition);

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

view.setRight(int rightPosition);

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

view.setTop(int topPosition);

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

view.setBottom(int bottomPositon);

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

答案 8 :(得分:4)

使用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);

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

答案 9 :(得分:3)

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

答案 10 :(得分:0)

我发现@Stefan Haustein非常接近我的经验,但不确定100%。我的建议是:

  • setLeft() / setRight() / setBottom() / setTop()有时无效。
  • 如果您要在添加并显示视图时临时设置位置(例如,做动画,不影响层次结构),只需使用{改为{1}} / setX() 。 (您可能希望在差异setY()setLeft() 中进行更多搜索)
  • 请注意,X,Y似乎是绝对的,并且AbsoluteLayout支持该功能,现在已弃用。因此,您可能不再支持X,Y。是的,是的,但只有一部分。这意味着,如果您添加了视图,则setX(),setY()会完美运行;否则,您尝试将视图添加到视图组布局(例如FrameLayout,LinearLayout,RelativeLayout)时,您必须设置其LayoutParams并使用<相反,strong> marginLeft,marginTop (在这种情况下,setX(),setY()有时无法工作)。
  • 通过marginLeft和marginTop 设置视图的位置是一个不同步过程。因此,需要一些时间来更新层次结构。如果您在设置边距后立即使用视图,则可能会得到错误的值

答案 11 :(得分:0)

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

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

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

或者,您也可以使用如下所示的视图替换视图:

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

parentView.addView(newView, childIndex);

答案 12 :(得分:0)

在 Kotlin 中,您可以按照以下方式进行操作;

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