Как я могу изменить цвет ряби при использовании? Attr/selectableItemBackground в качестве фона?
Я видел некоторые вопросы SO, и они дали несколько возможных методов для достижения того, что я хочу. Например:
использование
colorControlHighlight
атрибут в styles.xml.Вот мой файл styles-v21.xml:
<style name="SelectableItemBackground"> <item name="android:colorControlHighlight">#5677FC</item> <item name="android:background">?attr/selectableItemBackground</item> </style>
И мой виджет:
<TextView android:id="@+id/tv_take_photo_as_bt" android:layout_width="280dp" android:layout_height="48dp" android:text="@string/act_take_photo" style="@style/SelectableItemBackground"/>
И это не работает. Я тоже пытался добавить
parent="Theme.AppCompat
в стиль "SelectableItemBackground" или измените наcolorControlHighlight(no android: prefix)"
или измените на?android:attr/selectableItemBackground
ни то, ни другое не полезно.использование
backgroundTint
атрибут в макете.Итак, я добавляю
android:backgroundTint="#5677FC"
к моемуTextView
, Все еще бесполезно. Затем я попытался изменитьandroid:backgroundTintMode
вsrc_in
а такжеsrc_atop
и они никогда не имеют значения.
Итак, как я могу изменить цвет пульсации, когда я использую ?attr/selectableItemBackground
в качестве фона. Я сосредоточен только на Lollipop и выше. Заранее спасибо!
10 ответов
Наконец я нахожу решение: вместо того, чтобы использовать android:colorControlHighlight
прямо в теме SelectableItemBackground
Я должен написать другой стиль:
<style name="SelectableItemTheme">
<item name="colorControlHighlight">@color/ripple_color</item>
</style>
Затем:
<style name="SelectableItemBackground">
<item name="android:theme">@style/SelectableItemTheme</item>
<item name="android:background">?attr/selectableItemBackground</item>
</style>
Наконец добавить style="@style/SelectableItemBackground"
в View
в layout.xml.
ОБНОВЛЕНО 2016/8/26 После выпуска N я обнаружил, что иногда мы не можем использовать этот метод для установки цвета ряби для некоторого вида View
(например, CardView
). Теперь я настоятельно рекомендую разработчикам, использующим RippleDrawable
, который также может быть объявлен в XML. Вот пример:
Я хочу показать волновой эффект, когда пользователь касается / щелкает CardView
выше API21, и, конечно, должен быть другой вид обратной связи перед Lollipop. Поэтому я должен написать:
<android.support.v7.widget.CardView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:foreground="@drawable/selectable_item_background"/>
а также selectable_item_background
в drawable
папка:
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="false" android:drawable="@android:color/transparent" />
<item android:drawable="@color/color_clicked" />
</selector>
selectable_item_background
в drawable-v21
папка:
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/ripple_black" />
</selector>
наконец, ripple_black
в drawable
(или же drawable-v21
) папка:
<ripple
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:color="@color/color_clicked"
tools:ignore="NewApi" /> <!--you can remove this line if it's in v21 folder-->
Вот и все. Для других просмотров, возможно, вам следует использовать android:background="@drawable/selectable_item_background"
, Не забудьте установить OnClickListener
, OnTouchListener
или что-то подобное для них, иначе рябь не покажет.
Пульсация на устройствах pre и Lollipop+
Харран и Лютинг правы. Принятый ответ - не лучший способ. Позвольте мне показать в коде, как изменить цвет пульсации для версий до Lollipop и выше
Ваша AppTheme должна наследоваться от любой темы AppCompat и содержать атрибут colorControlHighlight (без префикса "android:")
<!-- Application theme. --> <style name="AppTheme" parent="@style/Theme.AppCompat.Light.NoActionBar"> <item name="colorControlHighlight">#40ffffff</item> </style>
Ваше представление должно содержать clickable="true" (или должен иметь прослушиватель кликов, установленный программно), а фон должен быть "? Attr/selectableItemBackgroundBorderless" или "? Attr/selectableItemBackground":
<LinearLayout ... android:clickable="true" android:background="?attr/selectableItemBackgroundBorderless"/>
Обратите внимание: если ваш родительский вид имеет белый фон, вы не увидите эффект ряби, так как он белый. Изменить значение colorControlHighlight для другого цвета
Кроме того, если вы хотите использовать разные цвета пульсации для разных действий, вы можете установить индивидуальную тему для каждого действия в файле манифеста, например:
<activity
android:name="com.myapp.GalleryActivity"
android:theme="@style/RedRippleTheme"
/>
Разные цвета ряби для разных фрагментов в одной и той же деятельности?
Вы можете изменить атрибуты темы деятельности для каждого фрагмента во время выполнения. Просто перезапишите их, прежде чем фрагмент будет заполнен вашим собственным стилем и примените к текущей теме:
в values /styles.xml
<style name="colorControlHighlight_blue">
<item name="colorControlHighlight">@color/main_blue_alpha26</item>
</style>
Тогда в вашем фрагменте до инфляции в onCreateView()
:
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
getContext().getTheme().applyStyle(R.style.colorControlHighlight_blue, true); //blue ripple color
View view = inflater.inflate(R.layout.my_fragment_layout, container, false);
return view;
}
Этот стиль будет работать только для этого фрагмента
Различный цвет пульсации для разных видов? (Леденец +)
Вы можете изменить цвет пульсации для каждого вида отдельно, используя colorControlHighlight
атрибут, он не работает, если вы примените их к представлению напрямую:
<TextView
...
colorControlHighlight="#40ffffff"/> <!-- DOESN'T WORK -->
Вы должны применить это как тему:
<TextView
...
android:theme="@style/colorControlHighlight_blue"/>
PS Кроме того, иногда этот подход помогает, если у вас есть неизвестные проблемы с пульсацией, и вы не можете понять это. В моем случае я использовал стороннюю скользящую библиотеку, которая испортила волновые эффекты для всего макета и явно добавила эту тему ко всем интерактивным представлениям, разработанным для меня.
Он показывает эффект ряби с цветом API +21 и простой серый фон при печати для API -21. Добавьте этот стиль:
<style name="AppTheme.MyRipple">
<item name="colorControlHighlight">@color/your_color</item>
<item name="android:background">?selectableItemBackgroundBorderless</item>
</style>
И установите его на вид:
<Button
...
android:theme="@style/AppTheme.MyRipple" />
Используйте следующие шаги:
1. Make changes to button view in your layout.xml
2. Add new styles in styles.xml
your_layout.xml
<Button
android:id="@+id/setup_submit_button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text="@string/action_sign_in"
android:textStyle="bold"
android:background="@color/colorPrimary"
android:textColor="@color/white"
style="@style/SelectableItemBackground"
android:foreground="?android:attr/selectableItemBackground"/>
-Атрибут style вызывает стиль, который мы создали.
Атрибут -Foreground вызывает выбираемый атрибут по умолчанию для andorid.
styles.xml
<style name="SelectableItemTheme">
<item name="colorControlHighlight">@color/white</item>
</style>
<style name="SelectableItemBackground">
<item name="android:theme">@style/SelectableItemTheme</item>
<item name="android:background">?attr/selectableItemBackground</item>
</style>
Принятый ответ неверен.
Правильный способ использования - это то, что Liuting упомянул в комментарии. использование colorControlHighlight
вместо android:colorControlHighlight
для изменения по умолчанию colorControlHighlight
от AppCompat
* Пожалуйста, обратитесь к http://android-developers.blogspot.co.uk/2014/10/appcompat-v21-material-design-for-pre.html в разделе Темы *
Используйте атрибут переднего плана в качестве selectableItemBackground и атрибут фона в качестве нужного цвета.
android:foreground="?attr/selectableItemBackground"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:background="@color/white"
Этот код работает для меня, чтобы создать рябь:
public static void setRippleDrawable(View view, int normalColor, int touchColor) {
try {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
RippleDrawable rippleDrawable = new RippleDrawable(ColorStateList.valueOf(touchColor), view.getBackground(), null);
view.setBackground(rippleDrawable);
} else {
StateListDrawable stateListDrawable = new StateListDrawable();
stateListDrawable.addState(new int[]{android.R.attr.state_pressed}, new ColorDrawable(touchColor));
stateListDrawable.addState(new int[]{android.R.attr.state_focused}, new ColorDrawable(touchColor));
stateListDrawable.addState(new int[]{}, new ColorDrawable(normalColor));
view.setBackground(stateListDrawable);
}
} catch (Exception e) {
Log.e(LOG_TAG, "" + e);
}
}
Я не нашел никакого способа изменить атрибут selectableItemBackground. Вот почему я сделал это, как указано выше.
В темной черной (или любой другой) программе попробуйте использовать, как показано ниже ripple_effect.xml
в drawable
папку и добавить код, как
<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
android:color="#f5f5f5">
<item android:id="@android:id/mask">
<shape android:shape="rectangle">
<solid android:color="#f5f5f5" />
</shape>
</item>
</ripple>
затем установите фон для любого вида как Linear layout, Button, TextView
и т.п.
<TextView
android:id="@+id/tvApply"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/ripple_effect"
android:clickable="true"
android:text="APPLY"
android:textColor="#FFFFFF"
android:gravity="center"
android:textSize="@dimen/_8sdp"
android:padding="@dimen/_8sdp"
android:focusable="true" />
Если вы хотите сделать это программно, это решение, над которым я работал, должно работать, по крайней мере, в большинстве случаев:
fun View.setBackgroundTintColor(@ColorInt color: Int) {
val background = background
if (background is RippleDrawable) {
val newBackground = background.mutate() as RippleDrawable
if (color != 0)
newBackground.setColor(ColorStateList.valueOf(color))
this.background = newBackground
} else {
if (color == 0)
ViewCompat.setBackgroundTintList(this, null)
else
ViewCompat.setBackgroundTintList(this, ColorStateList.valueOf(color))
}
}
Использование:
yourView.setBackgroundTintColor(0xffff0000.toInt())
И для сброса в нормальное состояние:
yourView.setBackgroundTintColor(0)
Как видите, вы должны знать, что, к сожалению, его использование может привести к тому, что у представления появится новый фон.
В вашем наборе XML-файлов:
<View
android:id="@+id/click_view"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_gravity="center"
android:background="?attr/selectableItemBackgroundBorderless" <!-- Set ripple this way -->
android:contentDescription="@null" />
И в вашем коде измените его цвет:
// Take borderless ripple
val ripple = clickView.background as? RippleDrawable
// Change color here
ripple?.setColor(ColorStateList.valueOf(Color.RED))
Не знаю, как это работает с Lollipop.