设置视图的绝对位置


180

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

例如,如果我有一个240x320px的屏幕,如何添加一个20x20px的屏幕,ImageView使其中心位于位置(100,100)?


3
另请参阅view.setTranslationX()view.offsetLeftAndRight()
Drew LeSueur 2013年

我刚刚发布了一个可能在这里引起关注的图书馆。github.com/ManuelPeinado/ImageLayout
曼努埃尔

1
这很困难,因为99.9%的时间绝对定位在android上是个坏主意。如果您编写的应用程序只能在一个物理设备上运行,那么这可能会起作用,但这通常不是一个安全的假设。例如,请勿将其上传到Google Play。它在iOS上运行良好,因为只有很少的硬件设备,并且您可以为每个设备构建自定义情节提要。
edthethird

2
@edthethird,在我的跨平台应用程序中,我得到了屏幕尺寸并以此为基础。我刚刚切换到“过时的” AbsoluteLayout,它工作正常。
William Jockusch 2015年

足够公平,但这就是相对布局或LinearLayout会自动为您执行的操作。
edthethird

Answers:


270

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

更多示例:

在(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);

相对于黄色ImageView将一个30x40黄色ImageView放置在(50,60),将另一个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);

1
今晚我会去,那是一个很好的主意,不知道为什么我没有考虑。正如我要说的那样ImageView,使用难道不是更好FrameLayout吗?
Sephy 2010年

实际上,这似乎可行,但是,仅当以这种方式添加一张图片时,它才有效。如果我尝试添加第二个,第一个就消失了
Sephy 2010年

1
这两个图像彼此重叠。我将在上面的解决方案中添加一些代码以进行解释。
安迪·张

2
是的,的确,昨天我也通过自己研究解决方案而发现了这一点。我也尝试使用FrameLayout。我的实际问题是我有5个图像,每个图像具有随机(x,y)位置,所以我不能使用RelativeLayout.RIGHT_OF或类似的东西。奇怪的是,我可以正确放置3张图像,但其中2张无法正常工作...我不明白...我将在今晚用一些屏幕截图和一些代码来更新我的帖子。
Sephy 2010年

9
为什么使用此方法会比使用AbsoluteLayout更好?仅仅因为AbsoluteLayout被弃用了?
内森

66

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

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

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>

活动/片段/自定义视图

//...
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);
//...

之所以会成功,是因为无需使用RelativeLayout,边距就可以用作绝对(X,Y)坐标:

在此处输入图片说明


2
辉煌!值得500!+1
丽莎·安妮

16

只是要添加到上面的Andy Zhang的答案中,如果愿意,可以将para.l给rl.addView,然后对其进行更改,因此:

params = new RelativeLayout.LayoutParams(30, 40);
params.leftMargin = 50;
params.topMargin = 60;
rl.addView(iv, params);

同样可以写成:

params = new RelativeLayout.LayoutParams(30, 40);
rl.addView(iv, params);
params.leftMargin = 50;
params.topMargin = 60;

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


喜欢这个样品。您能建议我在xml布局中放置图像时如何设置x,y轴。(我正在尝试调整图像的大小,并且需要将图像设置在某个位置)
G_S 2012年

恐怕我不太了解您的要求。您是否要访问与使用XML布局定位的对象相关联的LayoutParams对象?我不确定该怎么做。如果您无法在其他地方找到答案,则可能需要设置一个新问题来回答该问题。
2012年


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;
    }

但是,您必须确保的父布局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;
    }

这样,您仍然可以期望目标视图调整为使用布局XML文件设置的任何布局参数,而不用硬编码Java代码中的这些像素/ dps。


1

检查截图

将任何观点放在您想要的XY点上

布局文件

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.example.test.MainActivity" >

    <AbsoluteLayout
        android:id="@+id/absolute"
        android:layout_width="match_parent"
        android:layout_height="match_parent" >

        <RelativeLayout
            android:id="@+id/rlParent"
            android:layout_width="match_parent"
            android:layout_height="match_parent" >

            <ImageView
                android:id="@+id/img"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:background="@drawable/btn_blue_matte" />
        </RelativeLayout>
    </AbsoluteLayout>

</RelativeLayout>

