tags:

views:

157

answers:

3

I see posts saying that FrameLayout is the alternative, and that I should use margins to position things (this strikes me as wildly counter intuitive, but ok... if it works, I'll take it). However, I can't get it to work, so, I'm looking for assistance.

here's my code

    FrameLayout layout = new FrameLayout(this);
    layout.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));

    Button btn = new Button(this);
    btn.setBackgroundResource(R.drawable.btn);

    FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
    lp.setMargins(100,100,100,100);

    btn.setLayoutParams(lp);   //i've tried with and without this line, no change

    layout.addView(btn , lp);

The button is drawn at 0,0 no matter what I do. When I change the lp's LayoutParam to FILL_PARENT the button is then stretched to take up the entire screen (which makes sense).

HOW do you get it to draw somewhere else on the screen, irrespective of what else is there?

As always, super grateful in advance.

[EDIT] It seems my question isn't entirely clear (given the answers) so...

In the code above, the intent is to create a button, pass it to a layout and have it draw at 100,100 on the screen.

I'm aware of the fact that this may mean different things on different devices. I'm ok with that. I simply need a way to, programatically, and at run time, place an item at a SPECIFIC location. I don't want to rely on gravity (or the laws of thermodynamics). I just want to specify a location and have the element appear there :)

A: 

What exactly is your final objective with the layout? If all you need is a button -- say, in the center of the screen, you can just make a layout with:

<RelativeLayout
    android:xmlns="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:gravity="center"
    >
    <Button
        android:id="@+id/the_button"
        android:layout_width="wrap_content"
        android:layout_height = "wrap_content"
        android:text="@string/the_button_text"
        />
</RelativeLayout>

AbsoluteLayout is a bad idea because of the large number of screen resolutions you need to support. 100 pixels over on one screen may be halfway, while it may be less than a quarter across the screen on a higher dpi device.

kcoppock
I see this answer again and again... I get it... screens vary in size. But this is extremely frustrating. I'm not asking for alternatives to solutions to my problem... I'm asking for THE solution! I don't want the button in the center. I want it at a specific place, given the design. I have a graphical design which calls for the button to be at a specific X and Y location. I'm ok with the multitude of screen sizes. I'm WILLING to use AbsoluteLayout (I know it's deprecated)... I just want the answer :)
Dr.Dredel
If you think there's 1 single answer to any programming question, then maybe you should be doing something else.
Falmarri
Your very question title is asking for an alternative. Do you want it in a specific x,y coordinate relative to the top left of the screen? Do you want it in an x,y coordinate relative to another object in your layout? If you are really determined to use AbsoluteLayout, go ahead, but it's not the right way to do it.
kcoppock
Falmanrri... what I mean is, no one is answering the actual question. Basically the answer is always "why not do something else". I'm perfectly aware that there are many ways to skin a goat... I'm just asking for 1 but I want to skin a goat, not milk a kitten.
Dr.Dredel
Just use AbsoluteLayout if that's what you want to use. Or write your own.
Romain Guy
kcoppock, my question title implies that Android has done away with a way to do something and I can't figure out what the alternative is to doing that same something. I understand why Absolute is a sub-ideal approach, I'm just saying I can't find the correct way to replace it. (and as it happens, even Absolute doesn't seem to offer me the ability to move my Image to a specific (x,y) at runtime. This is what I'm trying to do.
Dr.Dredel
@Romain Guy -- If you can illustrate how to do this using AbsoluteLayout, I'll gladly give you the green check mark :) In the XML, when a view is the child of an AbsoluteLayout, you can legally use "android:layout_x" on it. And it works. At runtime however, when I create a new View (or Button, or anything that's View derived) and set it as a child to my AbsoluteLayout, there is no way to set a position property. There is a layout() method which doesn't seem to affect the items position on the screen.
Dr.Dredel
Because there's not a particular x,y value you can move it to that is going to work for all screen sizes, or even most. Once you start thinking about landscape layouts, your code is going to work even less. The alternative to AbsoluteLayout IS RelativeLayout. Of course it doesn't do things the same way -- if it did, there would be no point in deprecating it. Absolute coordinates just cannot work for the variety of screen resolutions that Android does and will later support. You need to rethink your layout structure.
kcoppock
"I have a graphical design which calls for the button to be at a specific X and Y location." -- then fix the design.
CommonsWare
ok, come on. There's no need for this to be adversarial. You guys have all been in the situation where you're given a design that you have to make work somehow. There's *usually a way, even if it's not the best way. Multiple screen resolutions are not a new phenomenon! In Brew and J2ME the environments are very very varied, but that doesn't prevent us from drawing things where we want to on the screen. Anyway... no need continue this, I'll take the question down if there's really no answer.
Dr.Dredel
Dredel, I don't intend for any of my comments to be taken as hostile in any way, but it really is a different architecture, absolutely positioning just doesn't work. If you could be more specific, or give an example of why you need something positioned absolutely, I'm certain we could give you a reasonable alternative.
kcoppock
@kcoppock -- ok, so, in my specific case, I have a camera app which has a "frame" around the camera preview. Somewhere in this frame is the "take picture" button. It's not exactly left or right or center (as the layouts seem to push everything towards). It's 20 pixels north of the bottom of the screen and 200 pixels east of the left of the screen. I'm not worried about phone rotation as the whole Activity is locked into landscape mode (though my coordinate descriptions above are of the portrait mode). How would you do this (other than telling the designer to alter the design).
Dr.Dredel
If your button is actually part of the image that is your frame, separate the button from the background. Save your button as a separate PNG image, and the frame sans button as a separate PNG image. Then there are several options for placement of the button. First thing that comes to mind is (I'm not certain if you're placing the frame above the camera view, or if the camera view is within the layout) a simple LinearLayout, and set the gravity to bottom|left, Add a button view, specify the width and height to wrap_content, set the left margin to 200px, and the bottom margin to 20px.
kcoppock
Since you need it relative to the bottom left of the screen, absolute layout won't help you much anyways. I'd use a relative layout with align parent bottom. To achieve the offset, you could give the button some padding, or use another relative layout where the button is pushed to the upper right. Give that layout a fixed size, but in dp units, not pixels so that it will make sense at different screen resolutions.
Mayra
odd, when I do what you suggest (kcoppock) the button just sits at the bottom left... the margins don't push it away. hard to paste code into here. I'm calling setMargins() on the LayoutParams and then saying ll.addView(btn, lp); is this wrong?
Dr.Dredel
You'll probably have an easier time doing it in xml.
Mayra
Hmm, to be honest I've not done any layout in java yet; all my layouts have been done in XML so far. I'm sure you know, but you are keeping in mind that the margins are declared in order of left, top, right, bottom, correct? So it would be setMargins(200, 0, 0, 20);
kcoppock
Myra, yes! however, I can't do it in xml because this is all sitting on top of a camera surface. In addition to this problem I also couldn't figure out how to shove a camera preview into a SurfaceView that was defined in the XML, so, I'm just adding content views on top of the camera surface as I go (at least it works!) :)
Dr.Dredel
+1  A: 

A good explanation of the different available layouts is available at http://mobiforge.com/designing/story/understanding-user-interface-android-part-1-layouts

As I do not completely understand from your description what you're trying to accomplish (do you want to overlay stuff?) maybe the visual examples there can help you in understanding how the layouts work and how to position stuff on them.

Kosi2801
Ok, you see how in that link they describe both FrameLayout and AbsoluteLayout as having an android:layout_x param? The compiler doesn't recognize layoutX or layout_x or anything like that associated with either FrameLayout or AbsoluteLayout. So, what I'm trying to do is simply position an element at a specific location, at runtime, and I am not seeing any way to do it.
Dr.Dredel
+2  A: 

As many have pointed out, setting a button at an absolute pixel position on the screen is a really bad idea, and will never work across all of the available android phones. I'm sure there is a better way to achieve the layout you want.

However, to answer the question as asked: to position it at runtime you can use the AbsoluteLayout.LayoutParms.

AbsoluteLayout absoluteLayout = //get absolute layout

Button button = new Button();
AbsoluteLayout.LayoutParms params = absoluteLayout.generateDefaultLayoutParams();
params.x = 100;
params.y = 100;

absoluteLayout.addView(button, params);
Mayra