218

Ran the new Lint tool against my code. It came up with a lot of good suggestions, but this one I cannot understand.

This tag and its children can be replaced by one and a compound drawable

Issue: Checks whether the current node can be replaced by a TextView using compound drawables.

A LinearLayout which contains an ImageView and a TextView can be more efficiently handled as a compound drawable

And here is my layout

<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_centerInParent="true">

<ImageView 
    android:id="@+id/upImage"
    android:layout_width="20dp"
    android:layout_height="20dp"
    android:layout_gravity="center_vertical"
    android:scaleType="centerInside"
    android:src="@drawable/up_count_big">
</ImageView>

<TextView
    android:id="@+id/LikeCount"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginLeft="2dp"
    android:layout_marginBottom="1dp"
    android:textColor="@color/gray"
    android:textSize="16sp"
    android:layout_gravity="center_vertical">
</TextView>
</LinearLayout>

Can someone provide a concrete example of how to make a compound drawable in this case?

Community
  • 1
  • 1
Leo
  • 4,652
  • 6
  • 32
  • 42
  • 4
    fwiw that's one of the checks I normally disable, because of the false positives. Not all `TextView` / `ImageView` combos can be replaced in this way. – Richard Le Mesurier May 05 '14 at 17:39
  • @RichardLeMesurier You can use custom view if you want to define a size of image. This will make your view lighter. See my answer: http://stackoverflow.com/a/31916731/2308720 – Oleksandr Aug 10 '15 at 10:11
  • @Alex I agree in many cases, however in my experience I have often it not worth the trouble of creating a custom view to get around what I consider to be a buggy Lint check. – Richard Le Mesurier Aug 10 '15 at 17:34

4 Answers4

286

TextView comes with 4 compound drawables, one for each of left, top, right and bottom.

In your case, you do not need the LinearLayout and ImageView at all. Just add android:drawableLeft="@drawable/up_count_big" to your TextView.

See TextView#setCompoundDrawablesWithIntrinsicBounds for more info.

chiuki
  • 14,580
  • 4
  • 40
  • 38
  • 38
    not necessarily, as your link shows an example with a dynamic image. In that case it may still be easier or preferable to use an `ImageView`. The warning says 'can be replaced by', not 'should be replaced by' – David O'Meara May 27 '12 at 11:47
  • 10
    but how can I make some space between Image and Text – Hitesh Dhamshaniya Sep 26 '12 at 10:23
  • 8
    @Hitesh Dhamshaniya, using DrawablePadding property in XML or code. – Snicolas Oct 12 '12 at 11:55
  • 1
    and you can also link TextView drawables to xml states, explained here: http://2cupsoftech.wordpress.com/2012/09/18/textview-drawables-xml-state-list-resource/ – 2cupsOfTech Nov 01 '12 at 21:51
  • 3
    In my case, I moved to a LinearLayout with an inner ImageView/TextView because the android:drawableLeft didn't offer enough control -- so, what you're basically telling me is that this warning/suggestion is a lie. – BrainSlugs83 Aug 02 '13 at 19:48
  • 5
    It's not a lie, for some cases a single TextView could indeed be efficient. But in general - yes, ImageView with TextView provides much richer control. – ılǝ May 21 '14 at 06:09
  • 2
    And how do you apply tinting to the compound drawables? I need that option? – Zordid Jul 21 '15 at 11:02
  • @Puni, do you use SVG images? If yes, you should add a support. – CoolMind Oct 17 '18 at 12:57
23

if for some reason you need to add via code, you can use this:

mTextView.setCompoundDrawablesWithIntrinsicBounds(left, top, right, bottom);

where left, top, right bottom are Drawables

Javier P
  • 1,332
  • 14
  • 21
  • Require API 17 above – Puni Nov 17 '17 at 19:04
  • I don't think so, [documentation](https://developer.android.com/reference/android/widget/TextView.html) states since API 1 – Javier P Nov 17 '17 at 21:25
  • See this link [documentation](https://developer.android.com/reference/android/widget/TextView.html#setCompoundDrawablesRelativeWithIntrinsicBounds(android.graphics.drawable.Drawable, android.graphics.drawable.Drawable, android.graphics.drawable.Drawable, android.graphics.drawable.Drawable)) – Puni Nov 17 '17 at 21:36
  • yeah note the **Relative** in the method name ;) I'm not referring to this one in the answer – Javier P Nov 17 '17 at 21:48
3

To add to this - it seems important to define the width & height of the drawable as per this post:

(his code works)

Community
  • 1
  • 1
Richard Le Mesurier
  • 29,432
  • 22
  • 140
  • 255
1

You can use general compound drawable implementation, but if you need to define a size of drawable use this library:

https://github.com/a-tolstykh/textview-rich-drawable

Here is a small example of usage:

<com.tolstykh.textviewrichdrawable.TextViewRichDrawable
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Some text"
        app:compoundDrawableHeight="24dp"
        app:compoundDrawableWidth="24dp" />
Oleksandr
  • 6,226
  • 1
  • 46
  • 54