26

How can i create selector programmatically?
i have a xml selector that assigned to TabWidget as Tab indicator color

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- Non focused states -->
    <item android:state_focused="false" android:state_selected="false" android:state_pressed="false" android:drawable="@drawable/bg_tab_unselected" />
    <item android:state_focused="false" android:state_selected="true"  android:state_pressed="false" android:drawable="@drawable/bg_tab_selected" />

    <!-- Focused states -->
    <item android:state_focused="true" android:state_selected="false" android:state_pressed="false" android:drawable="@drawable/bg_tab_unselected_focused" />
    <item android:state_focused="true" android:state_selected="true"  android:state_pressed="false" android:drawable="@drawable/bg_tab_selected_focused" />

    <!-- Pressed -->
    <!--    Non focused states -->
    <item android:state_focused="false" android:state_selected="false" android:state_pressed="true" android:drawable="@drawable/bg_tab_unselected_pressed" />
    <item android:state_focused="false" android:state_selected="true"  android:state_pressed="true" android:drawable="@drawable/bg_tab_selected_pressed" />

    <!--    Focused states -->
    <item android:state_focused="true" android:state_selected="false" android:state_pressed="true" android:drawable="@drawable/bg_tab_unselected_pressed" />
    <item android:state_focused="true" android:state_selected="true"  android:state_pressed="true" android:drawable="@drawable/bg_tab_selected_pressed" />
</selector>

Is there any way to create above xml code dynamically?

KTG
  • 345
  • 1
  • 4
  • 8

2 Answers2

62

you can use it like this:

public static StateListDrawable makeSelector(int color) {
    StateListDrawable res = new StateListDrawable();
    res.setExitFadeDuration(400);
    res.setAlpha(45);
    res.addState(new int[]{android.R.attr.state_pressed}, new ColorDrawable(color));
    res.addState(new int[]{}, new ColorDrawable(Color.TRANSPARENT));
    return res;
}

and then:

view.setBackground(makeSelector(Color.RED));
Leebeedev
  • 2,126
  • 22
  • 31
  • 1
    Thanks also for additional alpha and fade out setters! – JerabekJakub Nov 06 '17 at 07:50
  • Guys, if you try it but something won't work - take your attention that an order is important (of addState() calls - first pressed and then non pressed) – Artem Nov 17 '20 at 11:37
2

You can create the StateListDrawable directly and use addState for adding the states you've defined in XML:

StateListDrawable d = new StateListDrawable();

[...]

int[] sFocusedSelected = { android.R.attr.state_focused, android.R.attr.state_selected };
Drawable dFocusedSelected = getDrawable(R.drawable.bg_tab_selected_focused);
d.addState(sFocusedSelected, dFocusedSelected);

[...]

Same rules apply like for XML:

The selection is not based on the "best match," but simply the first item that meets the minimum criteria of the state.

tynn
  • 38,113
  • 8
  • 108
  • 143