Set the absolute position of a view
Solution 1
You can use RelativeLayout. Let's say you wanted a 30x40 ImageView at position (50,60) inside your layout. Somewhere in your activity:
// 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);
More examples:
Places two 30x40 ImageViews (one yellow, one red) at (50,60) and (80,90), respectively:
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);
Places one 30x40 yellow ImageView at (50,60) and another 30x40 red ImageView <80,90> relative to the yellow ImageView:
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);
Solution 2
In general, you can add a View in a specific position using a FrameLayout as container by specifying the leftMargin and topMargin attributes.
The following example will place a 20x20px ImageView at position (100,200) using a FrameLayout as fullscreen container:
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>
Activity / Fragment / Custom view
//...
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);
//...
This will do the trick because margins can be used as absolute (X,Y) coordinates without a RelativeLayout:
Solution 3
Just to add to Andy Zhang's answer above, if you want to, you can give param to rl.addView, then make changes to it later, so:
params = new RelativeLayout.LayoutParams(30, 40);
params.leftMargin = 50;
params.topMargin = 60;
rl.addView(iv, params);
Could equally well be written as:
params = new RelativeLayout.LayoutParams(30, 40);
rl.addView(iv, params);
params.leftMargin = 50;
params.topMargin = 60;
So if you retain the params variable, you can change the layout of iv at any time after adding it to rl.
Solution 4
A more cleaner and dynamic way without hardcoding any pixel values in the code.
I wanted to position a dialog (which I inflate on the fly) exactly below a clicked button.
and solved it this way :
// 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;
}
However you have to make sure the parent layout of myView
is an instance of RelativeLayout
.
more complete code :
// 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;
}
This way you can still expect the target view to adjust to any layout parameters set using layout XML files, instead of hardcoding those pixels/dps in your Java code.
Related videos on Youtube
Sephy
Free s/Lance/Spirit Frontender with a touch of backend culture (Fullstack :D ? ) Enjoys playing with all the crazy stuff going about the web platform (React, React Native, new Web APIs, Angular, NodeJs ...)
Updated on January 25, 2020Comments
-
Sephy over 4 years
Is it possible to set the absolute position of a view in Android? (I know that there is an
AbsoluteLayout
, but it's deprecated...)For example, if I have a 240x320px screen, how could I add an
ImageView
which is 20x20px such that its center is at the position (100,100)?-
Drew LeSueur over 11 yearsalso see
view.setTranslationX()
orview.offsetLeftAndRight()
-
Manuel about 11 yearsI've just released a library that may have been of interest here. github.com/ManuelPeinado/ImageLayout
-
edthethird over 9 yearsThis is so difficult because 99.9% of the time absolute positioning is a bad idea on android. If you are writing an app that will ONLY ever be run on one physical device, then this might work, but that is generally not a safe assumption to make. For example, do not upload this to google play. It works fine on iOS because there are only a handful of hardware devices, and you can build a custom storyboard for each one.
-
William Jockusch over 9 years@edthethird, In my cross-platform app, I get the screen size and base everything on that. I just switched over to the "obsolete" AbsoluteLayout, and it works fine.
-
edthethird over 9 yearsfair enough, but that's what a Relative Layout or LinearLayout will do for you automatically.
-
Paul McCarthy about 7 yearsWhy was AbsoluteLayout deprecated? Surely the need to place widgets in exact positions for certain apps has not gone away!
-
-
Sephy almost 14 yearsI'll have a go at that tonight, that's a pretty nice idea, don't know why I didn't think about that. As I have several
ImageView
to put, wouldn't it be better to use aFrameLayout
? -
Sephy almost 14 yearsIndeed this seems to work, however, it's only working when a add one picture this way. if I try to add a 2nd one, the first one just vanishes...
-
Andy Zhang almost 14 yearsThe two images are just on top of each other. I will add some code to my solution above to explain.
-
Sephy almost 14 yearsYeah indeed, i found that yesterday too by digging your solution on my own. I also try stuff with the FrameLayout. My actual issue is that I have 5 images with each a random (x,y) position, so I can't use RelativeLayout.RIGHT_OF or something like that. The strange thing is that i can get 3 images to be placed properly but 2 of them aren't working...I don't understand... I'll update my post with some screenshots tonight and some code.
-
Andy Zhang over 13 yearsThe above method pretty much does the same thing as absolute position. If you have any other concerns, I'd be happy to help!
-
Nathan almost 13 yearsWhy would using this method be any better than using AbsoluteLayout? Just because AbsoluteLayout is deprecated?
-
G_S almost 12 yearsloved this sample. Can you suggest me how can i set the x,y axis when i am having the image in the xml layout.(i am trying to resize the image and i need to set the image at some position)
-
Excrubulent almost 12 yearsI'm afraid I don't quite understand what you're asking. Are you trying to access the LayoutParams object associated with an object that has been positioned using the XML layout? I'm not sure how that's done. It might be worth setting up a new question to have this answered, if you can't find the answer elsewhere.
-
G_S almost 12 yearsplease have a look at this question stackoverflow.com/questions/12028404/…
-
KumailR over 10 years@sephy for your situation you can have your each view set to parentleft and parentTop = true, and by setting x, y position to leftmargin and topmargin respectively.
-
KumailR over 10 yearsabsolute layout is deprecated as because of different screen sizes. but with some calculation we can use absolute values to check whether one view on right,left,top,bottom of other view but for width and height sounds complicated; this way we can implement absolute behavior using relativelayout.
-
Lisa Anne over 8 yearsBrilliant! Worth the 500! +1