androidandroid-jetpack-composestandards

Android Jetpack Compose dimensions coding standards


For the old XML layouts I always use the dimen.xml file to define almost all dimensions, paddings, margins, etc.

While learning Jetpack Compose I find that all repositories, examples, etc., hardcode all dimensions related values directly into the compose code, even though I am aware that there is the possibility to use the dimensionResource method to read it from an xml file.

What is the recommended way for Compose regarding this? to keep using dimen XML files, or to hardcode it into the actual compose code?


Solution

  • [Google's official documentation][1] mentions that resource dimensions can be used with compose using dimensionResource() like below:

    Box(
        modifier = Modifier
            .padding(
                horizontal = dimensionResource(id = R.dimen.padding_horizontal),
                vertical = dimensionResource(id = R.dimen.padding_vertical),
             ),
    )
    

    I also prefer using them. I've seen a post on Medium where the writer suggested using kotlin classes and objects to store dimens and then using some formulas to calculate which class must be used based on the screen dimension. Still, personally, I don't suggest going that road. The dimens are already sufficient enough, both in stability and ease of use.

    [1]: https://developer.android.com/jetpack/compose/resources#dimensions

    The more that I've been working with compsoe, the more I realized using dimension resources is not an efficient and comprehensive way of dealing with dimens, compared how great it was with XML. So yeah, I think it's better to search in the web and find a better solution. One thing that I've started doing but I'm not yet sure it would work every where, is that I use an extension method to scale the dimens based on the screen size. I used this list enter image description here for getting the scales. It is for drawables, but It had worked well for me till now:

    @Stable
    @Composable
    fun Dp.scaled(): Dp {
        return this * getSizeScale()
    }
    
    @Stable
    @Composable
    fun TextUnit.scaled(): TextUnit {
        return this * getSizeScale()
    }
    
    @Composable
    private fun getSizeScale(): Float {
        val windowInfoClass = currentWindowAdaptiveInfo().windowSizeClass
        if (windowInfoClass.windowHeightSizeClass == WindowHeightSizeClass.MEDIUM) {
            return 0.75F
        } 
        // I haven't added support for other devices yet, but you can.
        return 1F
    }