When I see on the XML layout file in the android studio I can see the padding is there but on the device, I can not see it. I am not adding padding programmatically on that button. I only set the background of the button programmatically.
In Android Studio
In Device
Here is my button code
<Button
android:id="#+id/LoadBtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:minHeight="0dp"
android:minWidth="0dp"
android:layout_marginTop="16dp"
android:background="#color/colorAccent"
android:foreground="?android:attr/selectableItemBackground"
android:text=" LOAD MAP "
android:textAlignment="viewStart"
android:textColor="#android:color/white"
android:textSize="30sp"
android:textStyle="bold"
android:paddingStart="7dp"
android:paddingEnd="7dp"
android:paddingTop="10dp"
android:paddingBottom="10dp"
app:layout_constraintStart_toStartOf="#+id/fileTypeRadioGroup"
app:layout_constraintTop_toBottomOf="#+id/fileTypeRadioGroup" />
Here is the java code that I am doing with that button.
loadBtn = findViewById(R.id.LoadBtn);
loadBtn.setEnabled(false);
loadBtn.setBackground(ContextCompat.getDrawable(getApplicationContext(), R.drawable.disabled_button_background));
loadBtn.setEnabled(true);
loadBtn.setBackground(ContextCompat.getDrawable(getApplicationContext(), R.color.colorAccent));
Try setting the text of the button to dp, instead of sp. Sp will scale the text based on the device's preferences, while dp will not. It looks based on the example that they are just differently sized texts.
It could be that inside your android studio you are watching a display of one phone but when you run it you actually run it on another phone with a totally different screen resolution.
So you may see it as you would like to in your preview but this screen preview and your phone screen are different, and because different phones got different screen sizes and pixel densities you are seeing this differently.
When using a fixed size (7dp) value for padding for example for larger screens you will need to use more than 7dp if you want it to look like the preview or less if you are using a smaller screen than what you have in your android studio preview.
A good solution could be to use sdp library:
From the library github page:
An android lib that provides a new size unit - sdp (scalable dp). This size unit scales with the screen size. It can help Android developers with supporting multiple screens.
How to use:
You will first need to implement this:
dependencies {
implementation 'com.intuit.sdp:sdp-android:1.0.6'
}
And now on your layout file simply add the wanted padding:
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:text="Text"
android:textSize="30sp"
android:textStyle="bold"
android:padding="#dimen/_18sdp"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
</Button>
And it will look like this:
Something extra
If you want to make your texts scale in size as well according to the screen size (as I just showed for dp) you can use
AutosizingTextViews or you can even use
ssp library
Related
I finished the java codes and function of my little project. At the end, i check to support a big amount of android devices according to their size. But it was fail.
While researching, i understand that i should use sp for textsizes and dp for all other parameters. The layout -xml- is existed via sp and dp. But it is not like that i expected.
I create a new project for example.
My xml; (in ConstraintLayout)
<TextView
android:id="#+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="72dp"
android:text="Hello World!"
android:textSize="105sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.502"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="144dp"
android:text="Check"
android:textSize="160sp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="#+id/textView" />
For 1080 x 1920 xxhdpi; Click here to see layout
For 1440 x 2960 hdpi(samsung galaxy s8 ) Click here to see layout
In galaxy s8, elements are really small and there is problem in view. I guess that i misunderstand a basic concept. Can you clear up my mind please?
You're missing something here: when you set android:layout_marginTop="72dp" the 72dp wil lbe interpreted the same way in both layout files.
A solution is to use dimens instead of values directly in your xml file.
Watch here : https://stackoverflow.com/a/32861248/5778152
Hope it helps.
You have to be careful at screen size and pixel density.
The best way to treat all screen sizes is to use ConstraintLayout, or weightSum in LinearLayout (but it slows UI performance). This will help you keep the same position of the elements on all screens.
Pixel density is harder to treat. For text size, for example, I find it useful to use different dimens files.
Right click values folder and click Values resource file, put the name dimens and then choose Density from the left. There you can select what density you like to treat. In each file you make you can make a text size with the same name, like this:
<dimen name="normal_text_size">15sp</dimen>
and each time you set a text size use this tag. This way depending on the phone density the appropriate text size will be automatically selected.
You can read about ConstraintLayout here
Read about screen size here
And about pixel density here
I have a screen on which I need to display a number of images inside a horizontal LinearLayout.
I designed it for an xhdpi. I set the sizes of each ImageView to 100dp, and on an emulator (xhdpi 768x1280 4.7" screen) it looks something like
this while on a tablet emulator (xhdpi 1534x2048 9" screen) it looks like this.
In the latter, the images aren't scaled properly to look like it does on the smaller screen.
Is there a way to make it look the same on both screen sizes?
to make your layout adjust on different screen you need to design it to be responsive. Yes like what G.Dator said, you can use weight attribute. Here's the example :
<LinearLayout
android:layout_height="200dp"
android:layout_width="match_parent"
android:orientation="horizontal">
<ImageView
android:layout_width="0dp"
android:layout_height="200dp"
android:layout_weight="25"/>
<ImageView
android:layout_width="0dp"
android:layout_height="200dp"
android:layout_weight="25"/>
<ImageView
android:layout_width="0dp"
android:layout_height="200dp"
android:layout_weight="25"/>
<ImageView
android:layout_width="0dp"
android:layout_height="200dp"
android:layout_weight="25"/>
</LinearLayout>
Please let me know if you have further question.
Actually, the image is the same size in 2 devices. The problem is the difference between your dp width of your phone (384dp) and your tablet (767dp). There're few ways to resolve it:
using multiple layout files for sw360 and sw720. You can check this Google Guide
Using the same weight for all your ImageView with adjustViewBound=true to keep your image ratios.
Using code to set your ImageView size programmatically.
In addition to implementing a responsive layout structure (like what #Bhimbim mentioned), there is a library (https://github.com/intuit/sdp) which can be useful when you want to code once and use it on multiple different devices, it offers you sdp unit instead of dp which helps your view to scale better.
Example:
layout_width="#dimen/_30sdp"
layout_height="#dimen/_30sdp"
(Sorry i couldn't comment as i have registered recently).
In my Android app I have the following layout:
<android.support.v7.widget.CardView
android:id="#+id/difficultyCardView"
app:layout_widthPercent="60%"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
app:cardUseCompatPadding="true"
android:layout_centerHorizontal="true"
android:layout_above="#+id/noHighScoresCardView">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/yellow"
android:orientation="vertical">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginBottom="10dp"
android:src="#drawable/pushpin" />
<TextView
android:id="#+id/diffNameTv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginBottom="12dp"
android:maxLines="1"
android:singleLine="true"
android:text="FÁCIL"
android:textSize="20sp"
android:textStyle="bold" />
</LinearLayout>
</android.support.v7.widget.CardView>
In my Nexus 5, setting the text size to 20sp as shown above, makes text occupy, approximately, 75% of CardView's width. The problem is that, when I test this on a smaller phone, it adds ellipsis to the text.
What I want to achieve is that, on EVERY screen size and resolution, the text will exactly occupy 75% of the card with.
So, how can I solve this problem, creating multiple scale folders (ldpi, mdpi, ...) and adjusting font size in each of them, calculating it via code as a percentage, or any other solution?
Thank you.
Get the card width on the specific device and multiply by .75, then set the text size to that value.
if you want textview to take 75% of cardview with textsize 20sp then text will spilt into multiple lines.
android:maxLines="1"
android:singleLine="true"
remove these properties there is no need and allow textview for multiline
Will the text always be the same? If so the solution is pretty simple.
int ratio = 15;
int width = difficultyCardView.getWidth();
diffNameTv.setTextSize(width/ratio);
Adjust the ratio till the size is where you want it, then the text will be the same relative size compared to the card no matter what the screen size is.
What you want to do is to create a responsive layout. To do so create additional layout folders in the res directory. Add the pixel density name at the end of the folder name, separating the text "layout" and the density using a dash (e.g. layout-hdpi, layout-mhdpi, layout-xhdpi etc.) Within these folders, create the layout you want for each density. You can then resize the textview to 75% of each of the different screen sizes based on the pixel density. Therefore if 20sp fills 75% of the hdpi layout then you might need to increase the text size for a the mhdpi to fill 75% of the card.
Android will automatically select the correct layout for a particular device based on the screen size.
Why does text of x size not fit within a TextView of that same size?
For example, this TextView:
<TextView
android:id="#+id/time"
android:layout_width="wrap_content"
android:layout_height="60dp"
android:padding="0dp"
android:textSize="60dp"
android:text="12:22" />
Renders like this on my Nexus 5:
I'm not asking for how to scale the text (like many other questions). I am just trying to understand why android does this, and a formula for enough buffer to avoid clipping.
It should help to disable the implicit font padding
<TextView
android:id="#+id/time"
android:layout_width="wrap_content"
android:layout_height="60dp"
android:drawablePadding="0dp"
android:padding="0dp"
android:textSize="60dp"
android:includeFontPadding="false"
android:text="12:22" />
I think this tool may be helpful for you. It allows you to translate various UI units, like SP to DP. Seems like you should be able to figure out the correct conversions for various screen densities.
The unit sp can be changed in settings by the user to be different sizes. If you need the text to fit inside a bounding box you should use dp as the unit.
See Android sp vs dp
I have a fragment that takes up the whole screen, with Buttons and a SeekBar which scale to fit it, as well as fixed size TextViews. I use linear horizontal and vertical layouts with weights to achieve this.
The problem is I can't get the button text large enough without it making the buttons expand in size. For some reason, any text size greater than about 35sp makes the button expand, no matter how big the button is. This screen shot shows the button sizes have plenty of space for the text:
Ideally I would like the "<" and ">" characters to fill the buttons. (I was going to programmatically change the font size according to the button size, e.g. for different screen sizes) but haven't tried since I can't even get the static layout to work.
Edit: I would like to avoid images, since if I had 15 buttons, and 8 buckets, that would be 120 images I need!
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/VerticalLinearLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingBottom="0dp"
android:paddingLeft="0dp"
android:paddingRight="0dp"
android:paddingTop="0dp" >
<!-- ........ -->
<TextView
android:id="#+id/trackTextView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="2" >
<Button
android:id="#+id/trackPreviousButton"
style="android:buttonBarStyle"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:text="#string/button_track_previous"
android:textSize="35sp" />
<Button
android:id="#+id/trackNextButton"
style="android:buttonBarStyle"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:text="#string/button_track_next"
android:textSize="35sp" />
</LinearLayout>
<SeekBar
android:id="#+id/seekBar"
style="#style/tallerBarStyle"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />
<!-- ........ -->
</LinearLayout>
I have tried adding the following line to Buttons, but it only makes a small difference, if any:
android:padding="0dp"
Advice on getting the font height to fill the buttons without padding is my primary question. (But if the problem of dynamically sizing the text to fill the buttons for different screen sizes can be solved at the same time, that would be brilliant).
Edit: it turns out that using larger font sizes affects the effect of weighting for the height of the linear layouts, which is why there seemed to be padding - larger font size increased the button size, not because of the padding (which was 0) but because of the weighting
Button is not the right widget for your purpose. Use an ImageButton (or even an ImageView) instead.
I was going to programmatically change the font size according to the button size, e.g. for different screen sizes
Your current approach will land you in a lot of problems regarding proper sizing of your UI components. Given the plethora of android devices out there, screen size is just one aspect of the problem. You will also be dealing with varying screen densities. Best approach would be to put size/density buckets (drawable-mdpi/hdpi/xhdpi) to use. Help android in working for you.
Use drawables to indicate next and previous. If you're worried about the drawables being too small for tablet screens, create appropriate drawable resources/folders:
// Phones - 4 to 7 in
drawable-ldpi
drawable-mdpi
drawable-hdpi
drawable-xhdpi
drawable-xxhdpi
// Tablets - 7 to 10 in
drawable-large-mdpi
drawable-large-hdpi
// Tablets - 10 in
drawable-xlarge-mdpi
This list may not be exhaustive. Consider doing some research before finalizing your size/density buckets.
Output:
# drawable size 32dp:
# drawable size 64dp
Now it becomes quite straightforward - finalize drawable size by visual inspection on a phone, on a 7 inch tablet, and on a 10 inch tablet. Then use density scales to create and store appropriately sized drawable in the folders I mentioned above. Let android deal with what bucket to pick from.
The problem is by default buttons include a minHeight attribute. I had the same problem and solved it with just a single line of code in my XML file:
android:minHeight="0dp"
There is a quick and easy solution to your problem!
Auto-sizing text in Android is fiendishly difficult in my experience, especially when padding is involved. I would advise that instead of using an angle bracket character, you use a drawable - there are plenty of arrow icons available online - and an ImageButton. For example:
<ImageButton
android:id="#+id/trackNextButton"
style="android:buttonBarStyle"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:src="#drawable/left_arrow"
android:scaleType="fitXY"
android:padding="0dp"
android:textSize="35sp" />
By using different ScaleTypes you can alter the stretching of the image. Even better, the screen sizes problem is solved because you can add different drawables for different densities.
Use minWidth="0" or "1" to reduce the horizontal padding on a text Button.