2

I got a layout design which states sizes in px which I save in the dimen resource file.

Is there an automatic way to somehow let Android convert the px unit automatically to sp for strings or dp for other sizes, without the need for me to call a method every single time which converts the unit?

If not, how can I define specific sizes in the layout's xml if all the units are in px?

Abdul Waheed
  • 4,540
  • 6
  • 35
  • 58
CodeMonkey
  • 11,196
  • 30
  • 112
  • 203
  • 4
    Is there any reason you can't just define them as `dp` and `sp` in your `dimens` file, rather than as `px`? – PPartisan Jul 17 '17 at 11:15
  • 3
    No there isn't. That is not how Android works. I recommend your designer revisit his/her designs to specify DP instead, and to be aware that there are different screen sizes on Android devices. Otherwise your product is going to be in for a world of pain in the future. – Richard Le Mesurier Jul 17 '17 at 11:15
  • @PPartisan I can define them as I like, but I only know the px value which can change with each density (the sp or dp value can change). I need something to let me define values in the layout's xml and convert it for me automatically – CodeMonkey Jul 17 '17 at 11:17

3 Answers3

1

if you read here you will understand that what you want isn't the best solution.

I would suggest to you to change everything px to dp and then put those on the files

most probably your app will work for more than one density screens so the pixel way is very bad choice

Designing layouts for dp

When designing layouts for the screen, calculate an element’s measurements in dp:

dp = (width in pixels * 160) / density

For example, a 32 x 32 px icon with a screen density of 320 equals 16 x 16 dp.

Update

unfortunately what you want cannot be happen. You will have to generate different dp values for different density screens. Read also how to support diffent screen densities from the official documentation

gmetax
  • 3,853
  • 2
  • 31
  • 45
  • but how can I change the px to dp if the dp value changes with each density? – CodeMonkey Jul 17 '17 at 11:18
  • but again.. all I know is for example the value 16px. I can't just decide its for example 18dp since it the value for a specific density only. I need something that will let me define the size in the xml and convert it for me automatically according to the current device's density. – CodeMonkey Jul 17 '17 at 11:21
  • i have updated my answer, unfortunately the auto part it isn't possible – gmetax Jul 17 '17 at 11:24
  • Is there a way to create a dimen-ldpi, dimen-hdpi etc like you do for the drawables? – CodeMonkey Jul 17 '17 at 11:45
  • you can use folders like values-large , values-large-port and then you have inside there the dimens.xml file, check also here https://developer.android.com/training/multiscreen/screensizes.html – gmetax Jul 17 '17 at 11:50
  • in the past it was with hdpi, mdpi, xhdpi and it was very difficult to make it work well for all dimensions – gmetax Jul 17 '17 at 11:51
  • 2
    `the dp value changes with each density?` It actually **does not**. the **px** value will change, not the dp one. That's how dps work. In past, present and future. – Phantômaxx Jul 17 '17 at 11:51
  • @Rotwang you could say that the dp changes based on the density if you say that the dp getting calculated like that (width in pixels * 160) / density – gmetax Jul 17 '17 at 11:53
  • 2
    No. 50 dps wil always be 50 dps. At any density. What changes it the *equivalent **px*** they are translated to. **50 dp** @ 160 dpi is **50 px**. but it is **100 px** at 320 dpi and **200 px** at 640 dpi – Phantômaxx Jul 17 '17 at 11:55
  • yes you are correct that the dp isn't "changing" but I think that you are missing the point. Yes you have to calculate the dp based on your density that you want and then those dps will translate to px that will have different value on different screen. – gmetax Jul 17 '17 at 11:57
  • I don't get you. You have to work with the highest density you want to support. Do the relative proportions and get the dps you need. use these dps in all the other densities. You might want to make scaled versions (in px) of your resources. Then keep in mind the scale factors and you're good to go. – Phantômaxx Jul 17 '17 at 11:59
  • there isn't any reason to continue that. I know what you mean and I understand very well how it is working. – gmetax Jul 17 '17 at 12:02
1

You need to call a function all the time, or you need to create custom views that extends the views and override the size/textSize function that converts them automatically

class CustomTextView : AppCompatTextView {

    override fun setTextSize(size: Float) {
        // do the convertion here
        super.setTextSize(size)
    }

    override fun setTextSize(unit: Int, size: Float) {
        // or here
        super.setTextSize(unit, size)
    }
}

and you will probably need to extend every view that has been using dimens if you don't want to write a function all the time.

Arutha
  • 494
  • 5
  • 14
-1

Unfortunately, px to dp conversion can not be done by the system automatically for you.

however, you can define several values folders for various screen sizes and define different dimensions(in dp) for each of them.

refer this question for more details:

How to define dimens.xml for every different screen size in android?

Conversion from PX to dp or sp is something you have to do yourself.

and to conclude, you should not be doing this as most of the time values defined in dp and sp suits to most of the screen sizes, so try that first.

Rahul Tiwari
  • 6,851
  • 3
  • 49
  • 78
  • Thats the closest thing to getting the correct value based on the current density I saw. I need to calculate the dp values in advance that's true, but as long as Android is selecting the correct resource file for me, thats good enough. – CodeMonkey Jul 17 '17 at 12:47