Android, настройка фонового цвета кнопки теряет эффект пульсации
После добавления цвета к кнопке андроида, он теряет эффект пульсации, который заставляет пользователя чувствовать, что есть отзывчивый клик. Как это исправить? Я искал множество решений, но я не мог найти определенную, которая не была двусмысленной.
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ClockInOutFragment">
<AnalogClock
android:id="@+id/clock"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:layout_toRightOf="@+id/date_and_time"/>
<RelativeLayout
android:id="@+id/date_and_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="10dp">
<TextView
android:id="@+id/time_digits"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="12:10"
android:textSize="45sp"/>
<TextView
android:id="@+id/am_pm"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="@+id/time_digits"
android:layout_toRightOf="@+id/time_digits"
android:paddingLeft="3dp"
android:text="PM"
android:textSize="20sp"/>
<TextView
android:id="@+id/date"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/time_digits"
android:text="Mon, July 11"
android:textSize="22sp"/>
</RelativeLayout>
<!--Clock in and out buttons-->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:orientation="horizontal">
<Button
android:id="@+id/textView3"
android:layout_width="0dp"
android:layout_height="56dp"
android:layout_weight="1"
android:background="#4CAF50"
android:gravity="center"
android:text="Clock In"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textColor="#FFFFFF"/>
<!--Divider between the clock in and out button-->
<View
android:layout_width="1dp"
android:layout_height="match_parent"
android:background="#B6B6B6"/>
<Button
android:id="@+id/textView4"
android:layout_width="0dp"
android:layout_height="56dp"
android:layout_weight="1"
android:background="#FF5252"
android:gravity="center"
android:text="Clock Out"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textColor="#FFFFFF"/>
</LinearLayout>
</RelativeLayout>
Ответы
Ответ 1
Вы можете добавить эффект пульсации и цвет фона с добавлением дополнительной ряби:
ваш макет:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="@+id/button_connect"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dip"
android:fontFamily="sans-serif"
android:text="Connect"
android:background="@drawable/ripple"
android:textColor="#FFFFFF"
android:textSize="18sp" />
</LinearLayout>
ripple.xml(здесь вы можете добавить цвет фона в дополнение к эффекту пульсации):
<?xml version="1.0" encoding="utf-8"?>
<!-- in drawable folder-->
<ripple
xmlns:android="http://schemas.android.com/apk/res/android"
android:color="?android:colorControlHighlight">
<item android:id="@android:id/mask">
<shape android:shape="rectangle">
<solid android:color="?android:colorAccent" />
</shape>
</item>
<item>
<shape android:shape="rectangle">
<!-- put your background color here-->
<solid android:color="@color/default_color" />
</shape>
</item>
</ripple>
Ответ 2
Очень простой и прямой способ сделать это - установить атрибут ?attr/selectableItemBackground
в android:foreground
вашей кнопки. Следующее xml отлично действует и работает
<Button
android:id="@+id/btn"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@android:color/white"
android:foreground="?attr/selectableItemBackground"/>
Ответ 3
Не меняйте фон кнопки. Измените тему.
<style name="ButtonGray">
<item name="colorButtonNormal">@color/gray</item>
</style>
и в вашем XML файле
<Button
android:id="@+id/accept_button"
android:layout_height="wrap_content"
android:layout_width="0dp"
android:layout_weight="1"
android:text="@string/button_accept_group"
android:theme="@style/ButtonGray"/>
Или вы можете добавить его в свою основную тему приложения
<style name="AppTheme"
parent="Theme.AppCompat.Light.NoActionBar">
<item name="colorButtonNormal">@color/primary_color</item>
</style>
И не нужно менять фон кнопки.
Если вам нужен полностью настраиваемый фон, вам нужно создать свой селектор. И вы можете установить эффект пульсации.
Ответ 4
Просто используйте:
android:backgroundTint="#4CAF50"
Вместо:
android:background="#4CAF50"
Не забудьте изменить Button
на android.support.v7.widget.AppCompatButton
Ответ 5
На самом деле, вы можете использовать <layer-list>
для рисования, чтобы комбинировать эффект ряби с любым другим рисованием. Это универсальное решение также для pre-lolipop: я тестировал его во многих конфигурациях.
Единственная проблема заключается в том, что pre-lolipop аварийно завершает работу, когда ?selectableItemBackground
SelectableItemBackground появляется внутри <layer-list>
, поэтому мы должны создать LayerDrawable программно.
Очень быстрое простое решение выглядит так:
Укажите для вашего просмотра
android:background="?selectableItemBackground"
Затем в любом месте кода создайте mySpecialDrawable и сделайте свое дело:
Drawable[] layers = {mySpecialDrawable, getBackground()};
setBackgroundDrawable(new LayerDrawable(layers).mutate());
Пожалуйста, обратите внимание, что .mutate()
для LayeredDrawable здесь очень важен!
Более сложное решение может быть полезно, когда у вас уже есть пользовательский вид, и вы предпочитаете скорее расширять его функциональность и совместимость, чем добавлять дополнительный пустой FrameLayout в качестве родителя.
Внутри attrs.xml поместите:
<resources>
<declare-styleable name="MyView">
<attr name="selectableBackground" format="reference"/>
<attr name="backgroundDrawable" format="reference"/>
</declare-styleable>
</resources>
затем внутри вашего класса-потомка:
private Drawable selectableBackground;
private Drawable backgroundDrawable;
public MyView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
try {
TypedArray attributeArray;
attributeArray = context.obtainStyledAttributes(attrs, R.styleable.MyView);
int id = attributeArray.getResourceId(R.styleable.MyView_selectableBackground, -1);
if (id != -1) {
selectableBackground = ResourcesCompat.getDrawable(getResources(), id, context.getTheme());
}
id = attributeArray.getResourceId(R.styleable.MyView_backgroundDrawable, -1);
if (id != -1) {
backgroundDrawable = ResourcesCompat.getDrawable(getResources(), id, context.getTheme());
}
constructBackground();
attributeArray.recycle();
} catch (Exception e) {
Log.e(this.toString(), "Attributes initialization error", e);
throw e;
}
}
void setSelectableBackground(Drawable drawable) {
selectableBackground = drawable;
constructBackground();
}
void setDrawable(Drawable drawable) {
backgroundDrawable = drawable;
constructBackground();
}
private void constructBackground() {
if (selectableBackground != null) {
if (backgroundDrawable != null) {
Drawable[] layers = {backgroundDrawable, selectableBackground};
setBackgroundDrawable(new LayerDrawable(layers).mutate()); // Both, using layers
} else setBackgroundDrawable(selectableBackground); // Selectable only
} else setBackgroundDrawable(backgroundDrawable); // Background only or null
}
Я предпочитаю этот подход, потому что у него нет таких проблем, как атрибут android:foreground
который является 23+, или дополнительные издержки, связанные с включением интерактивных представлений внутри FrameLayout.
Ответ 6
Вы должны использовать стили
<style parent="Theme.AppCompat.Light" name="RaisedButtonGreen">
<item name="colorButtonNormal">@color/green</item>
<item name="colorControlHighlight">@color/greenLight</item>
<item name="android:textColor">@android:color/white</item>
</style>
это оптимальное решение
<Button
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="Button with ripple for style"
android:theme="@style/RaisedButtonGreen"/>