设置视图的绝对位置

Sep*_*phy 177 layout android position view android-layout

是否可以在Android中设置视图的绝对位置?(我知道有一个AbsoluteLayout,但它被弃用了......)

例如,如果我有一个240x320px的屏幕,我怎么能添加一个ImageView20x20px,使其中心位于(100,100)?

And*_*ang 266

您可以使用RelativeLayout.假设您想在布局中的位置(50,60)处使用30x40 ImageView.你活动的某个地方:

// Some existing RelativeLayout from your layout xml
RelativeLayout rl = (RelativeLayout) findViewById(R.id.my_relative_layout);

ImageView iv = new ImageView(this);

RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(30, 40);
params.leftMargin = 50;
params.topMargin = 60;
rl.addView(iv, params);
Run Code Online (Sandbox Code Playgroud)

更多例子:

分别在(50,60)和(80,90)处放置两个30x40 ImageViews(一个黄色,一个红色):

RelativeLayout rl = (RelativeLayout) findViewById(R.id.my_relative_layout);
ImageView iv;
RelativeLayout.LayoutParams params;

iv = new ImageView(this);
iv.setBackgroundColor(Color.YELLOW);
params = new RelativeLayout.LayoutParams(30, 40);
params.leftMargin = 50;
params.topMargin = 60;
rl.addView(iv, params);

iv = new ImageView(this);
iv.setBackgroundColor(Color.RED);
params = new RelativeLayout.LayoutParams(30, 40);
params.leftMargin = 80;
params.topMargin = 90;
rl.addView(iv, params);
Run Code Online (Sandbox Code Playgroud)

相对于黄色ImageView,在(50,60)处放置一个30x40黄色ImageView,将另一个30x40红色ImageView <80,90> 放置:

RelativeLayout rl = (RelativeLayout) findViewById(R.id.my_relative_layout);
ImageView iv;
RelativeLayout.LayoutParams params;

int yellow_iv_id = 123; // Some arbitrary ID value.

iv = new ImageView(this);
iv.setId(yellow_iv_id);
iv.setBackgroundColor(Color.YELLOW);
params = new RelativeLayout.LayoutParams(30, 40);
params.leftMargin = 50;
params.topMargin = 60;
rl.addView(iv, params);

iv = new ImageView(this);
iv.setBackgroundColor(Color.RED);
params = new RelativeLayout.LayoutParams(30, 40);
params.leftMargin = 80;
params.topMargin = 90;

// This line defines how params.leftMargin and params.topMargin are interpreted.
// In this case, "<80,90>" means <80,90> to the right of the yellow ImageView.
params.addRule(RelativeLayout.RIGHT_OF, yellow_iv_id);

rl.addView(iv, params);
Run Code Online (Sandbox Code Playgroud)

  • 为什么使用这种方法比使用AbsoluteLayout更好?仅仅因为弃绝了AbsoluteLayout? (9认同)
  • 是的,我昨天通过自己挖掘你的解决方案也发现了.我也尝试使用FrameLayout.我的实际问题是我有5个图像,每个图像都有一个随机(x,y)位置,所以我不能使用RelativeLayout.RIGHT_OF或类似的东西.奇怪的是,我可以正确放置3张图片,但其中2张图片不能正常工作...我不明白......今晚我会用一些截图和一些代码更新我的帖子. (2认同)

bon*_*nyz 63

通常,您可以通过指定leftMargin和topMargin属性,使用FrameLayout作为容器在特定位置添加View.

以下示例将使用FrameLayout作为全屏容器将20x20px ImageView放置在位置(100,200):

XML

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/root"
    android:background="#33AAFF"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >
</FrameLayout>
Run Code Online (Sandbox Code Playgroud)

活动/片段/自定义视图

//...
FrameLayout root = (FrameLayout)findViewById(R.id.root);
ImageView img = new ImageView(this);
img.setBackgroundColor(Color.RED);
//..load something inside the ImageView, we just set the background color

FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(20, 20);
params.leftMargin = 100;
params.topMargin  = 200;
root.addView(img, params);
//...
Run Code Online (Sandbox Code Playgroud)

这样做可以解决问题,因为边距可以用作绝对(X,Y)坐标而不需要RelativeLayout:

在此输入图像描述

  • 辉煌!值得500!+1 (2认同)

Exc*_*ent 16

只是为了添加上面的Andy Zhang的答案,如果你愿意,你可以给rl.addView提供参数,然后再对它进行更改,所以:

params = new RelativeLayout.LayoutParams(30, 40);
params.leftMargin = 50;
params.topMargin = 60;
rl.addView(iv, params);
Run Code Online (Sandbox Code Playgroud)

同样可以写成:

params = new RelativeLayout.LayoutParams(30, 40);
rl.addView(iv, params);
params.leftMargin = 50;
params.topMargin = 60;
Run Code Online (Sandbox Code Playgroud)

因此,如果保留params变量,则可以在将其添加到rl后随时更改iv的布局.


Har*_*nji 5

更简洁,更动态的方式,无需对代码中的任何像素值进行硬编码.

我想在一个单击的按钮下方放置一个对话框(我在飞行中充气).

并以这种方式解决了它:

    // get the yoffset of the position where your View has to be placed 
    final int yoffset = < calculate the position of the view >

    // position using top margin
    if(myView.getLayoutParams() instanceof MarginLayoutParams) {
        ((MarginLayoutParams) myView.getLayoutParams()).topMargin = yOffset;
    }
Run Code Online (Sandbox Code Playgroud)

但是,您必须确保父布局myView是一个实例RelativeLayout.

更完整的代码:

    // identify the button
    final Button clickedButton = <... code to find the button here ...>

    // inflate the dialog - the following style preserves xml layout params
    final View floatingDialog = 
        this.getLayoutInflater().inflate(R.layout.floating_dialog,
            this.floatingDialogContainer, false);

    this.floatingDialogContainer.addView(floatingDialog);

    // get the buttons position
    final int[] buttonPos = new int[2];
    clickedButton.getLocationOnScreen(buttonPos);        
    final int yOffset =  buttonPos[1] + clickedButton.getHeight();

    // position using top margin
    if(floatingDialog.getLayoutParams() instanceof MarginLayoutParams) {
        ((MarginLayoutParams) floatingDialog.getLayoutParams()).topMargin = yOffset;
    }
Run Code Online (Sandbox Code Playgroud)

这样,您仍然可以期望目标视图适应使用布局XML文件设置的任何布局参数,而不是在Java代码中对这些像素/ dps进行硬编码.