38

I want to set margins by percentage.. I have 4 imageviews in a linearlayout and want to set default left,right,top,bottom margins that keep same percentage for each screen size.

is it possible ?

here is a demo what i want.. enter image description here

And here is what i've tried and doesn't work

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_weight="1"
        android:weightSum="10" >

        <Thumbnail
            android:id="@+id/thumb1"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="4" />

        <Thumbnail
            android:id="@+id/thumb2"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="4" />

    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_weight="1"
        android:weightSum="10" >

         <Thumbnail
             android:id="@+id/thumb3"
             android:layout_width="0dp"
             android:layout_height="match_parent"
             android:layout_weight="4" >
         </Thumbnail>

        <Thumbnail
            android:id="@+id/thumb4"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="4" />

    </LinearLayout>

</LinearLayout>

Thanks for your help

Eugene Brusov
  • 17,146
  • 6
  • 52
  • 68
dracula
  • 4,413
  • 6
  • 26
  • 31

4 Answers4

28

You can have invisible Views in your LinearLayouts as spacers and use the layout_weight mechanism to assign them relative size.

Example:

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_weight="1">

    <Thumbnail
        android:id="@+id/thumb1"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="4" />

    <View
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:layout_weight="2"
        android:visibility="invisible"/>

    <Thumbnail
        android:id="@+id/thumb2"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="4" />

</LinearLayout>
laalto
  • 150,114
  • 66
  • 286
  • 303
  • 1
    logical if there isn't any other way :) but not sure with memory usage because i need so much invisible views – dracula Apr 24 '13 at 20:28
  • 3
    There is a `` view for that. I don't think there will be any performance/memory penalty for using invisible `View` instead, but really not sure - `View.java` is huge, skimmed it for just several minutes. – Alexander Malakhov Aug 04 '14 at 09:38
  • 1
    @AlexanderMalakhov `Space` was added in API level 14 so it's not as useful. Its naming makes the purpose more evident though. – laalto Aug 04 '14 at 09:42
  • 2
    there is `android.support.v7.widget.Space`. Though that could be an extra dependency. – Alexander Malakhov Aug 05 '14 at 03:48
  • android.support.v7.widget.Space is deprecated. Use android.support.v4.widget.Space instead. – Galya Aug 05 '15 at 07:23
22

Added on Aug 1 2017:

The two layouts from this answer are now deprecated but there is a description provided there on how to get the same functionality with ConstraintLayout. Thanks to dpg for pointing this out.

If you plan on using the percentages with resources, this answer might be useful.


Old answer:

There is now a better way that came out with support library version 23.0.0 (about time, right?). You can now use PercentFrameLayout or PercentRelativeLayout. They both have the following attributes:

  • layout_widthPercent
  • layout_heightPercent
  • layout_marginPercent
  • layout_marginLeftPercent
  • layout_marginTopPercent
  • layout_marginRightPercent
  • layout_marginBottomPercent
  • layout_marginStartPercent
  • layout_marginEndPercent

You can also take a look at PercentLayoutHelper.PercentLayoutParams

neits
  • 1,963
  • 1
  • 18
  • 32
  • Is this only for Android 6 ? – Iraklis Bekiaris Dec 05 '15 at 21:59
  • 1
    The percent layouts are in the Percent Support Library, which means that they are not only for Android 6. – neits Dec 07 '15 at 11:04
  • 3
    The new better way has become deprecated now. For both Layouts on the links: `This class was deprecated in API level 26.0.0-beta1. consider using ConstraintLayout and associated layouts instead.` – Peter Aug 01 '17 at 03:17
  • 1
    Perhaps you mean ConstraintLayout in "...how to get the same functionality with CoordinatorLayout..."? – Eugene Brusov Nov 06 '17 at 10:10
16

You can set margins with percentage using ConstraintLayout's Guidelines.

Say you want to define following percentage values for your layout:

Requested percentage values

Then you simply add following guidelines to your layout:

Layout Editor

