Android: centering buttons with percent width - android

I have in my Android app a fairly simple Activity that displays three buttons, each launching a different Activity. Currently, I use a RelativeLayout to center the middle button both horizontally and vertically, then place the top and bottom buttons 30dp off the middle one (and also horizontally centered).
What I'd like to do, however, is make the buttons stretch to be a certain percentage of the screen width. I can't figure out how to do this and keep the buttons centered. Is there a good object I can use as a "filler" in a LinearLayout on either side of the buttons (so I could just set the weights)? Or is there a way to do this that doesn't involve a LinearLayout?
The XML for the layout as it stands is:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<Button
android:id="#+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="#+id/button2"
android:layout_centerHorizontal="true"
android:layout_marginBottom="30dp"
android:onClick="button1Callback"
android:text="#string/button1Label" />
<Button
android:id="#+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:onClick="button2Callback"
android:text="#string/button2Label" />
<Button
android:id="#+id/button3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/button2"
android:layout_centerHorizontal="true"
android:layout_marginTop="30dp"
android:text="#string/button3Label" />
</RelativeLayout>

Sure. View or Frame both work.
<LinearLayout android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<View android:layout_height="0dp"
android:layout_width="0dp"
android:layout_weight="60" />
<Button android:layout_height="wrap_content"
android:layout_width="0dp"
android:layout_weight="20" />
<View android:layout_height="0dp"
android:layout_width="0dp"
android:layout_weight="20" />
</LinearLayout>
works fine as a spacer and seems to be utterly harmless as far as I can tell. I use this quite a bit in my app (although honestly, most of my buttons are fixed-width).
At one point I actually wrote a custom view with proportional layout. But in the end I ended up not using it at all. In almost all cases you can get equivalent proportional layout with judiciously applied weights in a linear layout.

Related

layout button corresponts to background

