Android: Alternative to AbsoluteLayout (I really do need absolute positioning) - android

I am trying to write a calendar app and I plan to have a grid (week view) which will probably be a TableLayout and directly on top of that I will have to absolutely position events on the grid.
But AbsoluteLayout is deprecated. What should I use instead?
Events may overlap and I think it would be really silly to try and use a non absolute layout to achieve what I want.
Maybe I should use RelativeLayout with a margin left and margin top on each of the child nodes. Seems odd to do it that way and might not be as efficient. Is this the best way or is there an alternative?

But AbsoluteLayout is deprecated. What should I use instead?
Write your own layout manager that implements the rules you want.

CommonsWare suggested writing my own layout manager and Christian pointed out it sounds easier than it is.
Yahel suggested SurfaceView/OpenGl and draw whatever I want.
I found out you can recreate absolute positioning by adding your child views to a RelativeLayout and set the RelativeLayout.LayoutParams to have only default values except width, height, marginTop and marginLeft. The top and left margin will be similar to top and left in AbsoluteLayout. Also, negative margins are supported.
Make sure you account for screen density and width and orientation changes and all the other caveats of absolute positioning that used to apply to AbsoluteLayout
If you have problems with getting your content to overflow past the right edge of the screen, try supplementing your positive left margin with an equally negative right margin. (original question)

I would suggest either going the easy way :
Setting your calendar for 15(or 30) minutes intervals, this way you don't need absolute positionning. A table view filled with linear view each representing 15 minutes interval and fill these with events.
Or going the hard but a lot more stable/speedy/customisable way :
SurfaceView/OpenGl draw your own however you want.
The problem with number 1 is the fact that the more you add elements in your view hierachy the more your app will take a performance hit. Say a conventional month you have 3 appointments a day, your hierarchy will be filled with a hundred views wich will be very long to render and heavy memory-wise too.
The problem with number 2 : Well it's a lot harder to code at first. If you have to write your own layoutmanager, don't, go surfaceview or openGL.

Related

Suggestions on approaches on achieving a specific layout on Android

I am trying to replicate the below layout (Boxes with Text and a line going outwards on a dedicated section) on Android
As evident, these boxes can be implemented as individual views (or drawable) to have the shape as
.
It is apparent that these boxes need to have some flexibility for the "wires" going out of them, most importantly deciding the "turning" point of the line. I have thought of a few approaches to achieve this:
Achieve the entire layout just by using image drawable and positioning the text boxes at exact places
Implement this with a dedicated view to have full flexibility of positioning the text boxes at any position and be compatible with all screen sizes.
I am inclined towards trying #2, but can't get my head around where to start. At first, I am not able to decide on whether I should be using a ViewGroup as the base class and add a TextView and a plain view as a child or should I be using a single View to implement this? The second thing I am concerned about, is whether I am overthinking it and there is an easy way to achieve the same thing (Just to save time, nothing else)?
Any help/guiding material is deeply appreciated. Thanks in advance.
I think that approach #2 will be better longer term. Because of the nature of the image, you will have to maintain the aspect ratio; otherwise, the person is stretched. Because you are maintaining the aspect ratio (at least the person-part), the placement of each text box and end point can be expressed as a percentage distance from an edge or the center lines.
Assuming the image you show is the entire image, the belly end point can be set at, say, 45% of of distance from the left edge and, also let's say, 42% of the distance from the top. The text boxes can be placed likewise. Once the text boxes and end point are place, the lines simply connect them. Now the image can stretch to any size to support multiple screen sizes and, as long as the aspect ratio is respected, and look good.
Take a look at ConstraintLayout and its percentage guidelines and barriers. There is also some radial placement which may help. You may still have to support the layout with a little code, but ConstraintLayout should be able to get you 95% of the way to a solution.
Edit: I meant to mention biases as well which may be the most helpful to you. Here is an example of using biases for a checkerboard solution that may be useful.

How does fill_parent in Android actually work under the hood?

I see great value in fill_parent, and I'd like to make my own implementation of it so I can do more than just fill the remaining space (ex: fill 80% of the remaining space, etc.)
How does fill_parent actually work under the hood? As in how does it compute the space remaining, how does it work at runtime, etc.
I've done similar things to fill_parent in the past where I calculate the space an element should take up based on the current screen size, how much of the screen the element should take up, etc. but I want to know specifically how Android does it with fill_parent.
Try creating a custom View or ViewGroup and you will find out.
There's 3 stages on bringing a View to your screen:
measure
layout
draw
In measure the parent tells the child how much space is available. It may do that in respect to the childs layout parameters. So if the child says match_parent (fill_parent is deprecated) the parent will pass in either its own size, or the remaining space (most of the time...)
The child then takes the available size, calls setMeasuredDimenstion(allTheSpaceIGot) and that's measuring for you.
Next up during layout, the parent checks the childrens measured sizes. It then sets the childrens bounds (top, left, bottom, right) accordingly.
Finally in onDraw every child draws itself within its bounds.
To sum this up:
Child gives parent information about its wishes.
Parent offers child some available space.
Child says "I'll take it".
Parent gives child its final restraints
Child draws itself within the constraints
If you want to assign say 60% to a view you should have a look at creating a custom ViewGroup (since that is who actually decides on the childs dimensions)
I also wrote a blog post about custom views that goes into more detail, followed by how to create a custom layout.
The entire source code for Android is open source, freely available within a few clicks on Google, so you can read it and study it all you want.
But just a fair warning, it's definitely no small task you're trying to accomplish, as there are an enormous amount of cases you have to account for.
If you want a layout to take X percent of available height/width, take a look at PercentageRelativeLayout
Just FYI: 'fill_parent' is deprecated, use 'match_parent' instead. They literally do the exact same thing, it's simply a different word.

