Search code examples
androidnine-patchandroid-selector

?android:attr/selectableItemBackground with another existing background


I have a 9patch set as the background of my layout. However I still want to provide touch feedback by using the selectableItemBackground attr.

I've tried using a <layer-list> with the 9patch and selectableItemBackground as the android:drawable of the second <item>, however that did not work.

I could also try making a selector and overlay the gradient drawable android uses for selectableItemBackground in list_selector_background_pressed.xml with a <layer-list>. But in 4.4 KitKat the selected background color is actually gray instead of blue in JellyBeans, so I can't really hardcode it :(

There has to be an easier way, right guys? D:


Solution

  • I've tried using a with the 9patch and selectableItemBackground as the android:drawable of the second , however that did not work.

    Yes, drawable attribute in a layer-list (or state-list) does not accept an attr value. You would see a Resource.NotFoundException. A look at LayerDrawable's (or StateListDrawable's) source code explains why: the value that you provide is assumed to be a drawable's id.

    But, you can retrieve a theme and platform-specific drawable for an attribute in code:

    // Attribute array
    int[] attrs = new int[] { android.R.attr.selectableItemBackground };
    
    TypedArray a = getTheme().obtainStyledAttributes(attrs);
    
    // Drawable held by attribute 'selectableItemBackground' is at index '0'        
    Drawable d = a.getDrawable(0);
    
    a.recycle();
    

    Now, you can create a LayerDrawable:

    LayerDrawable ld = new LayerDrawable(new Drawable[] {
    
                           // Nine Path Drawable
                           getResources().getDrawable(R.drawable.Your_Nine_Path), 
    
                           // Drawable from attribute  
                           d });
    
    // Set the background to 'ld'
    yourLayoutContainer.setBackground(ld);
    

    You'll also need to set yourLayoutContainer's clickable attribute:

    android:clickable="true"