In Android Studio, I want the size of the buttons as well as the distance between them to change with the size of the display.
Basically, I have a background with special places for buttons (I know it's a bad practice) and on different screens, the buttons don't fit the background.
I've tried to accomplish this via ConstraintLayout, but match_constraint makes the size of the button large as the container and margins are static.
I've tried this answer to a similar question, but it didn't work properly.
I didn't manage to do this in ConstraintLayout either. A chain with percentage guidelines will need its children to be set to wrap_content. Therefore the size of the buttons will remain the same, for example in landscape and portrait modes. Therefore I used "empty" Views in a LinearLayout. By giving each element, the buttons AND the empty views, a weight, you can achieve the effect of button sizes relative to screen width. Voila:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<View
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight=".1666" />
<Button
android:id="#+id/button1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight=".25"
android:text="Button1" />
<View
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight=".1666" />
<Button
android:id="#+id/button2"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight=".25"
android:text="Button2" />
<View
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight=".1666" />
</LinearLayout>

Android UI: Size 2 view?

Good day everyone, currently i'm trying to make my first Android app, and then the first thing i realized, that idiotic XML UI designing.
I have this 2 view (button) and i'd like to make them so the first one fill the half of the parent (RelativeLayout) and the second one fills the other half of the parent...
My Code is:
<Button
android:id="#+id/Top1"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_alignParentLeft="true"
android:layout_toLeftOf="#id/Top2"
android:text="top1"/>
<Button
android:id="#+id/Top2"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_alignParentRight="true"
android:layout_toRightOf="#id/Top1"
android:text="TOP2"/>
The problem, that i'm get this error:
"No resource found that matches the given name (at 'layout_toLeftOf' with value '#id/Top2')."
It seems, that not even Android want to use XML.
Like an old C program where if a method is written below the call, it will give an error...
So i have 2 question:
1: How to solve this problem in the XML?
2: Or can i avoid this XML designing, and use code-like design like in C# ?
There are a few ways you can go about this and I provided you with two ways to have buttons aligned side by side.:
Use a LinearLayout with orientation set as horizontal
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/btn_container">
<Button
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="Left Button"
android:layout_weight="1"
android:id="#+id/btn_left" />
<Button
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Right Button"
android:id="#+id/btn_right" />
</LinearLayout>
Use a RelativeLayout and an extra View to align your buttons.
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<View
android:id="#+id/strut"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_centerHorizontal="true" />
<Button
android:id="#+id/btn_left"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignRight="#id/strut"
android:text="Left Button" />
<Button
android:id="#+id/btn_right"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_alignLeft="#id/strut"
android:layout_alignParentRight="true"
android:text="Right Button" />
</RelativeLayout>
You are correct, Top2 needs to be defined first in the XML before you can refer to it. That being said, if all you are doing is putting 2 buttons next to each other and have them fill the parent, you should consider using a LinearLayout. Order is important there, too: for horizontal orientation the children are laid out left to right, for vertical they are laid out top to bottom.

how to align an element to right in horizontal LinearLayout?

I have a LinearLayout that contains a lot of TextViews and ImageButtons, I want to align some of these elements to right, i had a look at this and this but i can't use their tips as i can't change the orientation and can't make android.gravity:right as i don't want to align all the elements to right, also i can't use nested layouts or but the desired elements into RelativeLayout because that shifts the rest of elements to the left and i want them at the center.
this is my code:
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="0.15"
android:layout_marginTop="10dp"
android:layout_gravity="center"
android:gravity="center"
android:background="#drawable/media_mediabar"
android:orientation="horizontal" >
<ImageButton
android:id="#+id/move_backward"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:adjustViewBounds="true"
android:background="#android:color/transparent"
android:clickable="true"
android:scaleType="centerInside"
android:src="#drawable/media_button_rewind"
android:layout_marginLeft="7dp"
android:layout_marginRight="7dp"
android:tag="released"/>
<ImageButton
android:id="#+id/rmeote_mines"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:adjustViewBounds="true"
android:background="#android:color/transparent"
android:clickable="true"
android:scaleType="centerInside"
android:src="#drawable/remote_minus" />
<TextView
android:id="#+id/remote_plus_minus"
android:text="0"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#android:color/white"
android:layout_gravity="center"
android:layout_marginTop="15dp"
android:layout_marginBottom="15dp" />
.
.
.<!.. some other elements ..!>
</LinearLayout>
The desired result:
The simplest solution would be using empty views with weights as separators.
<LinearLayout android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<!-- Left button -->
<Button ...
... />
<View android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1" />
<!-- Middle button -->
<Button ...
... />
<View android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1" />
<!-- Right button -->
<Button ...
... />
</LinearLayout>
The separator views can be made invisible as an optimization, because they don't draw anything and are used only for layout. You can tweak the actual 'layout_weight' values to get the desired layout. Starting from API level 14 you can use instances of Space as separators which will improve performance and readability (there is also a version of Space in the support library).
For such a complex layout you'd be way better of using RelativeLayout instead.
i can't use nested layouts
Then you can't solve your problem.
Nested layout are the heart of Android layout, to create such complex view that you desire, I think you must use nested layouts.
#Ridcully suggested you to use RelativeLayout, this is a good idea. You can combine it with few linear layouts and you be fine.
I think that RelativeLayout should be your base layout.

Create 4 ImageButtons at bottom of the layout

I am trying to display 4 ImageButtons at the bottom of the layout. I am able to get only 3 ImageButtons. The fourth ImageButton is not visible. and here is my code for that.
I am using Relative Layout for to display the application.
<ImageButton
android:id="#+id/Button1"
android:layout_weight="1.0"
android:layout_gravity="bottom"
android:layout_alignParentBottom="true"
android:longClickable="true"
android:layout_width="wrap_content"
android:layout_height="75sp"
android:background="#android:color/transparent"
android:src="#drawable/imagebutton2"/>
<ImageButton
android:id="#+id/Button2"
android:layout_gravity="bottom"
android:layout_toRightOf="#+id/Button1"
android:layout_width="wrap_content"
android:layout_height="75sp"
android:background="#android:color/transparent"
android:src="#drawable/imagebutton1"
android:layout_weight="1.0"
android:layout_marginLeft="2dp"
android:longClickable="true"/>
<ImageButton
android:id="#+id/Button3"
android:layout_gravity="bottom"
android:layout_toRightOf="#+id/Button2"
android:layout_height="75sp"
android:layout_width="wrap_content"
android:layout_weight="1.0"
android:background="#android:color/transparent"
android:src="#drawable/imagebutton1"
android:layout_marginLeft="2dp"
android:longClickable="true"/>
<ImageButton
android:id="#+id/Button4"
android:layout_gravity="bottom"
android:layout_height="75sp"
android:layout_width="wrap_content"
android:layout_weight="1.0"
android:background="#android:color/transparent"
android:src="#drawable/imagebutton1"
android:layout_marginLeft="2dp"
android:longClickable="true"
android:layout_alignParentRight="true"/>
Put it in a LinearLayout with weights and align this LinearLayout tot he bottom of the parent like this:
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_alignParentBottom="true" >
<ImageButton
android:id="#+id/ib1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1" />
<ImageButton
android:id="#+id/ib2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1" />
<ImageButton
android:id="#+id/ib3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1" />
<ImageButton
android:id="#+id/ib4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1" />
</LinearLayout>
Note that this method will decrease the performance somewhat.
First you need to remove this from your ImageButton attributes if you want to keep using RelativeLayout as their parent layout:
android:layout_weight="1.0"
It is used in LinearLayout, Lint should be giving you a warning about it (invalid layout param in RelativeLayout).
If you want your 4 buttons to show in the bottom of the screen you need to include
android:layout_alignParentBottom="true"
in all 4 ImageButtons, I tried the xml you provide and only the 1st button is showing in the bottom.
And last but not least, if you want your button to have the same size to have some design consistency, I would suggest putting them in a horizontal LinearLayout with
android:layout_alignParentBottom="true"
android:layout_width="fill_parent"
and configure the ImageButtons with
android:layout_width="0dp"
android:layout_weight="1.0"
then include that LinearLayout in your RelativeLayout.
Another thing : since you're using
android:layout_width="wrap_content"
for your ImageButtons, you need to make sure the image is not too wide, otherwise some of your buttons might not be shown on screen because the first one(s) is taking too much space, leaving the last one(s) to the right of your screen.
On a side note, I hope you're not trying to make a iOS-style lower tab bar, this is frowned upon in Android, more info here ...
Have a good one !
Like some people say, in the last button, you don't have android:layout_toRightOf = "#id/Button3" so it's going to be in the top of the layout.
Other way to do this that I usually do is:
android:layout_toRightOf = "#id/Button1"
android:layout_alignbottom = #id/Button1"
It's going to align with the bottom of the button1. I do this because sometimes this button isn't align with the other one, depends of the layout.
At the last ImageButton you don't have:
android:layout_toRightOf="#+id/Button3"
You will need this if you want it to be at the bottom.
I would also suggest that you remove some of your code:
android:layout_gravity="bottom"
android:layout_weight="1.0"
This only works in FrameLayout or LinearLayout.
If you want to know for sure every ImageButton is at the bottom of the screen use what you used for the first button:
android:layout_alignParentBottom="true"

button placement in a linear layout

I have a linear layout with several buttons in it. The button images are all the same size and have the same attributes... except for one button. This one button has a smaller font size. All the buttons except for this one are in a perfect line exactly the way I want. For some reason, the button with the smaller font appears a little lower on the screen than the other buttons. I'm having a hard time wrapping my head around the idea of a button that requires less space taking up additional space.
Might someone give me a hint on what to read up on?
EDIT
Here's main.xml (seems like SO filters some of it, all the important stuff is here...)
<ScrollView android:id="#+id/scroll"
android:layout_width="match_parent"
android:layout_height="300px">
<TextView
android:id="#+id/the_text_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:typeface="monospace"
android:textSize="9pt"
android:background="#color/paper"
android:paddingLeft="20dp"
android:paddingBottom="20dp"
android:textColor="#color/type"
/>
</ScrollView>
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<Button style="#style/ASR33_button"
android:tag="Y"
android:text="Y"
/>
<Button style="#style/ASR33_button"
android:tag="N"
android:text="N"
/>
<Button style="#style/ASR33_button"
android:tag="E"
android:text="E"
/>
<Button style="#style/ASR33_button"
android:tag="W"
android:text="W"
/>
<Button style="#style/ASR33_button"
android:tag="S"
android:text="S"
/>
<Button style="#style/ASR33_button"
android:tag="F"
android:text="F"
/>
<Button style="#style/ASR33_button"
android:tag="R"
android:text="R"
/>
<Button style="#style/ASR33_button"
android:tag="M"
android:text="M"
/>
<Button style="#style/ASR33_button"
android:tag="T"
android:text="T"
/>
<Button style="#style/ASR33_button"
android:onClick="onEnterButtonClicked"
android:textSize="6pt"
android:text="RE-\nTURN"
/>
<Button style="#style/ASR33_button"
android:tag="U"
android:text="U"
/>
</LinearLayout>
<LinearLayout
android:orientation="horizontal"
android:layout_marginTop="10dp"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="#+id/instructions"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:textSize="9pt"
android:paddingLeft="10dp"
android:typeface="normal"
android:text="Commands: (Y)es, (N)o, (N)orth, (E)ast, (W)est, (S)outh, (M)ap, (ST)atus, (Fight), (R)un, (SU)icide. All commands must be followed by RETURN."
/>
</LinearLayout>
The one that's wonky is the 2nd from the bottom, with the different onclick event. The style has 11pt for the character size. If I use it (and a 1 letter button name, like the others) it behaves. But that's not what the ASR33 'enter' key has on it. So if I reduce the font size to say 6 pt, the weirdness happens.
The style can be seen here.
Again, just reading references or ideas please, I can figure it out if I have a word or two to search on. It's hard to know what you don't know...
RESOLUTION
Anurag has it right, see his answer below. Here's an excerpt of the updated LinearLayout:
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:baselineAligned="false">
maybe the re sizing has happened due to the wrap_content property of your button. so what you should do is have a fixed height to the linear layout holding all the buttons while its with is set to fill parents.
and inside the linear layout let individual buttons have height set to wrap content which will give all the buttons the same height as that of the linear layout and also set the attribute android:adjustViewBounds="true" for the small button. this attribute will resize your image button to maintain the aspect ratio. i hope this helps.
EDIT:
So here is the solution to your problem, something that was caused due to the base alignment property of the linear layout. A horizontal LinearLayout aligns the baselines of all its child controls by default. So the first line of text in your multi-line button is vertically aligned with the single line of text in the other buttons. set android:baselineAligned="false" on the LinearLayout. This worked perfectly on my HTC.

Categories

Resources