<?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/imageView1"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:scaleType="centerCrop"
        app:srcCompat="@drawable/ic_launcher_background"
        app:layout_constraintTop_toTopOf="@+id/horGuideline1"
        app:layout_constraintStart_toStartOf="@+id/verGuideline1"
        app:layout_constraintEnd_toStartOf="@+id/verGuideline2"
        app:layout_constraintBottom_toTopOf="@+id/horGuideline2" />

    <ImageView
        android:id="@+id/imageView2"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:scaleType="centerCrop"
        app:srcCompat="@drawable/ic_launcher_background"
        app:layout_constraintTop_toTopOf="@+id/horGuideline1"
        app:layout_constraintStart_toStartOf="@+id/verGuideline3"
        app:layout_constraintEnd_toStartOf="@+id/verGuideline4"
        app:layout_constraintBottom_toTopOf="@+id/horGuideline2" />

    <ImageView
        android:id="@+id/imageView3"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:scaleType="centerCrop"
        app:srcCompat="@drawable/ic_launcher_background"
        app:layout_constraintTop_toTopOf="@+id/horGuideline3"
        app:layout_constraintStart_toStartOf="@+id/verGuideline1"
        app:layout_constraintEnd_toStartOf="@+id/verGuideline2"
        app:layout_constraintBottom_toTopOf="@+id/horGuideline4" />

    <ImageView
        android:id="@+id/imageView4"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:scaleType="centerCrop"
        app:srcCompat="@drawable/ic_launcher_background"
        app:layout_constraintTop_toTopOf="@+id/horGuideline3"
        app:layout_constraintStart_toStartOf="@+id/verGuideline3"
        app:layout_constraintEnd_toStartOf="@+id/verGuideline4"
        app:layout_constraintBottom_toTopOf="@+id/horGuideline4" />

    <android.support.constraint.Guideline
        android:id="@+id/verGuideline1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        app:layout_constraintGuide_percent="0.05" />

    <android.support.constraint.Guideline
        android:id="@+id/verGuideline2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        app:layout_constraintGuide_percent="0.35" />

    <android.support.constraint.Guideline
        android:id="@+id/verGuideline3"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        app:layout_constraintGuide_percent="0.65" />

    <android.support.constraint.Guideline
        android:id="@+id/verGuideline4"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        app:layout_constraintGuide_percent="0.95" />

    <android.support.constraint.Guideline
        android:id="@+id/horGuideline1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        app:layout_constraintGuide_percent="0.12" />

    <android.support.constraint.Guideline
        android:id="@+id/horGuideline2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        app:layout_constraintGuide_percent="0.47" />

    <android.support.constraint.Guideline
        android:id="@+id/horGuideline3"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        app:layout_constraintGuide_percent="0.53" />

    <android.support.constraint.Guideline
        android:id="@+id/horGuideline4"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        app:layout_constraintGuide_percent="0.88" />

</android.support.constraint.ConstraintLayout>

As a result your layout looks something like this:

Result view

Eugene Brusov
  • 17,146
  • 6
  • 52
  • 68
  • Cool ! I didn't know about this. Also, `android.support.constraint.Guideline` has ben replaced with `androidx.constraintlayout.widget.Guideline`. – Aruman Nov 10 '21 at 17:20
0

Looking at your image here is what you could possibly do, use a relative layout and put the linear layout inside it. you can also use the weightSum if you want to make the image views to fit properly.

<RelativeLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_marginLeft="5dp"
    android:layout_marginLeft="5dp" >

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:orientation="vertical" >

        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />

        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />
    </LinearLayout>

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:orientation="vertical" >

        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />

        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />
    </LinearLayout>

</RelativeLayout>
Eugene Brusov
  • 17,146
  • 6
  • 52
  • 68
deepdroid
  • 633
  • 5
  • 26
  • giving exact margin is not good way for multiple screens. that's why i'm looking for a percentege solution – dracula Apr 24 '13 at 20:24
  • Setting a left and right margins for your relative layout will set same margins on all screens since these values are in dp. – deepdroid Apr 24 '13 at 20:31
  • but dp values effects different for each density. – dracula Apr 24 '13 at 20:38
  • These are density-independent pixels, in my experience using dp units in layouts has caused no issues in terms of margins on different screens. – deepdroid Apr 24 '13 at 20:45