Question

I'm trying to simplify some graphics from requiring a 9-patch for each density, to just using an XML drawable. It's a fairly simple graphic:

9-patch drawable

2 Segments:

  • 8dp wide for both segments
  • Top segment is 2dp tall
  • Bottom segment fills the view
  • Right side is filled with transparency

Giving this result when set as a background image:

9-patch as list item example

It seems like this should be fairly simple to recreate as an XML drawable, and would avoid creating 5 different 9-patch graphics. However, I've looked into layer-list drawables, inset drawables, clip drawables -- they all seem to require that you know the size of the view beforehand (e.g. to keep it 2dp for an inset, you'd need to set insetRight to the width of the view - 2dp). I also tried using the shape tag's size tag, but that doesn't keep a fixed size, just a fixed proportion (so for taller views it will scale proportionally).

Am I overlooking something simple, or is this something I'd have to resort to checking programatically after layout?

Was it helpful?

Solution

This is not possible. This is the best solution I found. Only xml, no coding, no bitmaps, no additional views )

<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
    <shape
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:shape="rectangle">

        <solid
            android:color="#ff0000" />
    </shape>
</item>
<item
    android:top="4dp">
    <shape
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:shape="rectangle">

        <solid
            android:color="#00ff00" />
    </shape>
</item>

<item
    android:left="10dp">
    <shape
        android:shape="rectangle">
        <solid
            android:color="#FFFFFF" />
    </shape>
</item> 
</layer-list>

enter image description here

Via code you can make your own drawble type with desired behavior. Xml drawable very limited. IMHO my suggestion is the closest to what you demanded.

OTHER TIPS

I think the answer by @Leonidos is very close to what I'm proposing, except I'm using the drawable as a separate view instead of the background for the entire list detail layout. This allows it to be a fixed width and to let the item text have its own background. Let me know if I'm not understanding your constraints.

The following file is "res/drawable/list_left_border"

<?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="#e76e63" />
        </shape>
    </item>
    <item android:top="2dp">
        <shape android:shape="rectangle" >
            <solid android:color="#ffc257" />
        </shape>
    </item>

</layer-list>

Then on the layout for the list item in "res/layout/list_item.xml"

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal"
    tools:context=".MainActivity" >

    <View
        android:background="@drawable/list_left_border"
        android:layout_width="8dp"
        android:layout_height="match_parent" />

    <TextView
        android:id="@+id/listItemText"
        android:textSize="15sp"
        android:padding="10dp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

</LinearLayout>

Here's the image. The background is pink to show that the list item is transparent.

enter image description here

I'm going to go one further and suggest a slight reworking of AndroidGuy's answer, which itself includes Leonidos' answer.

Same drawable XML, different list item XML as follows:

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

<FrameLayout
    android:layout_width="match_parent"
    android:layout_height="100sp">

    <ImageView
        android:layout_width="8dp"
        android:layout_height="match_parent"
        android:src="@drawable/list_left_border" />

    <TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center_vertical"
        android:text="Item Text"
        android:textSize="22sp" >
    </TextView>
</FrameLayout>

The FrameLayout gives the original background behaviour, rather than separation into a new view.

I've shown this below, with backgrounds to demonstrate:

illustration

This doesn't really deserve the points though.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top