Как изменить цвет в компонентах материалов ПРОГРАММНО на Android?

Я ищу решение для изменения цвета некоторых объектов макета Android Material Components. Как программно изменить цвет текста или границ в кнопке материала? Все функции, такие как MaterialButton.setTexColor(), не работают. То же самое для StrokeColor. Изменение должно быть сделано логически, непосредственно из кода. Нет стилей XML, цвета должны иметь возможность изменяться в реальном времени на основе значений, считываемых из базы данных.

Такие вещи не работают:

//renewSetDate is a Material Button Object
renewSetDate.strokeColor = ColorStateList.valueOf(Color.RED)
renewSetDate.setTextColor(Color.WHITE)

Это макет XML для кнопки материала.

<com.google.android.material.button.MaterialButton
                        android:id="@+id/addSubs_btnSet_date"
                        style="@style/Widget.MaterialComponents.Button.OutlinedButton"
                        android:layout_width="0dp"
                        android:layout_height="wrap_content"
                        android:layout_marginStart="15dp"
                        android:layout_marginTop="10dp"
                        android:layout_marginEnd="15dp"
                        android:text="Imposta data di rinnovo abbonamento"
                        android:textAlignment="center"
                        android:textColor="#FFFFFF"
                        app:layout_constraintEnd_toEndOf="parent"
                        app:layout_constraintHorizontal_bias="0.0"
                        app:layout_constraintStart_toStartOf="parent"
                        app:layout_constraintTop_toBottomOf="@+id/addSubs_detailTitle"
                        app:strokeColor="@color/colorAccent" />

Цвета должны считываться из шаблонов, сохраненных в базе данных. Я не могу создать стиль XML для каждого из шаблонов.

Меня очень раздражает необходимость менять цвета макета только неизвестно какими атрибутами в шаблоне XML.

Это зависимости

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
    implementation 'androidx.appcompat:appcompat:1.1.0'
    implementation 'androidx.core:core-ktx:1.1.0'
    implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
    implementation 'androidx.recyclerview:recyclerview:1.0.0'
    implementation 'androidx.cardview:cardview:1.0.0'
    implementation 'androidx.viewpager2:viewpager2:1.0.0-rc01'
    implementation 'androidx.legacy:legacy-support-v4:1.0.0'
    implementation 'com.google.android.material:material:1.0.0'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'androidx.test.ext:junit:1.1.1'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'

comment
какую версию вы используете?   -  person Gabriele Mariotti    schedule 10.11.2019
comment
Что-то вроде button.setStrokeColor(AppCompatResources.getColorStateList(this, R.color.button_selector)); и button.setTextColor(AppCompatResources.getColorStateList(this,R.color.button_selector)); работает.   -  person Gabriele Mariotti    schedule 10.11.2019
comment
Но я читал цвета из записей базы данных в виде шестнадцатеричных чисел, например #A45B01. Поэтому я не могу использовать R.color.xxxxxxxx . Я вообще не могу использовать какой-либо файл XML, стиль или цвет... все цвета будут вставлены в кнопки во время выполнения, когда я открываю действие, но читаю данные из БД.   -  person spel    schedule 10.11.2019
comment
Я думаю, проблема в библиотеках и в том, как они (разработчики Google) определили свойства материальных объектов... я думаю, что на этом этапе я буду использовать стандартные объекты для макета...   -  person spel    schedule 11.11.2019
comment
Попробуйте использовать 1.1.0-beta02 библиотеки материалов.   -  person Gabriele Mariotti    schedule 11.11.2019


Ответы (3)


Не уверен, что на это уже был дан полный ответ или нет.

У меня была такая же проблема, и в итоге я сделал:

button.strokeColor = ColorStateList.valueOf(Color.RED)
button.strokeWidth = 1

И это сработало для меня.

person jakepurple13    schedule 25.02.2020

Вы можете определить цвет следующим образом:

//From RGB
int colorRGB = Color.rgb(255,0,0);

//From HEX String
int colorHEX = Color.parseColor("#FF11AA");

Затем, чтобы определить цвет границы в MaterialButton, вы можете использовать метод setStrokeColor.

int[][] states = new int[][] {
    new int[] { android.R.attr.state_checked},  // checked
    new int[] { -android.R.attr.state_checked}  // checked false
};

int[] colors = new int[] {
    colorRGB,
    colorHEX
};

ColorStateList myColorSelector = new ColorStateList(states, colors);
button.setStrokeColor(myColorSelector);

Для цвета текста вы можете использовать аналогичный метод setTextColor. Ваш селектор должен обрабатывать следующие состояния:

<selector xmlns:android="http://schemas.android.com/apk/res/android">
  <item android:alpha="1.00" android:color="?attr/colorPrimary" android:state_checkable="true" android:state_checked="true" android:state_enabled="true"/>
  <item android:alpha="0.60" android:color="?attr/colorOnSurface" android:state_checkable="true" android:state_checked="false" android:state_enabled="true"/>
  <item android:alpha="1.00" android:color="?attr/colorPrimary" android:state_enabled="true"/>
  <item android:alpha="0.38" android:color="?attr/colorOnSurface"/>
</selector>

Что-то вроде:

int[][] states =  new int[][]{
    new int[]{android.R.attr.state_checkable,android.R.attr.state_checked,android.R.attr.state_enabled},
    new int[]{android.R.attr.state_checkable,-android.R.attr.state_checked,android.R.attr.state_enabled}, 
    new int[]{android.R.attr.state_enabled},
    new int[]{} 
};
person Gabriele Mariotti    schedule 11.11.2019

Я использую MaterilButton и Kotlin, я напишу некоторые варианты, которые вы можете использовать:

binding.buttonCancelRequest.isClickable=false      

binding.buttonCancelRequest.background.setColorFilter(Color.GRAY,PorterDuff.Mode.MULTIPLY)
    
binding.buttonCancelRequest.strokeColor= ColorStateList.valueOf(Color.GRAY)
person sana ebadi    schedule 26.05.2021