Joakim Sjöstedt
Joakim Sjöstedt

Reputation: 948

How do I set constraints and programmatically increase image in proportion to text size?

This is perhaps a bit hard to explain, so I included a picture to show you what I mean.

I have three images in Android Studio. They should all be alined to match and the middle part should expand as the text on top of the graphic expands (the middle height should equal the text height I suppose). Have been sitting with this for awhile now but don't get anywhere.

  1. Do I add code in xml? Something like android:layout_height="@id/textView"

  2. Is it better to do relative constraints in xml or constraints in UI?

  3. In xml, how do I do relative constraints to other children? I know code like android:layout_alignParentTop, android:layout_alignChildTop, but how do I set distance to children?

enter image description here

Upvotes: 0

Views: 96

Answers (1)

AGDownie
AGDownie

Reputation: 638

If I read this correctly, you want the centre image and text view to adjust height based on the height of the text. The simplest way of doing that would be using your middle image as a stretchable background to the text view and similarly for the header and footer views, preferably using 9-patch PNG images.

Solution 1: Using 9-patch PNG images

Here is an example XML with 9-patches to show how this works.

N.B. The example contains two layouts, each enclosing a single TextView with header and footer views. The first TextView has a single line of text, the second has two lines.

<LinearLayout
    android:layout_width="320dp"
    android:layout_height="wrap_content"
    android:orientation="vertical" >

    <View
        android:layout_width="match_parent"
        android:layout_height="10dp"
        android:background="@drawable/top" />

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:textSize="32sp"
        android:padding="5dp"
        android:gravity="center_horizontal"
        android:text="A line of text" 
        android:background="@drawable/middle" />
    <View
        android:layout_width="match_parent"
        android:layout_height="10dp"
        android:background="@drawable/bottom" />
</LinearLayout>

<Space
    android:layout_width="match_parent"
    android:layout_height="10dp" />

<LinearLayout
    android:layout_width="320dp"
    android:layout_height="wrap_content"
    android:orientation="vertical" >

    <View
        android:layout_width="match_parent"
        android:layout_height="10dp"
        android:background="@drawable/top" />

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:textSize="32sp"
        android:padding="5dp"
        android:gravity="center_horizontal"
        android:text="A line of text\nAnother line of text" 
        android:background="@drawable/middle" />
    <View
        android:layout_width="match_parent"
        android:layout_height="10dp"
        android:background="@drawable/bottom" />
</LinearLayout>

Nine-Patches

top.9.png:

Top

middle.9.png:

Middle

bottom.9.png:

Bottom

Example output

Example output

Solution 2: All XML

Alternatively, you could do it all in XML using <shape> and <layer-list> drawables instead of the 9-patch PNG images. Here is a modified version of the above to work with XML drawables.

This example shows rounded corners on the border as an added bonus, but beware it can be tricky to draw complex compound shapes using XML as there are only a small number of primitive shapes you can use.

Note also that this version relies on the addition of dimension resources to ensure everything matches up.

res/values/dimens.xml

<resources xmlns:android="http://schemas.android.com/apk/res/android" >
    <dimen name="layout_width">320dp</dimen>
    <dimen name="header_height">15dp</dimen>
    <dimen name="header_inset_height">5dp</dimen>
    <dimen name="inset">5dp</dimen>
    <dimen name="inset_width">310dp</dimen>
    <dimen name="footer_height">15dp</dimen>
    <dimen name="corner_radius">10dp</dimen>
    <dimen name="inset_radius">5dp</dimen>
</resources> 

res/drawable-nodpi/header.xml

