?android:attr/selectableItemBackground с другим существующим фоном

У меня есть 9 патчей, установленных в качестве фона моего макета. Однако я все еще хочу обеспечить обратную связь при касании, используя атрибут selectableItemBackground.

Я пробовал использовать <layer-list> с патчем 9 и selectableItemBackground в качестве android:drawable второго <item>, однако это не сработало.

Я также мог бы попробовать создать селектор и наложить градиент, который можно использовать для Android, для selectableItemBackground в list_selector_background_pressed.xml с помощью <layer-list>. Но в 4.4 KitKat выбранный цвет фона на самом деле серый, а не синий в JellyBeans, поэтому я не могу его жестко закодировать :(

Должен быть более простой способ, верно, ребята? Д:


person Jason Hu    schedule 28.11.2013    source источник


Ответы (1)


Я пытался использовать a с 9patch и selectableItemBackground в качестве android:drawable второго , однако это не сработало.

Да, атрибут drawable в списке слоев (или списке состояний) не принимает значение attr. Вы увидите Resource.NotFoundException. Взгляд на исходный код LayerDrawable (или StateListDrawable) объясняет, почему: предполагается, что значение, которое вы предоставляете, является идентификатором drawable.

Но вы можете получить рисунок для темы и платформы для атрибута в коде:

// 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();

Теперь вы можете создать 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);

Вам также необходимо установить атрибут yourLayoutContainer's clickable:

android:clickable="true"
person Vikram    schedule 02.12.2013
comment
Это выглядит интересно. Попытаюсь. - person Jason Hu; 03.12.2013
comment
@JasonHu Извините, я не прочитал ваш комментарий полностью, был на связи. Если у вас есть вопрос, пожалуйста. - person Vikram; 03.12.2013
comment
Удивительно. Работает как шарм. Сначала я думал, что мне придется сделать селектор для выбранных состояний (9patch только по умолчанию и LayerDrawable при выборе). Но кажется, что рисуемый объект, который вы получаете из selectableItemBackground, на самом деле является самим селектором. Спасибо. - person Jason Hu; 03.12.2013
comment
Одна вещь, которую следует отметить для людей, которые могут попытаться сделать это. Обязательно сохраните отступы в представлении, прежде чем динамически устанавливать фон с помощью 9patch, и установите его обратно после того, как фон был установлен. По-видимому, 9-й патч заставит вас потерять отступы в представлении. stackoverflow.com/questions/10095196 / - person Jason Hu; 03.12.2013
comment
@JasonHu Точно. И поскольку мы создаем LayerDrawable --› изменения состояния передаются обоим объектам рисования. selectableItemBackground прозрачен, когда не имеет состояния. И именно поэтому это работает. - person Vikram; 03.12.2013
comment
Я дам вам награду после того, как 1-й день блокировки исчезнет. - person Jason Hu; 03.12.2013
comment
@JasonHu Интересная информация. Я не знал о проблеме заполнения. Спасибо! - person Vikram; 03.12.2013
comment
Викрам и @JasonHu, вы оба сэкономили мне кучу часов. Спасибо! - person jenzz; 30.01.2015