4

I have a FrameLayout that has a ripple effect on click. To do this I have this tag on my FrameLayout:

android:foreground="?attr/selectableItemBackgroundBorderless"

The problem is that I get an error that says: "Cannot resolve symbol '?attr/selectableItemBackgroundBorderless'". Despite the error, I can still run the project and the FrameLayout has the effect I want.

But if I try to had this tag instead:

android:foreground="?android:attr/selectableItemBackgroundBorderless"

I get another error. It says that this tag requires API level 21.

So my question is, what is the right way to do this? Should I keep using the one that cannot resolve symbol and ignore the error? Is there any other way to have a similar behaviour with another tag?

Ravers
  • 988
  • 2
  • 14
  • 45

6 Answers6

3

?android:attr/selectableItemBackgroundBorderless for a ripple that extends beyond the view. It will be drawn upon, and bounded by, the nearest parent of the view with a non-null background.

  • selectableItemBackgroundBorderless is a new attribute introduced in API level 21.

If you want to use this, then open your MODULE LEVEL build.gradle and set

    compileSdkVersion 27
    buildToolsVersion "27.0.3"
    defaultConfig {
        applicationId "\\"
        minSdkVersion 21
        targetSdkVersion 27

Make sure, add google() in your PROJECT LEVEL build.gradle section.

repositories {
        ....
        google() //maven { url 'https://maven.google.com' }
    }

STRUCTURE

<!-- Background drawable for borderless standalone items that need focus/pressed states. -->
 <attr name="selectableItemBackgroundBorderless" format="reference" />

NOTE

If your code is deliberately accessing newer APIs, and you have ensured (e.g. with conditional execution) that this code will only ever be called on a supported platform, then you can annotate your class or method with the @TargetApi annotation specifying the local minimum SDK to apply, such as @TargetApi(11), such that this check considers 11 rather than your manifest file's minimum SDK as the required API level.

XML for that,

android:foreground="?android:attr/selectableItemBackgroundBorderless"
tools:targetApi="lollipop"

For more information,

IntelliJ Amiya
  • 74,896
  • 15
  • 165
  • 198
2

From the source code of support library appcompat-v7, you can see that ?attr/selectableItemBackgroundBorderless is an alias for ?android:attr/selectableItemBackgroundBorderless:

<item name="selectableItemBackgroundBorderless">?android:attr/selectableItemBackgroundBorderless</item>

And from Android platform source code, you can see that selectableItemBackgroundBorderless is the resource added in version 21 of the platform:

<public type="attr" name="selectableItemBackgroundBorderless" id="0x0101045c" />

When you're using the following:

android:foreground="?attr/selectableItemBackgroundBorderless"

You're using the resource that support library provided. The error, in my opinion, is because Android Studio trying to know the original resource which is not found in api below 21. Because the original resource not found, it will fallback to the resource that is provided by the support library.

ישו אוהב אותך
  • 28,609
  • 11
  • 78
  • 96
1

It's helped me:

  1. Open your project in Android Studio.
  2. Build -> Clean Project.
  3. Open the project directory.
  4. Delete the following directories: .idea, .gradle
  5. Go back to Android Studio.
  6. File -> Invalidate Caches / Restart... -> Invalidate and Restart.
  7. File -> Sync Project with Gradle Files

Hope this helps you.

Alex
  • 888
  • 2
  • 7
  • 21
0

Instead of directly assigning android:foreground, have your FrameLayout use a style:

<FrameLayout 
    style="@style/MyStyle"
    ....>

On res/values/styles.xml, add the following:

<style name="MyStyle">
    <item name="android:foreground">?attr/selectableItemBackgroundBorderless</item>
</style>

Then on res/values-v21/styles.xml, add the symbol with the android: prefix:

<style name="MyStyle">
    <item name="android:foreground">?android:attr/selectableItemBackgroundBorderless</item>
</style>
0

android:foreground="?android:attr/selectableItemBackgroundBorderless" is only to be used on api 21 or later. If you want the app-compat version, you should remove the android part. (you can also remove the attr part, which is equal to not removing it).

Both of the below methods will work on api lower than 21 and are exactly the same:

android:foreground="?attr/selectableItemBackgroundBorderless"

android:foreground="?selectableItemBackgroundBorderless"

Adib Faramarzi
  • 3,798
  • 3
  • 29
  • 44
0

Set it to android:background="?android:attr/selectableItemBackground"

Unheilig
  • 16,196
  • 193
  • 68
  • 98
LopezDevelop
  • 291
  • 7
  • 13