我怎样才能通过代码改变视图的位置?比如改变它的X、Y位置。这可能吗?
对于低于Honeycomb(API级别11)的东西,你必须使用
setLayoutParams(...)
。
如果你能将你的支持限制在Honeycomb及以上,你可以使用
setX(...)
、
setY(...)
、
setLeft(...)
、
setTop(...)
等。
是的,你可以在Android中动态地设置视图的位置。同样地,你的XML文件的
LinearLayout
中有一个
ImageView
。所以你可以通过
LayoutParams
来设置它的位置。但要确保根据你的XML文件中的布局来采取
LayoutParams
。根据所采取的布局,有不同的
LayoutParams
。
Here is the code to set:
LayoutParams layoutParams=new LayoutParams(int width, int height);
layoutParams.setMargins(int left, int top, int right, int bottom);
imageView.setLayoutParams(layoutParams);
David T.
:
还要注意,你必须导入android.widget.LinearLayout.LayoutParams;因为默认是ViewGroup的LayoutParams。
这在安卓8+系统上似乎并不奏效。你是否遇到过类似的问题?
知道为什么Andriod的设计者要如此麻烦地阻止程序员使用X、Y来定位东西吗?最终,所有的东西都必须以这种方式绘制。这表明,安卓系统是由不会编码的人设计的。
Stefan Haustein
发布于
2019-10-16
0
人赞同
已经有了不同的有效答案,但除了相应的API级别的限制外,似乎都没有正确地建议在什么情况下使用哪种(些)方法。
如果你可以等待一个布局周期,并且父级视图组支持
MarginLayoutParams
(或子类),请设置
marginLeft
。/
marginTop
。
如果你需要立即和持续地改变位置(例如对于一个PopupMenu锚),另外调用
layout(l, t, r, b)
,坐标相同。这样就可以抢占布局系统稍后确认的位置。
对于即时(临时)变化(如动画),使用
setX()
。/
setY()
代替。在父类的大小不依赖于WRAP_CHILDREN的情况下,使用
setX()
/
setY()
就可以了。/
setY()
。
Never
use
setLeft()
/
setRight()
/
setBottom()
/
setTop()
, see below.
背景介绍
:
【替换代码12/ 【替换代码13/ 【替换代码14/
mRight
字段由layout()中相应的LayoutParams填充。布局是由Android视图布局系统隐含地、异步地调用的。因此,设置
MarginLayoutParams
似乎是永久设置位置的最安全、最干净的方式。然而,在某些情况下,异步布局滞后可能是一个问题,例如,当使用视图渲染光标时,它应该被重新定位并同时作为PopupMenu的锚。在这种情况下,调用
layout()
对我来说很有效。
setLeft()
和
setTop()
的问题是。
仅仅调用它们是不够的--你还需要调用
setRight()
和
setBottom()
以避免拉伸或缩小视图。
这些方法的实现看起来相对复杂(=做了一些工作来解释每个方法引起的视图大小变化)
它们似乎会引起输入字段的奇怪问题。
编辑文本软数字键盘有时不允许有数字
替换代码4】和
setY()
在布局系统之外工作,相应的值被视为布局系统确定的左/上/下/右值的额外偏移,相应地移动视图。它们似乎是为动画添加的(在这种情况下,需要不经过布局循环就能立即产生效果)。
你好,Stefan。你能不能给我一些书或文章,让我了解安卓的布局系统是如何工作的。我明白布局()onMeasure()onDraw()的调用顺序,但我想知道更多细节。谢谢
不幸的是,我不能 -- 最好和最确定的参考似乎是实际的安卓源代码O:)
signal
:
我使用setY来改变视图,它是在下一个布局周期改变,而不是立即改变?
How did you determine this?
值得指出的是,
marginLeft
可以通过使用
setLayoutParams
与
new FrameLayout.LayoutParams(width, height)
来设置,在此基础上设置
marginLeft
。
Ben
发布于
2019-10-16
0
人赞同
有一个库叫
NineOldAndroids
它允许你使用Honeycomb的动画库,一直到第一版。
这意味着你可以用一个稍微不同的界面来定义左、右、translationX/Y。
Here is how it works:
ViewHelper.setTranslationX(view, 50f);
你只需使用ViewHelper类的静态方法,传递视图和你想设置的任何值。
brianmearns
发布于
2019-10-16
0
人赞同
我建议使用
setTranslationX
和
setTranslationY
。我自己也是刚刚开始,但这些似乎是移动视图的最安全和最好的方式。我想这在很大程度上取决于你到底想做什么,但这对我来说对二维动画很有效。
Chickenrice
发布于
2019-10-16
0
人赞同
如果你使用HoneyComb Sdk(API Level 11),你可以尝试使用以下方法。
view.setX(float x);
参数x是这个视图的视觉x位置。
view.setY(float y);
参数y是该视图的视觉y位置。
I hope it will be helpful to you. :)
我在2.2 Froyo上工作,这些方法在它那里是不可用的。
Orr
发布于
2019-10-16
0
人赞同
对于对所有API级别的支持,你可以使用
it
like this:
ViewPropertyAnimator.animate(view).translationYBy(-yourY).translationXBy(-yourX).setDuration(0);
Balaji.K
发布于
2019-10-16
0
人赞同
设置该视图相对于其父级的左边位置。
view.setLeft(int leftPosition);
设置该视图相对于其父级的右边位置。
view.setRight(int rightPosition);
设置该视图相对于其父级的顶部位置。
view.setTop(int topPosition);
设置该视图相对于其父级的底部位置。
view.setBottom(int bottomPositon);
上述方法用于设置视图与其父级的相关位置。
对不起,这些方法是不可用的。你能给我发送任何代码吗?
GDanger
:
"这个方法是用来被布局系统调用的,一般不应另行调用,因为这个属性可能随时被布局改变。"
Alessandro Muzzi
发布于
2019-10-16
0
人赞同
使用LayoutParams。
如果你使用的是LinearLayout,你必须导入android.widget.LinearLayout.LayoutParams,否则为你使用的布局导入适当版本的LayoutParams,否则会导致
类的转换异常
, then:
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),但这不会设置组件的位置,它只会设置组件左边界的位置,其他部分将保持在相同的位置。
james
:
那么,我们怎样才能在不影响原始视图的情况下将视图移动到特定的位置?
我不确定我是否理解你的问题,因为如果你想移动一个视图,你会因为你移动它而改变它。总之,如果你想在另一个独立的视图上移动一个视图,你可能需要一个FrameLayout视图,然后,在它里面,你可以放置你的独立视图(显然,如果你想让它在你的主视图下移动,你必须把FrameLayout放在你的主视图之前)。
glodos
发布于
2019-10-16
0
人赞同
使用
RelativeLayout
,将你的视图置于其中,从你的视图中获得
RelativeLayout.LayoutParams
对象,并按你的需要设置边距。然后在你的视图上调用
requestLayout()
。这是我知道的唯一方法。
Nguyen Tan Dat
发布于
2019-10-16
0
人赞同
我发现@Stefan Haustein与我的经验非常接近,但不确定100%。我的建议是。
setLeft()
/
setRight()
/
setBottom()
/
setTop()
won't work sometimes.
If you want to
set a position temporarily (e.g for doing animation, not affected a hierachy)
when
the view was added and shown
, just
use
setX()
/
setY()
instead. (You might want search more in
difference
setLeft()
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 is added, setX(), setY() will work perfectly
; otherwise,
when
you try to
add a view into view group layout
(e.g FrameLayout, LinearLayout, RelativeLayout), you
must set
its LayoutParams with
marginLeft, marginTop
instead (setX(), setY() in this case won't work sometimes).
Set position of the view by marginLeft and marginTop
is an
unsynchronized
process. So it
needs a bit time to update hierarchy
. If you
use the view straight away after set margin
for it, you
might get a wrong value
.
Braden Holt
发布于
2019-10-16
0
人赞同
在定位方面需要记住的一点是,每个视图都有一个相对于其父视图的索引。因此,如果你有一个带有三个子视图的线性布局,子视图将各自有一个索引。在上面的例子中,0、1、2。
这允许你在父级视图中的最后一个位置(或末尾)添加一个视图,具体做法如下。
int childCount = parent.getChildCount();
parentView.addView(newView, childCount);
另外,你也可以使用类似以下的方法来替换一个视图。