How can I dynamically set the position of view in

2019-01-01 15:49发布

How can I change the position of view through code? Like changing its X, Y position. Is it possible?

11条回答
旧人旧事旧时光
2楼-- · 2019-01-01 16:18

Use RelativeLayout, place your view in it, get RelativeLayout.LayoutParams object from your view and set margins as you need. Then call requestLayout() on your view. This is the only way I know.

查看更多
长期被迫恋爱
3楼-- · 2019-01-01 16:21

I would recommend using setTranslationX and setTranslationY. I'm only just getting started on this myself, but these seem to be the safest and preferred way of moving a view. I guess it depends a lot on what exactly you're trying to do, but this is working well for me for 2D animation.

查看更多
情到深处是孤独
4楼-- · 2019-01-01 16:22

Set the left position of this view relative to its parent:

view.setLeft(int leftPosition);

Set the right position of this view relative to its parent:

view.setRight(int rightPosition);

Set the top position of this view relative to its parent:

view.setTop(int topPosition);

Set the bottom position of this view relative to its parent:

view.setBottom(int bottomPositon);

The above methods are used to set the position the view related to its parent.

查看更多
后来的你喜欢了谁
5楼-- · 2019-01-01 16:26

Use LayoutParams. If you are using a LinearLayout you have to import android.widget.LinearLayout.LayoutParams, else import the proper version of LayoutParams for the layout you're using, or it will cause a ClassCastException, then:

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

NB: Note that you can use also imageView.setLeft(int dim), BUT THIS WON'T set the position of the component, it will set only the position of the left border of the component, the rest will remain at the same position.

查看更多
几人难应
6楼-- · 2019-01-01 16:28

There are different valid answers already, but none seems to properly suggest which method(s) to use in which case, except for the corresponding API level restrictions:

  • If you can wait for a layout cycle and the parent view group supports MarginLayoutParams (or a subclass), set marginLeft / marginTop accordingly.

  • If you need to change the position immediately and persistently (e.g. for a PopupMenu anchor), additionally call layout(l, t, r, b) with the same coordinates. This preempts what the layout system will confirm later.

  • For immediate (temporary) changes (such as animations), use setX() / setY() instead. In cases where the parent size doesn't depend on WRAP_CHILDREN, it might be fine to use setX() / setY() exclusively.

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

Background: The mLeft / mTop / mBottom / mRight fields get filled from the corresponding LayoutParams in layout(). Layout is called implicitly and asynchronously by the Android view layout system. Thus, setting the MarginLayoutParams seems to be the safest and cleanest way to set the position permanently. However, the asynchronous layout lag might be a problem in some cases, e.g. when using a View to render a cursor, and it's supposed to be re-positioned and serve as a PopupMenu anchor at the same time. In this case, calling layout() worked fine for me.

The problems with setLeft() and setTop() are:

  • Calling them alone is not sufficient -- you also need to call setRight() and setBottom() to avoid stretching or shrinking the view.

  • The implementation of these methods looks relatively complex (= doing some work to account for the view size changes caused by each of them)

  • They seem to cause strange issues with input fields: EditText soft numeric keyboard sometimes does not allow digits

setX() and setY() work outside of the layout system, and the corresponding values are treated as an additional offset to the left / top / bottom / right values determined by the layout system, shifting the view accordingly. They seem to have been added for animations (where an immediate effect without going through a layout cycle is required).

查看更多
登录 后发表回答