How to change color in Material Components PROGRAMMATICALLY on Android?

て烟熏妆下的殇ゞ 提交于 2020-03-03 09:06:26

问题


I'm looking for a solution to change the color of some Android Material Components layout objects. How can I change the color of text or borders in a Material Button programmatically? All functions like MaterialButton.setTexColor() do not work. Same thing for the StrokeColor. The change must be made logically, directly from code. No XML styles, colors must be able to change in live, based on values read from a database.

Things like these don't work :

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

This is the XML Layout for the Material Button

<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" />

Colors must be read from templates saved in a database. I can't create an XML Style for each of the template.

I find it really annoying to have to change the layout colors only by who knows what attributes in an XML template.

These are the dependencies

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'

回答1:


Not sure if this was completely answered yet or not.

I was having the same issue and I ended up doing:

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

And that worked for me.




回答2:


You can define the color in this way:

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

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

Then to define the border color in the MaterialButton you can use the setStrokeColor method.

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

For the text color you can use something similar with the setTextColor method. Your selector should handle these states:

<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>

Something like:

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[]{} 
};


来源:https://stackoverflow.com/questions/58790816/how-to-change-color-in-material-components-programmatically-on-android

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!