What do margin values for a Toast do?

The Android Toast class provides methods to get and set margins. I'm pretty sure they refer to the outside margins for the whole toast message. Since Toast messages float over the UI, why exactly are these Margins necessary?
I tried looking over the SDK reference as well as searching the Internet. The closest thing to a solution I found was a one line suggestion that both margins and offsets allowed control over the positioning of a Toast. Why would I need two methods (albeit conceptually different, since margins allow specification in terms of percentage container width), to control the positioning of the Toast?
Just to be sure, these margins don't work like padding for other layouts does it? That would not make sense, but I'd like to be clear.
In sum, I want to know why margins are needed, what margins do, and the use-cases for margins versus offsets, that is, when should I use margins, when should I use offsets, and why?
Update:
I haven't managed to find any answers yet. I've tried using margins versus using offsets in code and found that they seem to offer two different paradigms of positioning the Toast. The design intent (why two methods), when I should use one method versus the other (or at least examples of when one was found more useful than the other by other programmers/UI designers), and even the exact operation (do margins "center" the toast inside them? are margins applied against the closest container edges?) of these methods remain unclear.
Update 2:
I looked at the docs closely, and also at some code for Toast.java that Google pointed me to. What became apparent is that the Toast is contained within a Window (Activity window?) and that it might be an overlay. The WindowManager.LayoutParams class has also provided further clues. I've decided to play a bit more with using Toasts, offsets and margins, as well as look at the code from the AOSP to get a clearer understanding.
I'll update here as I discover more.
I believe the margins determine how far the toast appears from the screen edge. You can also call setGravity() to change which side of the screen it appears on, and then use the margins to control how far away it is from the side of the screen. So for example:
myToast.setMargin(10, 20);
Will create a toast that has 10% of the containers width between the edge and the container, and 20% of the containers height between the toast and the containers edge
To create a toast that is in the top left corner of the container, with a 10 pixel margin on the left and 20 pixel margin from the top:
myToast.setGravity(Gravity.LEFT| Gravity.TOP, 10, 20)

How to create a regular, resizable grid without nested weights?

I've one of the simplest layouts imaginable: A num pad.
I want to create a fragment containing a 3 x 4 grid of buttons. The layout should automatically resize the num pad to fill the available space.
I've learned, that GridLayout is not up to the task, and TableLayout/TableRow or nesting LinearLayouts means nesting weights, which is also discouraged for performance reasons. A RelativeLayout won't work either, because that requires at least one button with given dimensions.
So, is there a clean way to create a regular grid that will resize to fill its parent?
Any help is appreciated, thx!
You will need a custom compound control.
Check the following link:
http://developer.android.com/guide/topics/ui/custom-components.html#compound
Make the control fill the available space. Make it to have 12 buttons. Calculate the size and position of them based on their position and the available space.
Depending on your needs you might also need to override onMeasure() and onLayout() defined earlier in the above document, in the "Fully Customized Components" section.

Position subviews in Android

I'm trying to understand Android's View structure and I'm a little confused on how to position child views
Let's say I have a FrameLayout that will contain my custom view. My custom view only draws a rectangle 50x50 px.
So I set my View.setMeasureDimension(50, 50);
Now how should I move this view? I found a couple of ways of doing it.
1: I could do something like canvas.drawRect(new Rect(offsetX, offsetY, right, bottom)); but this will make my View larger and thereby my measureWidth / height are not valid any longer?
2: Set padding on the parent element, and thereby affect the left / top View.getLeft() / View.getTop(). But this will affect all child elements.
3: Use View.offsetLeftAndRight( number of pixels to move ). I do not quite understand what this actually does. Does it cause some kind of canvas.translate() ? But this way I need to keep the state on how many times I called offsetLeftANdRight() because calling offsetLeftANdRight(10) and then offsetLeftANdRight(10) will move it 20px.
I'm a bit confused on what way is the "correct" way of doing it. Is there a better way?
Android apps run on devices of different sizes, with often completely different screens. Because of that you shouldn't be using any absolute positioning or sizing. Wherever possible create views and position them relative to each other.
You need to become familiar with the various views Android provides to create layouts:
http://developer.android.com/guide/topics/ui/layout-objects.html
It sometimes takes a lot of thought as items will be positioned differently on different devices (and orientations) so the view relationships are more important than absolute positions.
LinearLayout is a good all-purpose container for placing controls, though RelativeLayout is often more efficient (if a bit harder to use sometimes)
Once items are positioned relative to each other you can use padding and margins to tweak their positions.

Categories

Resources