7

On Android, I would like to create a button that contains some other Views. For example, something like this:

+---------------------------+
| Hello world!    +-------+ |
|                 | image | |
| Some more info  +-------+ |
+---------------------------+

But I'd like it to be more flexible than this specific example. Ideally, the button would simply be able to contain a ViewGroup, so that I could implement its layout in a separate XML file. However, because Button extends View, but not ViewGroup, this doesn't seem possible.

Is there any way to achieve this using standard Android components, or do I have to resort to writing a custom button class?


As requested, some example XML that does the trick:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    android:focusable="true"
    android:clickable="true"
    android:background="@android:drawable/btn_default">
    <TextView
        android:id="@+id/name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textColor="@android:color/primary_text_light"/>
    <TextView
        android:id="@+id/additional_line_1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textColor="@android:color/primary_text_light"/>
    <TextView
        android:id="@+id/additional_line_2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textColor="@android:color/primary_text_light"/>
</LinearLayout>

I had to set the colour on the TextViews explicitly, otherwise they would be nearly unreadable (they're white by default). I dug up the identifier from the SDK: .../platforms/android-7/data/res/values/public.xml. Strangely, primary_text_light gives black text, whereas primary_text_dark results in white...

Thomas
  • 174,939
  • 50
  • 355
  • 478
  • 25.3k rep on SO and you're asking this question? I'll give you a hint...write your own class....or did I miss the point? – Squonk Dec 12 '10 at 13:00
  • 7
    Really? Does the reputation imply that a fellow can never get stuck someplace and ask for some tips? – Siddharth Lele Dec 12 '10 at 13:05
  • I'd also say, create your own custom View(Group) class. – Mathias Conradt Dec 12 '10 at 13:10
  • @Siddharth Lele and @Thomas: Sorry if that sounded harsh and unhelpful and I apologise but yes, it seems to me that as SO is a programmer's Q&A site, then someone who has built a significant reputation answering questions can surely perform a simple search on the Android Developers pages which would bring up things like this... http://developer.android.com/guide/topics/ui/custom-components.html and this http://developer.android.com/guide/topics/ui/custom-components.html#compound – Squonk Dec 13 '10 at 02:20
  • 4
    @MisterSquonk: Of course I searched. The idea of creating a custom class did occur to me; read the last sentence of my post again if you're not convinced. I was only wondering if such a seemingly simple thing could not be done in a more simple way (WPF would let me do it!). As it turns out, there is, but neither of the links you post have pointed me towards it. So I'm still glad I asked :) – Thomas Dec 13 '10 at 08:27
  • I want my text to be white and the button/Layout background dark, how do I do this since the btn_default is white or really light grey. Found out by using btn_default_holo_dark, wasn't available in my version of API so I copied and pasted the g pngs and 1 xml file into my project from the samples in SDK. – JPM Apr 16 '12 at 22:58

3 Answers3

4

Create the layout of the desired button, and set it's android:background to @android:drawable/btn_default. Make the outermost View that contains the rest clickable and focusable and you're done.

ognian
  • 11,451
  • 4
  • 35
  • 33
  • interesting... @Thomas: If this works, please share a short sample XML, I am very interested :) – WarrenFaith Dec 12 '10 at 14:01
  • 2
    @WarrenFaith: That kind of things works fine. I have used `android:background="@android:drawable/edit_text"` set for a `Button` to make it look like an `EditText`. (Avoided date validations using a Date Picker :)) – Macarse Dec 12 '10 at 14:04
  • @WarrenFaith: I put the XML into the question. – Thomas Dec 13 '10 at 08:46
  • Works like a charm, including all state changes that I was briefly worried about! Thanks! – Thomas Dec 13 '10 at 08:47
1

I am not sure, but have you tried the ImageButton class? I guess you should be able to set the image to the right side and you should be able to add a label with new lines, too.

[update] I missed the "more flexible" part. If you want to have a more flexible one, I guess you need to create an own implementation with an own OnTouchListener to handle all possible states and detecting clicks.

WarrenFaith
  • 57,492
  • 25
  • 134
  • 150
1

I wouldn't create a class for that. It's just a RelativeLayout with two TextViews and a ImageView.

As you might know, a ViewGroup extends View and a View can have click listeners. So you need to create the layout and set a click listener to it.

The issue here is how you handle the states, you can try using @android:drawable/btn_default as a background as @ognian said.

Macarse
  • 91,829
  • 44
  • 175
  • 230