I have a UI Design from my designer, and it exists of a background map with several buttons on it, positioned non-linear all over the map. Currently I position them in a RelativeLayout that is as large as the map, and use margin-left and margin-top etc in dip.
This works ok, but I also need to account for users with very small screens, that cause the map to scale down. My relative layout scales with it, but the margin values ofcourse not.
So I am wondering, how should I do this? I would prefer to layout these buttons using percentages like
left="30%"
top="50%"
Is there anything in Android that makes such a thing possible? Otherwise I have to come up with a custom layout class for that.
Visual Representation: (Ofcourse they don't actually are on 6 lines, and partially overlap in x or y position). It's actually a real (abstract) map of a building with location markers that you can press as buttons.
-------------------------
| x x |
| x |
| |
| x |
| x |
| x x|
-------------------------
Here is a complicated way that does not require a custom ViewGroup. Suppose you want a button at left 30%, top 40%
FrameLayout
View with background, match parent
LinearLayout orientation=horizontal, match parent
View layout_width=0dp, layout_weight=30, height=match_parent
LinearLayout orientation=vertical, width=0dp, weight=70, hieght=match
View layout_height=0dp, layout_weight=40, width=match_parent
FrameLayout layout_height=0dp, layout_weight=60
Button
I use Dimension resource files put in the relevant layout- buckets so I can change margins/paddings/sizes depending on device size.
(http://developer.android.com/guide/topics/resources/more-resources.html#Dimension)
(Storing dimensions in xml file in Android)
Related
I would like to have a background on my app that changes color depending on a given number. Let me elaborate some more. For example, I pass the number 40 out of 100, 2/5s of the screen should be x color, and the other 3/5s should be the other color. Here are two little diagrams:
40 / 100 40/60
+---+ +---+
| | 3/5 not filled in | | 1/3 not filled in
| | |...| 2/3 filled in
| | |...|
|...| 2/5 filled in +---+
|...|
+---+
So I was thinking I could go about making a dynamic background (giving a certain number) by drawing in the shapes. The problem is, I am not exactly sure how I would go about doing this. Where do I place the code to draw the shapes, and how exactly would I insert them into my XML file in the correct place (I already have a static color background that is up in my XML)?
Ok, you need to create an activity with two Linear Layouts. The width attribute will be set to match_parent and the height to 0dp. You will then be able to set the height with a layout weight of X %.
As an example, those layouts split the screen 25% 75% :
<LinearLayout
layout_weight="1"/>
<LinearLayout
layout_weight="3"/>
Give them an id to change values programmatically (weight and background color).
You can do it this way :
LinearLayout top = findViewById(R.id.top);
//Third Param stands for weight
LinearLayout.LayoutParams param = new LinearLayout.LayoutParams(
LayoutParams.MATCH_PARENT, 0, 1.0f);
top.setLayoutParams(param);
top.setBackgroundColor(Color.BLUE);
I have a LinearLayout that contains multiple ImageButtons and TextViews. Something like this:
+---------+-----------+-------------------+-------+ <- LinearLayout
| i | i | text here | i |
+---------+-----------+-------------------+-------+
These items are hard to tap. I want to increase their tappable area. It seems as if TouchDelegate is the proper way to do this.
However, view.getParent().setTouchDelegate(new TouchDelegate(r, child)) is a 1:1 mapping, not a 1:Many mapping. So how would one solve this problem when a View has multiple children that each need to be tappable beyond their bounds?
Say we have the below vertical LinearLayout (WRAP_CONTENT on both layout width and height) with two childs Button with varying height.
{ LinearLayout
* empty space *
| |
| Button 1 |
|__________|
|Button 2| }
Why animating Button 1 "y" using ObjectAnimator, producing this:
{ LinearLayout
| |
| Button 1 |
|__________|
* empty space *
|Button 2| }
hence leaving a space there instead of moving Button2 below Button1 as well?
As for the code (nothing fancy): ObjectAnimator.ofFloat(button1, "y", delta).start();
I tried using ValueAnimator (with setY in OnAnimationUpdate() and then upon seeing the same thing,
Setting LinearLayout to invalidate during OnAnimationUpdate() also did the same thing.
tried with TranslateAnimation with fillEnabled and fillAfter being true. Both still producing this behavior.
What am I missing here? I have used LayoutAnimation but so far, I only used to animate them if a child is added or removed. Not if their bounds change.
Can anyone clue me in to the right method/terms here (or the correct way to achieve this effect)?
Note that I also actually wanted Button1 to be clipped by the parent container, if I animate beyond the parent bounds (though I not sure if it makes any difference for Button2). English isn't my first language so pardon the grammar or terms. Thanks.
Background
To learn animations, I'm creating a Towers of Hanoi type of game. My main goal is to animate the movement of the block from one tower to another. I've got the following layout
|------RelativeLayout------|
|-Linear-|-Linear-|-Linear-|
|-Block1-|-----------------|
|-Block2-|-----------------|
|-Block3-|-----------------|
|--------------------------|
ID| Tower1 | Tower2 | Tower3 |
I've set the XML attribute android:clipChildren="false" on every ViewGroup.
For example, if I tried to animate the movement of Block1 from Tower1 to Tower2 using Block1.animate().setDuration(3000).translationX(1000). As the layout is right now, Block1 will animate within Tower1, but Block1 gets clipped the second it leaves Tower1.
I've played with changing the z-order by adding the blocks last in the XML file. It doesn't reliably work, though.
To ensure animations don't get clipped, I've decided to add a copy of the Block1 (named copyBlock) to the root RelativeLayout, position copyBlock on top of Block1, and animate it to the destination Tower2 (defined in coordinates)
To get the destination coordinates, I was planning on adding an invisible copyBlock to Tower2, then get the coordinates. This way, I can take advantage of the LinearLayout's layout functions to account for matters such as padding, gravity, etc. Otherwise, I'll have to get the position of Tower2, calculate the topmost block, adjust the coordinates of Block1 so that it'll be on top of the topmost block and centered.
But, I'm pretty sure this way is hacky, and there's a better way
Questions
How can I get the above destination coordinates without having to add an invisible view to the destination tower? Is there a way to ask for a "prelayout" without having to add View to the layout?
Do you have any explanations for why the animation gets clipped? Is there a better way to approach this rather than adding a new view to the root RelativeLayout ViewGroup?
Ok,
1- You can't overcome the clipping issue, because you are trying to move the child beyond the parent dimensions, unless you are moving within the same parent.
2- Use FrameLayout instead of RelativeLayout so you can control views margins correctly;
3- You can get the destination coordinates by knowing the height of the root layout and width, its seems the towers width are equal, so the (total width/3) will give the cell width then get the X coordinate, and the (total height - cell height ) will give the Y coordinate of the tower ( assuming you have the tower hight)
I have list of images added in a LinearLayout
+------------+
| Image 1 |
+------------+
| Image 2 |
+------------+
| Image 3 |
+------------+
I want every 2nd image to get Displayed above 1st and 3rd Image.
For that I have set Bottom Margin of Image 1 to -10 pixels so Image 2 overrides Image 1 and it works, but this same logic does not work for Image 3, Image 2 does not override Image 3s Top portion, as i have given -10 top margin for the Image 3.
I have also tried bring_to_front for Image 2 but it does not work.
How Should i get it working.
Thanks,
PP.
FrameLayout will be an ideal choice for such a case. It allows z-ordering of child views and will stack all the view over one another. Using view#setVisibility(...) you can toggle visibility of your views to get the desired effect.
use framelayout(it is like div tag in html)
links:
http://developer.android.com/resources/articles/layout-tricks-merge.html
http://android-pro.blogspot.com/2010/02/frame-layout.html