<?xml version="1.0" encoding="utf-8"?>
<layer-list
    xmlns:android="http://schemas.android.com/apk/res/android" >

    <item>
        <shape android:shape="rectangle">
            <solid android:color="#ffff00ff" />
            <corners 
                android:radius="@dimen/corner_radius" 
                android:bottomLeftRadius="0dp" 
                android:bottomRightRadius="0dp" />
            <size 
                android:width="@dimen/layout_width" 
                android:height="@dimen/header_height" />
        </shape>
    </item>
    <item
        android:top="@dimen/inset"
        android:left="@dimen/inset"
        android:right="@dimen/inset">
        <shape android:shape="rectangle">
            <solid android:color="#ffffff00" />
            <corners 
                android:radius="@dimen/inset_radius" 
                android:bottomLeftRadius="0dp" 
                android:bottomRightRadius="0dp" />
            <size 
                android:width="@dimen/inset_width" 
                android:height="@dimen/header_inset_height" />            
        </shape>        
    </item>

</layer-list>

res/drawable-nodpi/body.xml

<?xml version="1.0" encoding="utf-8"?>
<layer-list
    xmlns:android="http://schemas.android.com/apk/res/android" >

    <item>
        <shape android:shape="rectangle">
            <solid android:color="#ffff00ff" />
            <size android:width="@dimen/layout_width"/>
        </shape>
    </item>
    <item
        android:left="@dimen/inset"
        android:right="@dimen/inset">
        <shape android:shape="rectangle">
            <solid android:color="#ffffff00" />
            <size android:width="@dimen/inset_width" />            
        </shape>        
    </item>

</layer-list>

res/drawable-nodpi/footer.xml

<?xml version="1.0" encoding="utf-8"?>
<layer-list
    xmlns:android="http://schemas.android.com/apk/res/android" >
    <item>
        <shape android:shape="rectangle">
            <solid android:color="#ffff00ff" />
            <corners 
                android:radius="@dimen/corner_radius"
                android:topLeftRadius="0dp"
                android:topRightRadius="0dp" />
            <size 
                android:width="@dimen/layout_width" 
                android:height="@dimen/footer_height" />
        </shape>
    </item>
    <item
        android:bottom="@dimen/inset"
        android:left="@dimen/inset"
        android:right="@dimen/inset">
        <shape android:shape="rectangle">
            <solid android:color="#ffffff00" />
            <corners 
                android:radius="@dimen/inset_radius"
                android:topLeftRadius="0dp"
                android:topRightRadius="0dp" />
            <size 
                android:width="@dimen/inset_width" 
                android:height="@dimen/header_inset_height" />            
        </shape>        
    </item>

</layer-list>

res/layout/activity_main.xml:

<LinearLayout 
    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:gravity="center"
    android:fitsSystemWindows="true"
    android:orientation="vertical">

    <LinearLayout
        android:layout_width="@dimen/layout_width"
        android:layout_height="wrap_content"
        android:orientation="vertical" >

        <View
            android:layout_width="match_parent"
            android:layout_height="@dimen/header_height"
            android:background="@drawable/header" />

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_centerInParent="true"
            android:textSize="32sp"
            android:padding="5dp"
            android:gravity="center_horizontal"
            android:text="A line of text" 
            android:background="@drawable/body" />
        <View
            android:layout_width="match_parent"
            android:layout_height="@dimen/footer_height"
            android:background="@drawable/footer" />
    </LinearLayout>

    <Space
        android:layout_width="match_parent"
        android:layout_height="10dp" />

    <LinearLayout
        android:layout_width="@dimen/layout_width"
        android:layout_height="wrap_content"
        android:orientation="vertical" >

        <View
            android:layout_width="match_parent"
            android:layout_height="@dimen/header_height"
            android:background="@drawable/header" />

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_centerInParent="true"
            android:textSize="32sp"
            android:padding="5dp"
            android:gravity="center_horizontal"
            android:text="A line of text\nAnother line of text" 
            android:background="@drawable/body" />
        <View
            android:layout_width="match_parent"
            android:layout_height="@dimen/footer_height"
            android:background="@drawable/footer" />
    </LinearLayout>

</LinearLayout>

Example output:

XML example output

Upvotes: 1

Related Questions