Is there a method to have the height depending from the width in my xml?
I have some Buttons in a linear layout. The button's widths depending from the device because they fill the screen horizontally. I want to have square buttons and this is my problem.
Is there one can help me?
<Button
android:id="#+id/b_0xa"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:clickable="false"
android:text="#string/b_0xa" />
To make the height of view equals to width of view, can use ConstraintLayout
app:layout_constraintDimensionRatio="1:1"
1 before : is for width
1 after : is for height
Please try below code:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<Button
android:layout_width="wrap_content"
android:layout_height="0dp"
app:layout_constraintDimensionRatio="1:1"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:text="Button"/>
</androidx.constraintlayout.widget.ConstraintLayout>
The output of above code is:
You can do it easily programatically in your Java code.
Get the width of the button dynamically [using int x = mButton.getWidth()], and then use the value returned to set the height [mButton.setHeight(x)].
P.S. : It is advisable to use LayoutParams to set the height and width of any View. So, instead of using setHeight(), you should use setLayoutParams().
mButton.setLayoutParams(new LinearLayout.LayoutParams(x, x));
You should change the values given to the android:layout_width and android:layout_height, by assigning fixed values to them
<Button
android:id="#+id/b_0xa"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_weight="1"
android:clickable="false"
android:text="#string/b_0xa" />
Assigning fixed values to them makes sure that no matter the screen size, your button stays the same, since the unit used is the dp. Make sure the values you assign are the same since you want a square.
In this scenario, I would recommend using layout_weight for your height attribute, it will then assign a proportional weight to the button that will scale on different screen sizes:
<Button
android:id="#+id/b_0xa"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight=".4"
android:clickable="false"
android:text="#string/b_0xa" />
In order for this approach to work, you must apply a weight to the height of other views in the layout. The total weight must equal 1, therefore you will have to play around with the layouts and weights to achieve the optimal design.
As I explained here if you want to do it 100% from XML you can use a PercentRelativeLayout and do the following:
<android.support.percent.PercentRelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<Button
app:layout_aspectRatio="100%"
app:layout_widthPercent="100%" />
</android.support.percent.PercentRelativeLayout>
Make sure you include the library in your app gradle file:
compile 'com.android.support:percent:XX.X.X'
You can achieve this using Constraint Layout. I am using aspect ratio attribute and an absolute value for width for the button. When my Button hits the constraints as per it's width, it'll accordingly set my height.
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
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"
xmlns:app="http://schemas.android.com/apk/res-auto">
<Button
android:id="#+id/b_0xa"
android:clickable="false"
android:text="#string/app_name"
android:layout_width="300dp"
android:layout_height="0dp"
android:src="#android:drawable/dark_header"
app:layout_constraintDimensionRatio="h,16:9"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
<Button
android:id="#+id/random"
android:layout_width="60dp"
android:layout_height="60dp"
android:layout_weight="1"
android:text="text view"
/>
Make sure You give this code or change the height and width manually
Related
I have a constraint layout and inside a linear layout that looks like a bar that is constrained to the bottom. Besides I have an item (called SwipeFlingAdapterView) that I would like to take the remaining space, meaning to start from the top, and to go all the way down until the top of the linear layout bar:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".fragments.SwipeFragment">
<LinearLayout
android:id="#+id/likeDislikeBar"
android:layout_width="match_parent"
android:layout_height="#dimen/like_dislike_height"
android:gravity="bottom"
android:orientation="horizontal"
app:layout_constraintBottom_toBottomOf="parent">
<ImageButton
android:id="#+id/dislikeButton"
android:layout_width="0dp"
android:layout_height="#dimen/like_dislike_button_height"
android:layout_weight="1"
android:background="#null"
android:src="#drawable/dislike"
android:layout_gravity="center_vertical"
android:scaleType="centerInside"/>
<ImageButton
android:id="#+id/likeButton"
android:layout_width="0dp"
android:layout_height="#dimen/like_dislike_button_height"
android:layout_weight="1"
android:background="#null"
android:src="#drawable/like"
android:layout_gravity="center_vertical"
android:scaleType="centerInside"/>
</LinearLayout>
<com.lorentzos.flingswipe.SwipeFlingAdapterView
android:id="#+id/frame"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintBottom_toTopOf="#id/likeDislikeBar"
app:rotation_degrees="15.5"/>
</androidx.constraintlayout.widget.ConstraintLayout>
The views are constrained correctly, so theoretically if I remove the height="match_parent" from the SwipeFlingAdapterView, it will take the available space. Setting its height to "match_parent" will cause it to overlay the likeDislikeBar.
Is there a simple way to achieve this? Can I do it with a constraint layout?
It is not recommended to use match_parent for any child of the ConstraintLayout as stated in the official docs and tutorial. This applies to both vertical and horizontal dimensions.
In order to make the SwipeFlingAdapterView use all available height between the constraints you need to set its android:layout_height to 0dp (to match constraints).
You need to remove
app:layout_constraintEnd_toEndOf="parent"
Also ConstraintLayout seems like an overkill for such a simple layout.
RelativeLayout is pretty sufficient here. You can set likeDislikeBar to have layout_alignParentBottom and SwipeFlingAdapterView to have layout_alignParentTop and android:layout_above="#id/likeDislikeBar" in this case.
I have an app that have an activity with 3 imagebutton and a banner ad below. Something like this...
The ImageButton layout sizes are wrap-content, and each source is a png that i've made.
Now, when i've tested in a small screen the bottom one is behind the banner ad.
I want to scale the ImageButtons dending on the size (mainly the height) of the screen.
Can anyone tell me a correct way to do it?
I have to make small png sources that fits on a small screen and then make more drawables with minimal screen width qualifiers? 320dpi and 480dpi its a really big margin, i will have to make some more folders in between.
Thank you all in advance!!!
if you dont domain Constraint Layout, maybe you can try to use a LinearLayout inside your main layout with weight to divide the screen... something like below, it may work:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:weightSum="4"
android:padding="10dp">
<ImageButton
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:src="#drawable/..."/>
<ImageButton
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:src="#drawable/..."/>
<ImageButton
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:src="#drawable/..."/>
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:src="#drawable/..."/>
</LinearLayout>
</RelativeLayout>
Just adjust it as you want... Hope this work :)
You don't need to create separate images, you can use ConstraintLayout and it will manage the sizes for you automatically. I have tested the code below and it seems to work fine. Have a go at it:
your_activity.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="match_parent"
android:layout_width="match_parent"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<ImageButton
android:id="#+id/imageButton1"
android:layout_width="wrap_content"
android:layout_height="0dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toTopOf="#id/imageButton2"
android:background="#color/white"
android:src="#drawable/image_1"/>
<ImageButton
android:id="#+id/imageButton2"
android:layout_width="wrap_content"
android:layout_height="0dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="#id/imageButton1"
app:layout_constraintBottom_toTopOf="#id/imageButton3"
android:background="#color/white"
android:src="#drawable/image_2"/>
<ImageButton
android:id="#+id/imageButton3"
android:layout_width="wrap_content"
android:layout_height="0dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="#id/imageButton2"
app:layout_constraintBottom_toTopOf="#id/bannerContainer"
android:background="#color/white"
android:src="#drawable/image_3"/>
<!-- Whatever container your banner is in -->
<RelativeLayout
android:id="#+id/bannerContainer"
android:layout_width="match_parent"
android:layout_height="80dp"
android:background="#000"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
Note:
I have added the background colors just to test out. The main point to focus on for you is that the height of the ImageButton is 0dp for all, and the constraints manage the height automatically.
The good part of ConstraintLayout is that you don't need to specify different weights like you would in a LinearLayout, so you can have images of different heights and it will work just fine.
If you are using css you can use the property unit vh (viewport height). The measurement is a percentage of the viewport/screen height. For example height: 10vh; width: auto; will render the element height as 10% of the screen height, without distorting your png. If you use this measurement for the four elements shown, they will all appear on the screen at the same time if their values add up to 100.
https://www.sitepoint.com/css-viewport-units-quick-start/
I am trying to understand how Android's ConstraintLayout works, and in order to do so, I want to create a layout that would take 1/4 of the view height with a left/right/bottom margin of 25dp, and in this layout, put two views, the first one would take 70% of its height and the second one the remaining 30%.
To sum up this:
I tried this so far:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout android:layout_height="match_parent"
android:layout_width="match_parent"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<android.support.constraint.ConstraintLayout
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginEnd="24dp"
android:layout_marginStart="24dp"
android:layout_marginBottom="25dp"
app:layout_constraintDimensionRatio="w,1:4"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintBottom_toBottomOf="parent" >
<View
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintDimensionRatio="w,7:10"
android:background="#color/red" />
<View
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintDimensionRatio="w,3:10"
android:background="#color/light_blue" />
</android.support.constraint.ConstraintLayout>
</android.support.constraint.ConstraintLayout>
But instead I'm only having the bottom view (that should take 30% of the height) taking the whole layout space. What am I doing wrong?
Thanks for your help.
What you have:
Property app:layout_constraintDimensionRatio is "self dependable" , that is it only adjust width-to-height ratio of itself.
What you require:
If you're using ConstrainLayout 1.1.x you can use property app:layout_constraintHeight_percent , which takes values from 0 to 1.
Also, you might have to adjust constrains of these views top and bottom to be relative to each other.
It is possible to add a ImageView inside a XML LinearLayout with the 15% of the width of the screen of width and also exactly the same height?
I tried it with this dialog code which is being displayed when a user clicks on a marker on the map:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/custom_info_bubble"
android:orientation="vertical">
.
. [some more content here]
.
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:weightSum="100">
<ImageView
android:id="#+id/favorite"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginRight="5dp"
android:adjustViewBounds="true"
android:layout_gravity="center_horizontal"
android:layout_weight="15"
android:layout_marginEnd="5dp" />
</LinearLayout>
</LinearLayout>
But is has two problems:
Problem 1: android:layout_weight="15" makes 15% of the width of the dialog, not of the screen, and that's a huge problem, because the dialog has some times more or less width depending of its content.
Problem 2: the width is 15% ok but the height is the real height of the image. I don't know how to make it to have exactly the same height than it's width. Its a square image, so I tried make it respecting its proportions putting wrap_content on height and adjustViewBounds=true but it didn't work.
Problem 3: the ImageView is not being centered, is aligned to the left. I need it centered.
How can this be achieved with XML instead of Java code?
This is how I do in XML, by this way my image height is equal to 15% of the screen width :
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="#+id/favorite"
android:layout_width="0dp"
android:layout_height="0dp"
android:adjustViewBounds="true"
android:src="#drawable/ic_launcher_background"
app:layout_constraintDimensionRatio="H, 100:15"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent" />
</android.support.constraint.ConstraintLayout>
Look at the result :
No, AFAIK it's not possible via XML.
But you can easy achieve it programmatically:
if you want you can just create a custom view with the required parameters and just put it into XML.
Look into https://stackoverflow.com/a/20427215/1159507 for reference.
How to make it take up 15% of the screen width:
//Get 15% of screen width:
myWidth = getWindow().getDecorView().getWidth() * .15;
myImageView = findViewById(R.id.favorite);
myView.setWidth(myWidth);
//Height should be the same as the width
myView.setHeight(myWidth);
The following two lines say that the width of the image view will be determined in percents and it'll be relative to the parent.
app:layout_constraintWidth_default="percent"
app:layout_constraintWidth_percent="0.15"
The following line means that the width and height of the imageview will be the same. The ratio is width:height.
app:layout_constraintDimensionRatio="1:1"
With Guidelines you get the ability to set % widths/heights in views under constraint layout. The following says that the guideline is 20% of its parent. You can then place views with constraint set to this Guidelines.
app:layout_constraintGuide_percent="0.2"
Below is a full example xml you can try out.
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<android.support.constraint.Guideline
android:id="#+id/guideline"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_percent="0.2" />
<ImageView
android:id="#+id/imageView5"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="#423dfe"
app:layout_constraintWidth_default="percent"
app:layout_constraintWidth_percent="0.15"
app:layout_constraintDimensionRatio="1:1"
android:layout_marginBottom="8dp"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
app:layout_constraintBottom_toTopOf="#+id/guideline" />
</android.support.constraint.ConstraintLayout>
You can only do this with the beta version of ConstraintLayout:
compile 'com.android.support.constraint:constraint-layout:1.1.0-beta1'
Related SO posts: 1 2 3
Further reading: Constraint Layout
Is it possible to dynamically create Layouts which be 50% width, so 3rd one to be under first one? I have tried with android:layout_weight=".5", but it doesn't working.
EDIT: No proper answer by far
You can do the follwoing with a LinearLayout:
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:weightSum="2"
android:gravity="left"
android:orientation="horizontal">
<TextView
android:layout_weight="1"
android:layout_width="0dip"
android:layout_height="wrap_content"
android:text="Takes up half the width" />
</LinearLayout>
By setting the weightSum on the parent, you're saying that the weights of the children should equal that amount. By setting the single child's weight to half of that, it'll take up half the space. Make sure to set the width of the child to 0 so it knows to use the weight value to calculate its space relative to its parent.
You could use the Percent Support Library:
add the library
compile 'com.android.support:percent:23.3.0'
Example:
<android.support.percent.PercentRelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
app:layout_widthPercent="50%"
app:layout_heightPercent="50%"
app:layout_marginTopPercent="25%"
app:layout_marginLeftPercent="25%"/>
</android.support.percent.PercentFrameLayout>