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>
Related
I have 4 image buttons which should be aligned like this:
As you can see they overlap, so I can't use a simple table layout, because of "collapsing" table rows. My attempt was to use transparent images among those image buttons while I used nested and overlapping LinearLayouts to align them. With this attempt I don't have to worry about density related calculations. This seemed to work in the first place, but unfortunately one of the invisible buttons overlays the real image buttons, so I can't click at least one image button anymore, because it's like clicking the invisible button, overlaying the real image button.
Another difficulty is that I can't use density related alignments within the xml file. The reason is that these image buttons are scaled in a different way than other scaled images. This is because these image buttons should always be as big as a thumbnail despite of a phone or a tablet. So the usual alignment with margin is not applicable here.
I think the only way to achieve this is to calculate it programmatically. Or any other ideas?
Here's my version (less Views), based on my original tip:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/controller_container"
android:layout_width="240dp"
android:layout_height="240dp"
>
<ImageButton
android:id="#+id/button_invisible_center"
android:layout_width="80dp"
android:layout_height="80dp"
android:layout_centerInParent="true"
android:contentDescription="button_invisible"
android:visibility="invisible"
/>
<ImageButton
android:id="#+id/button_left"
android:layout_width="80dp"
android:layout_height="80dp"
android:layout_toLeftOf="#id/button_invisible_center"
android:layout_alignTop="#id/button_invisible_center"
android:background="#drawable/button_control"
android:contentDescription="#string/button_left"
/>
<ImageButton
android:id="#+id/button_up"
android:layout_width="80dp"
android:layout_height="80dp"
android:layout_above="#id/button_invisible_center"
android:layout_alignLeft="#id/button_invisible_center"
android:background="#drawable/button_control"
android:contentDescription="#string/button_up"
/>
<ImageButton
android:id="#+id/button_right"
android:layout_width="80dp"
android:layout_height="80dp"
android:layout_toRightOf="#id/button_invisible_center"
android:layout_alignTop="#id/button_invisible_center"
android:background="#drawable/button_control"
android:contentDescription="#string/button_up"
/>
<ImageButton
android:id="#+id/button_down"
android:layout_width="80dp"
android:layout_height="80dp"
android:layout_below="#id/button_invisible_center"
android:layout_alignLeft="#id/button_invisible_center"
android:background="#drawable/button_control"
android:contentDescription="#string/button_down"
/>
</RelativeLayout>
The result is:
I re-arranged the Views in order to minimize their count and therefore increase performances, being the layout lighter.
What was the trick? wrap_content in the container, shrunk everything to the center, whyle match_parent (which worked perfectly) was just out of specifics.
So I gave the buttons fixed sizes 80*80 dp and the container 3 times 80 dp (maximum combined width and height).
The image I used is't "cut out", so it better illustrates the concept.
Enjoy!
[EDIT]
In your case, this part
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
is not needed. Just replace it with
<RelativeLayout
since it's meant to be placed inside another container.
Now I have a solution due to Golem's tip although it doesn't work with just one centered invisible item. I had to place invisible buttons left of "up", right of "up", left of "down" and in the center where one button has 100x100dp, the invisible side buttons have 80x80dp and the invisible center button has 60x60dp. If you know any better, let me know.
<RelativeLayout
android:id="#+id/controller_container"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|left" >
<ImageButton
android:id="#+id/button_invisible_top_left"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/button_control_invisible_side"
android:contentDescription="#string/button_invisible" />
<ImageButton
android:id="#+id/button_up"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="#id/button_invisible_top_left"
android:background="#drawable/button_control"
android:contentDescription="#string/button_up" />
<ImageButton
android:id="#+id/button_invisible_top_right"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="#id/button_up"
android:background="#drawable/button_control_invisible_side"
android:contentDescription="#string/button_invisible" />
<ImageButton
android:id="#+id/button_left"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#id/button_invisible_top_left"
android:background="#drawable/button_control"
android:contentDescription="#string/button_left" />
<ImageButton
android:id="#+id/button_invisible_center"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="#id/button_left"
android:layout_below="#id/button_up"
android:background="#drawable/button_control_invisible_center"
android:contentDescription="#string/button_invisible" />
<ImageButton
android:id="#+id/button_right"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="#id/button_invisible_center"
android:layout_below="#id/button_invisible_top_right"
android:background="#drawable/button_control"
android:contentDescription="#string/button_up" />
<ImageButton
android:id="#+id/button_invisible_bottom_left"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#id/button_left"
android:background="#drawable/button_control_invisible_side"
android:contentDescription="#string/button_invisible" />
<ImageButton
android:id="#+id/button_down"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="#id/button_invisible_bottom_left"
android:layout_below="#id/button_invisible_center"
android:layout_alignBottom="#id/button_invisible_bottom_left"
android:background="#drawable/button_control"
android:contentDescription="#string/button_down" />
</RelativeLayout>
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.
My layout contains 3 ImageButtons, arranged vertical in a LinearLayout.
Now I want that each of them has the same height and together fill the device's screen height.
Works fine with the attribute android:layout_weight="1". But if the image of one ImageButton is too big, it won't work (this button is higher than the others), despite setting android:scaleType="center_inside".
Any advices/tricks?
If you need any code, let me know. But there is nothin special.
If you have given weights correctly than this should work. The size of the image doesn't matter than. Just one thing to keep in mind while using weights is that attribute for which you are giving the weight(height/width) should be assigned value "0dp" in the xml, only then the weights will work correctly. Here is the example code.
<?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="vertical"
android:gravity="center"
android:weightSum="3">
<ImageView
android:id="#+id/imageView1"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:src="#drawable/drawable1"
android:layout_weight="1"
android:scaleType="centerInside"
/>
<ImageView
android:id="#+id/imageView2"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_weight="1"
android:src="#drawable/drawable2"
android:scaleType="fitXY" />
<ImageView
android:id="#+id/imageView3"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_weight="1"
android:src="#drawable/drawable3"
android:scaleType="fitXY" />
</LinearLayout>
Just use this xml and replace the drawables according to your needs. Let me know if any issues.
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.
I have two buttons which I would like to appear side-by-side horizontally, but together they fill the horizontal length of the phone. The height is wrap content, that's fine. My issue right now is that only one button is showing up (stretching across the screen).
Here is my XML code:
<LinearLayout
android:id="#+id/page_buttons"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
>
<Button
android:id="#+id/prevButton"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Previous"
/>
<Button
android:id="#+id/nextButton"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Next"
/>
Change your Buttons XML to include the layout_weight attribute:
<Button android:id="#+id/nextButton"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Next"/>
Since nobody is explaining why their solutions work, I will give it a go.
The problem lies in the layout of the buttons. The two concerned attributes are layout_width and layout_weight.
In other layout systems, when you indicate that each element of a layout has to fill the parent (layout_width="fill_parent"), they do so by distributing equally the space of the parent between them. So, each of them would have the same size.
Instead, in Android's layout system, if both elements have
layout_width="fill_parent" the first element (in your case, the
Previews button) will be stretched to fill the parent and the second
(or third, or etc.) will not have any space left to distribute, so it
will not be visible.
Now, to make it understand that you want both buttons to show, you set the layout_weight for each button. To make the buttons have the same size, set the same layout weight to both of them.
The layout_weight defines how many "parts" (or segments) of the parent each of the buttons occupy. The parent will be cut into a number of segments equal to the sum of the children's segments. If you want to make one button three times bigger then the other, you have to assign it the number of parts equal to the number of parts of the first button, multiplied by three.
So if you want your Next button to be two times bigger then the
Previews button, you can do this:
for Previews button: layout_weight=1
for Next button: layout_weight=2
In consequence, the parent will be cut in 3 parts, 2 of which will be allocated to the Next button and 1 to the Previews button.
The example taken here is for buttons and horizontal layout, but this will work just fine for any type of object and also for vertical layout parent.
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<Button
android:id="#+id/button01"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#id/entry"
android:layout_alignParentLeft="true"
android:layout_toLeftOf="#+id/space"/>
<TextView
android:id="#+id/space"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"/>
<Button
android:id="#+id/button02"
android:layout_toRightOf="#id/button01"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="#id/entry"
android:layout_alignParentRight="true"/>
</RelativeLayout>
Seems like you want two equal buttons, not wrapped content. I created a centered spacer using TextView, and relatively aligned to that. Left button to parent left and spacer, Right button to Left Button and parent right.
Parent of your Button is Linear-Layout, and you are setting Button's width as fill parent and hence it is taking the whole space. You hav two options to Implement this...
Give the fixed width for your button(eg 50dip).
Give the width as 0dp and insert one more attribute in both button "weight" and give 0.5dip for each...
The two buttons should be on a linearlayout. The linear layout should be horizontal and each button has a weight of 1. This should give you two buttons with equal size along the screen width. A sample is here
Horizontal orientation: check the 2 Buttons at the end of this xml layout
Your Requirement is
<LinearLayout
android:id="#+id/page_buttons"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
>
<Button
android:id="#+id/prevButton"
android:layout_width="0dp"
android:weight="0.5"
android:layout_height="wrap_content"
android:text="Previous"
/>
<Button
android:id="#+id/nextButton"
android:layout_width="0dp"
android:weight="0.5"
android:layout_height="wrap_content"
android:text="Next"
/>
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent" android:layout_height="wrap_content"
android:layout_centerHorizontal="true">
<TextView
android:text="#+id/SomeText"
android:id="#+id/TextView01"
android:layout_width="wrap_content" android:layout_height="wrap_content" />
<LinearLayout
android:orientation="horizontal"
android:background="#android:drawable/bottom_bar"
android:paddingLeft="4.0dip"
android:paddingTop="5.0dip"
android:paddingRight="4.0dip"
android:paddingBottom="1.0dip"
android:layout_width="fill_parent" android:layout_height="wrap_content"
android:layout_below="#+id/TextView01">
<Button
android:id="#+id/allow"
android:layout_width="0.0dip" android:layout_height="fill_parent"
android:text="Allow"
android:layout_weight="1.0" />
<Button
android:id="#+id/deny"
android:layout_width="0.0dip" android:layout_height="fill_parent"
android:text="Deny"
android:layout_weight="1.0" />
</LinearLayout>
</RelativeLayout>
I found the leading issue for people who still seems to not get what they want.
when using buttons with their conventional (out-of-the-box/default) background, it has a built in margin.
If you try changing the background manually with a single color, you can tell easily that you just need to set a separate background.
other than that when you have the weights put in, it will work.