【发布时间】:2011-09-26 00:16:53
【问题描述】:
如何通过代码改变视图的位置?就像改变它的 X、Y 位置一样。有可能吗?
【问题讨论】:
如何通过代码改变视图的位置?就像改变它的 X、Y 位置一样。有可能吗?
【问题讨论】:
对于 Honeycomb(API 级别 11)以下的任何内容,您必须使用 setLayoutParams(...)。
如果您可以限制对 Honeycomb 及更高版本的支持,您可以使用 setX(...)、setY(...)、setLeft(...)、setTop(...) 等。
【讨论】:
sets the top position of this view relative to its parent. This method is meant to be called by the layout system and should not generally be called otherwise, because the property may be changed at any time by the layout. - 所以也许这不是一个好主意 ;)
是的,您可以在 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 级别限制:
如果可以等待一个布局周期并且父视图组支持MarginLayoutParams(或子类),则相应设置marginLeft/marginTop。
如果您需要立即且持久地更改位置(例如,对于 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() 在布局系统之外工作,相应的值被视为布局系统确定的左/上/下/右值的附加偏移量,相应地移动视图。它们似乎是为动画添加的(需要立即产生效果而无需经过布局周期)。
【讨论】:
marginLeft 可以通过使用 setLayoutParams 和您设置 marginLeft 的 new FrameLayout.LayoutParams(width, height) 来设置
有一个名为 NineOldAndroids 的库,它允许您使用 Honeycomb 动画库一直到版本一。
这意味着您可以使用稍微不同的界面定义左、右、平移X/Y。
这是它的工作原理:
ViewHelper.setTranslationX(view, 50f);
您只需使用 ViewHelper 类中的静态方法,传递视图以及您想要设置的值。
【讨论】:
我建议使用setTranslationX 和setTranslationY。我自己才刚刚开始,但这些似乎是移动视图的最安全和首选的方式。我想这在很大程度上取决于您到底想要做什么,但这对我来说非常适合 2D 动画。
【讨论】:
如果您使用的是 HoneyComb Sdk(API Level 11),您可以尝试使用以下方法。
view.setX(float x);
参数x是这个视图的视觉x位置。
view.setY(float y);
参数y是这个视图的视觉y位置。
希望对你有所帮助。 :)
【讨论】:
要支持所有 API 级别,您可以像这样使用it:
ViewPropertyAnimator.animate(view).translationYBy(-yourY).translationXBy(-yourX).setDuration(0);
【讨论】:
使用布局参数。 如果您使用的是 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),但是这不会设置组件的位置,它只会设置组件左边框的位置,其余的将保持在同一位置。
【讨论】:
使用RelativeLayout,将视图放入其中,从视图中获取RelativeLayout.LayoutParams 对象并根据需要设置边距。然后在您的视图上致电requestLayout()。这是我知道的唯一方法。
【讨论】:
设置此视图相对于其父视图的左侧位置:
view.setLeft(int leftPosition);
设置此视图相对于其父视图的正确位置:
view.setRight(int rightPosition);
设置此视图相对于其父视图的顶部位置:
view.setTop(int topPosition);
设置此视图相对于其父视图的底部位置:
view.setBottom(int bottomPositon);
以上方法用于设置视图与其父视图相关的位置。
【讨论】:
我发现@Stefan Haustein 与我的经验非常接近,但不确定 100%。我的建议是:
setLeft() / setRight() / setBottom() / setTop() 有时不起作用。setY() 代替。 (您可能希望在setLeft() 和setX() 的区别中进行更多搜索)【讨论】:
在 Kotlin 中,您可以按以下方式进行操作;
view
.animate()
.x(50f)
.y(100f)
.duration = 500L
【讨论】:
定位时要记住的一点是,每个视图都有一个相对于其父视图的索引。因此,如果您有一个包含三个子视图的线性布局,则在上述情况下,每个子视图都有一个索引:0、1、2。
这允许您通过执行以下操作将视图添加到父视图中的最后一个位置(或末尾):
int childCount = parent.getChildCount();
parentView.addView(newView, childCount);
或者,您可以使用以下内容替换视图:
int childIndex = parentView.indexOfChild(childView);
childView.setVisibility(View.GONE);
parentView.addView(newView, childIndex);
【讨论】: