What is the alternative to AbsoluteLayout in Android? - android

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 :)

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

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.

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.

Related

Android/XML: Is there a way to set images in specific places, rather than relative? Can they be set to scale properly when on a bigger device?

I have several images, that need to be in specific places, but remain separate images. For example, imagine I have an image of a face. The separate images would be the nose, the eyes, the lips, etc...
I need them in specific places on the face. The problem is two-fold:
1: I need to put them in specific locations. Relative layout doesn't seem to work super well. Unless I type the margin gaps in exactly.
2: The other issue is when I change to a different device, it screws up the positioning. If I manually enter in margins, when I move to a tablet, everything is screwed up again.
What is the best way to accomplish this?
You can create nested Linear layouts , include your components and use android:layout_weight in each of them .If you have high alignment constraints , create a separate layout for each component and accordingly use android:orientation in it. This way you won't have any positioning issues when you switch devices .
FYR
FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
layoutParams.gravity = Gravity.LEFT|Gravity.TOP;
layoutParams.leftMargin = x;
layoutParams.topMargin = y;
imageView.setLayoutParams(layoutParams);

Can android padding be made to be not clickable?

EDIT: Answer found through Emil's comments. Code ended up like this:
FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(
FrameLayout.LayoutParams.WRAP_CONTENT,
FrameLayout.LayoutParams.WRAP_CONTENT);
params.setMargins(left, top, right, bottom);
view.setLayoutParams(params);
Thanks all :D
I'm currently writing an Android application and I have a dynamically created tree which displays ImageView elements within it. However, to arrange these images I've used padding left to line them up correctly, dynamically changing how the padding is calculated so that everything turns out evenly. However when I do this, the padding covers up some of the images to the left, and even though you can see the images behind this padding, when you click on that image, it will evaluate the image who's padding is being used (the furthest left element). I'm basically wondering if there is a way to programatically set something that does what padding does to images but isn't clickable? Margins would make sense, but you cannot set margins on ImageViews.
The tree set up is like this:
-----A-----
--B--C--D--
-E-F----G--
Imagine every letter is an ImageView, dynamically placed with padding. But if I click on B or C, D's code will be evaluated because it's left padding covers B and C. The same goes for E or F, click those, and G will be evaluated. I cannot figure out a different way to place these ImageViews. Any help is greatly appreciated.
Consider replacing your padding with layout_margin property. that way the area that separates the padded view is not considered as part of the view but ratter as part of the layout it sits in.
So use
android:layout_margin="10dp"
or:
android:layout_marginLeft="10dp"
for your needs.

Android - How to draw a letter at a specific point?

I want to fill the screen with a 100 different letters in random positions. On the iPhone I just created a bunch of UILabels set their x and y positions and then used animations to move them about.
On Android it doesn't look like I can add a TextView to my view and specify its X and Y. Is there a way to do this?
View gameView = findViewById(R.id.gameboard);
tv = new TextView(gameView.getContext());
tv.setText("A");
tv.setWidth(w); tv.setHeight(h);
// How to set the X and Y?
EDIT: The solution was to use AbsoluteLayout:
AbsoluteLayout al = (AbsoluteLayout)findViewById(R.id.gb_layout);
tv = new TextView(this);
AbsoluteLayout.LayoutParams params = new AbsoluteLayout.LayoutParams(
AbsoluteLayout.LayoutParams.WRAP_CONTENT,
AbsoluteLayout.LayoutParams.WRAP_CONTENT,10,10);
params.x = 50;
params.y = 50;
al.addView(tv, params);
and to move it base on MotionEvent me:
AbsoluteLayout.LayoutParams p = new AbsoluteLayout.LayoutParams(
AbsoluteLayout.LayoutParams.WRAP_CONTENT,
AbsoluteLayout.LayoutParams.WRAP_CONTENT,(int)me.getX(), (int)me.getY());
mTV.setLayoutParams (p);
I think you are making a game and for this you should look into SurfaceView here is an good example then
1...if you look into code there is onDraw method where you will get the width of screen and height
2...Now taking this width and height as seed for random generator get x and y position.
3...Iterate through point 2 100 times and you will get the desired result
You can use a FrameLayout for this. Set each TextView's background to transparent and add it to the FrameLayout. Make each TextView, and the FrameLayout, fill their parent. The FrameLayout places all its child views at (0,0). To move letters around, just change the top and left padding of the corresponding TextView.
In android positioning child views is the responsibility of the layout class.
You need to create a custom.layout and overide the onLayout method. In this method you can iterate through all the child views calling View.layout(left,top,right,bottom) on each child.
i found this example code whilst trawling the net :
https://gist.github.com/882650
You should also check out view.setTranslationX (and Y) which might be exactly what you need
I'm not entirely sure how you'd go about doing this in code, but you need to use an absolute layout as your root element. (edit: Do not use absolute layout, as it was pointed out that it is deprecated. The closest alternative seems to be RelativeLayout.)
The properties in the XML format for the absolute layout coordinates are layout_x and layout_y.
edit: A little research is saying you need to be using setLayoutParams, but my Eclipse IDE is not working properly, so unfortunately I can't test exactly what you're looking for.

Alternative to AbsoluteLayout in Android?

If AbsoluteLayout is deprecated what can I use instead of it?
I've done an app that uses AbsoluteLayout but it doesn't work well with the different screen resolutions. I use because I can set the X and Y position of a button. Can I set the position of a button using another layout?
you can use RelativeLayouts as described here: Set the absolute position of a view
Use RelativeLayout and set left and right margins like
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);
lp.leftMargin = x;
lp.topMargin = y;
Consider using FrameLayout. If you set your child gravity to TOP|LEFT then you can use leftMargin and topMargin as the positions. As a bonus you get a few other useful positioning mechanisms by changing the gravity.
I will suggest you guys if you want to have full control over the positions of your views on the screen just to extend ViewGroup and make your own implementation of AbsoluteLayout. The easiest solution will be to use one of the existing Layouts and play with margins, paddings, gravity and so on, but the control is not gonna be so powerful and can cost some problems on the diff device screens.
I would just use a relative layout and set it based off of the other items/edges of the screen. Otherwise your layout appears different on different devices.

Programmatically resize of view depends on android version?

I am facing a weird behavior regarding the subject.
I have a very simple layout containing only an empty RelativeLayout.
Once I have input form the user this relative layout is filled with square tiles to achieve a mosaic-like effect. Each tile is made by a FrameLayout containing two images (only one is drawn at any given time). It is not possible for me to put the tiles in the XML layout because I do not know in advance how many of them I will need.
In the onSizeChanged of my relative layout, I force a resize on all the tiles to fit the new size.
The code is something like this:
public void resizeTiles(int w, int h) {
int l1 = w / X; int l2 = h / Y;
int tileS = (l1 <= l2 ? l1 : l2);
android.view.ViewGroup.LayoutParams lp;
for (Tile t : myTiles) {
lp = t.getLayoutParams();
lp.width = tileS;
lp.height = tileS;
}
}
In my manifest file I have the following:
<uses-sdk
android:minSdkVersion="4"
android:targetSdkVersion="4"
/>
Thus, target system is 1.6.
So far so good, this is working like a charm ... but only on 2.2.
The same binary placed on emulator 2.1-update1 or previous is giving me back an empty layout (I also tried a couple of physical devices, same result).
Debugging, I tracked down the problem is in the resize; commenting out width and height assignments I see the tiles but with distorted proportions.
Any suggestion on how to make this working ?
Thanks in advance.
onSizeChanged() is called late in the layout process, once the final size has been determined. There may already have been some layout passes that have happened down through the hierarchy at that point.
Basic answer is: layout params are for telling the view's parent its layout params prior to is performing a layout. If they change, the layout must be invalidated to perform a new complete layout with the new params. You should never change these in the middle of a layout.
The best thing to do is just write your own layout manager. (If you are doing layout of tiles, RelativeLayout does a ton more stuff that you don't need, making it a lot less efficient than necessary.) It is actually not very hard to write a simple layout manager.
You can use the simple layout managers in the framework as a guide:
https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/widget/AbsoluteLayout.java
https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/widget/FrameLayout.java
(Note that even these are a lot more complicated than you probably need, since they are intended to be general purpose for the layouts they are implementing. We really should have an API demo of a custom layout that is truly simple.)

Categories

Resources