material-components / material-components/material-components-android
[TabLayout] Default tab text appearance is incorrectly setting attributes for text appearance instead of style
Open
@imhappi is already working on this.
Since Jan 4, 2024.
bug
Widget: Tab
- Dominant language
- Java
- Stars
- 17.4k
- Forks
- 3.2k
- PR merge metrics
- No merged PRs in 30d
Description
Description:
When updating to 1.9.0 of material, we noticed an error when taking Paparazzi snapshot tests using a TabLayout. There was a change from 1.7.0 -> 1.9.0 where defaultTabTextAppearance was used.
Stacktrace
Jun 06, 2023 3:19:08 PM app.cash.paparazzi.internal.PaparazziLogger error
SEVERE: null: Style ResourceReference{namespace=apk/res-auto, type=attr, name=textAppearanceButton} is not of type STYLE (instead attr)
Jun 06, 2023 3:19:08 PM app.cash.paparazzi.internal.PaparazziLogger error
SEVERE: null: Style ResourceReference{namespace=apk/res-auto, type=attr, name=textAppearanceButton} is not of type STYLE (instead attr)
Jun 06, 2023 3:19:08 PM app.cash.paparazzi.internal.PaparazziLogger error
SEVERE: resources.resolve: Failed to find style with 2130969720
Cannot invoke "android.content.res.BridgeTypedArray.setTheme(android.content.res.Resources$Theme)" because "ta" is null
java.lang.NullPointerException: Cannot invoke "android.content.res.BridgeTypedArray.setTheme(android.content.res.Resources$Theme)" because "ta" is null
at android.content.res.Resources_Theme_Delegate.obtainStyledAttributes(Resources_Theme_Delegate.java:74)
at android.content.res.Resources$Theme.obtainStyledAttributes(Resources.java:1631)
at android.content.Context.obtainStyledAttributes(Context.java:874)
at android.widget.TextView.setTextAppearance(TextView.java:3965)
at androidx.appcompat.widget.AppCompatTextView.setTextAppearance(AppCompatTextView.java:216)
at android.widget.TextView.setTextAppearance(TextView.java:3954)
at androidx.core.widget.TextViewCompat.setTextAppearance(TextViewCompat.java:289)
...
at com.google.testing.junit.testparameterinjector.PluggableTestRunner$ContextMethodRule$1.evaluate(PluggableTestRunner.java:429)
at org.junit.runners.BlockJUnit4ClassRunner$1.evaluate(BlockJUnit4ClassRunner.java:100)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:366)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:103)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:63)
at org.junit.runners.ParentRunner$4.run(ParentRunner.java:331)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:79)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:329)
at org.junit.runners.ParentRunner.access$100(ParentRunner.java:66)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:293)
at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
at org.junit.runners.ParentRunner.run(ParentRunner.java:413)
at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.runTestClass(JUnitTestClassExecutor.java:108)
at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.execute(JUnitTestClassExecutor.java:58)
at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.execute(JUnitTestClassExecutor.java:40)
at org.gradle.api.internal.tasks.testing.junit.AbstractJUnitTestClassProcessor.processTestClass(AbstractJUnitTestClassProcessor.java:60)
at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.processTestClass(SuiteTestClassProcessor.java:52)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:36)
at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
at org.gradle.internal.dispatch.ContextClassLoaderDispatch.dispatch(ContextClassLoaderDispatch.java:33)
at org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:94)
at jdk.proxy1/jdk.proxy1.$Proxy2.processTestClass(Unknown Source)
at org.gradle.api.internal.tasks.testing.worker.TestWorker$2.run(TestWorker.java:176)
at org.gradle.api.internal.tasks.testing.worker.TestWorker.executeAndMaintainThreadName(TestWorker.java:129)
at org.gradle.api.internal.tasks.testing.worker.TestWorker.execute(TestWorker.java:100)
at org.gradle.api.internal.tasks.testing.worker.TestWorker.execute(TestWorker.java:60)
at org.gradle.process.internal.worker.child.ActionExecutionWorker.execute(ActionExecutionWorker.java:56)
at org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker.call(SystemApplicationClassLoaderWorker.java:113)
at org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker.call(SystemApplicationClassLoaderWorker.java:65)
Expected behavior:
Correctly load styles from attributes using something like this
val attrs = intArrayOf(defaultTabTextAppearance) // The array of attributes we're interested in.
val ta = context.obtainStyledAttributes(attrs) // Get the value referenced by the attributes in the array
val resId = ta.getResourceId(0, 0) // The first 0 is the index in the 'attrs' array.
ta.recycle() // Don't forget that! You can also use TypedArray.use { } extensions from android KTX.
TextViewCompat.setTextAppearance(textView, resId) // Utility method to set text appearance for all SDK versions
Source code: The code snippet which is causing this issue
class SampleTest {
@get:Rule
val paparazzi = Paparazzi(
deviceConfig = DeviceConfig.PIXEL_2.copy(fontScale = accessibilityTextSize.scale),
)
private val context: Context by lazy { paparazzi.context.wrapWithTheme { design.provide(this) } }
@Test
fun default() {
val view = TabLayout(context, null)
println("textAppearanceButton ID: " + com.google.android.material.R.attr.textAppearanceButton)
TextViewCompat.setTextAppearance(textView, com.google.android.material.R.attr.textAppearanceButton)
paparazzi.snapshot(view)
}
}
Minimal sample app repro:
TBD
Android API version:
32 (via Paparazzi)
Material Library version: 1.9.0
Device: (Run via junit tests with Paparazzi)
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Assessment
This issue has not been assessed yet.