Java类

public class MainActivity extends Activity {

    private RelativeLayout rlParent;
    private int width = 100, height = 150, x = 20, y= 50; 

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        AbsoluteLayout.LayoutParams param = new AbsoluteLayout.LayoutParams(width, height, x, y);
        rlParent = (RelativeLayout)findViewById(R.id.rlParent);
        rlParent.setLayoutParams(param);
    }
}

完成了


0

以防万一它可能对某人有帮助,您也可以尝试使用此动画制作器ViewPropertyAnimator,如下所示

myView.animate().x(50f).y(100f);

myView.animate().translateX(pixelInScreen) 

注意:此像素不是相对于视图的。此像素是屏幕中的像素位置。

归功于bpr10答案


-1

尝试下面的代码在特定位置设置视图:

            TextView textView = new TextView(getActivity());
            textView.setId(R.id.overflowCount);
            textView.setText(count + "");
            textView.setGravity(Gravity.CENTER);
            textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 12);
            textView.setTextColor(getActivity().getResources().getColor(R.color.white));
            textView.setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View v) {
                    // to handle click 
                }
            });
            // set background 
            textView.setBackgroundResource(R.drawable.overflow_menu_badge_bg);

            // set apear

            textView.animate()
                    .scaleXBy(.15f)
                    .scaleYBy(.15f)
                    .setDuration(700)
                    .alpha(1)
                    .setInterpolator(new BounceInterpolator()).start();
            FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams(
                    FrameLayout.LayoutParams.WRAP_CONTENT,
                    FrameLayout.LayoutParams.WRAP_CONTENT);
            layoutParams.topMargin = 100; // margin in pixels, not dps
            layoutParams.leftMargin = 100; // margin in pixels, not dps
            textView.setLayoutParams(layoutParams);

            // add into my parent view
            mainFrameLaout.addView(textView);

-1

我的Xamarin代码,我正在为此使用FrameLayout,以下是我的代码:

               List<object> content = new List<object>();

        object aWebView = new {ContentType="web",Width="300", Height = "300",X="10",Y="30",ContentUrl="http://www.google.com" };
        content.Add(aWebView);
        object aWebView2 = new { ContentType = "image", Width = "300", Height = "300", X = "20", Y = "40", ContentUrl = "https://www.nasa.gov/sites/default/files/styles/image_card_4x3_ratio/public/thumbnails/image/leisa_christmas_false_color.png?itok=Jxf0IlS4" };
        content.Add(aWebView2);
        FrameLayout myLayout = (FrameLayout)FindViewById(Resource.Id.frameLayout1);
        foreach (object item in content)
        {

            string contentType = item.GetType().GetProperty("ContentType").GetValue(item, null).ToString();
            FrameLayout.LayoutParams param = new FrameLayout.LayoutParams(Convert.ToInt32(item.GetType().GetProperty("Width").GetValue(item, null).ToString()), Convert.ToInt32(item.GetType().GetProperty("Height").GetValue(item, null).ToString()));
            param.LeftMargin = Convert.ToInt32(item.GetType().GetProperty("X").GetValue(item, null).ToString());
            param.TopMargin = Convert.ToInt32(item.GetType().GetProperty("Y").GetValue(item, null).ToString());

            switch (contentType) {
                case "web":{
                        WebView webview = new WebView(this);

                        //webview.hei;
                        myLayout.AddView(webview, param);
                        webview.SetWebViewClient(new WebViewClient());
                        webview.LoadUrl(item.GetType().GetProperty("ContentUrl").GetValue(item, null).ToString());

                        break;
                    }
                case "image":
                    {
                        ImageView imageview = new ImageView(this);

                        //webview.hei;
                        myLayout.AddView(imageview, param);
                        var imageBitmap =  GetImageBitmapFromUrl("https://www.nasa.gov/sites/default/files/styles/image_card_4x3_ratio/public/thumbnails/image/leisa_christmas_false_color.png?itok=Jxf0IlS4");
                        imageview.SetImageBitmap(imageBitmap);


                        break;
                    }

            }

        }

这对我很有用,因为我需要根据其外观将视图的属性彼此重叠,例如,视图彼此堆叠

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.