为什么`android(foreground`属性不起作用())

古人学问无遗力,少壮工夫老始成。这篇文章主要讲述为什么`android:foreground`属性不起作用?相关的知识,希望能为你提供帮助。
看看这个小的android应用程序:
main activity.java:

package io.github.gsaga.toucheventtest; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; public class MainActivity extends AppCompatActivity {@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } }

activity_main:
< ImageView android:layout_width="match_parent" android:layout_height="match_parent" android:foreground="@drawable/ic_launcher_background" xmlns:android="http://schemas.android.com/apk/res/android" />

android:foreground指向的图像没有显示,但是如果我在foreground中将src更改为backgroundactivity_main.xml则会出现。此代码似乎遵循此处描述的说明:
https://developer.android.com/reference/android/view/View.html#attr_android:foreground
为什么android:foreground标签不适用于上面的代码?
注意:
minSdkVersion19,我在Android 5.1API level 22)运行这个应用程序
答案 Short answer这是由于API级别23以来Android中存在的错误。

More details on the behavior以下是所有XML属性的列表以及与通过FrameLayout引入的API级别将前景drawable设置为视图相关的相应方法。但是,这些后来被转移到API级别23的View
╔════════════════════════════╦═════════════════════════════════════════════════╦═════════════╗ ║XML attribute║Method║Added in║ ║║║ (API level) ║ ╠════════════════════════════╬═════════════════════════════════════════════════╬═════════════╣ ║ android:foreground║ setForeground(Drawable)║ 1║ ╠════════════════════════════╬═════════════════════════════════════════════════╬═════════════╣ ║ android:foregroundGravity║ setForegroundGravity(int gravity)║ 1║ ╠════════════════════════════╬═════════════════════════════════════════════════╬═════════════╣ ║ android:foregroundTint║ setForegroundTintMode(PorterDuff.Mode tintMode) ║ 21║ ╠════════════════════════════╬═════════════════════════════════════════════════╬═════════════╣ ║ android:foregroundTintMode ║ setForegroundTintMode(PorterDuff.Mode tintMode) ║ 21║ ╚════════════════════════════╩═════════════════════════════════════════════════╩═════════════╝

  • Android doc说,setForeground(Drawable)在API 1中添加,setForegroundTintList (ColorStateList tint)setForegroundTintMode (PorterDuff.Mode tintMode)在API级别21中添加到View。这是错误的。在FrameLayout有直到API 23。
  • 在API级别< 23,即使不需要,您也会收到警告。你可以压制它。见this。

现在来看看这些属性如何在不同版本上运行。
╔═══════════╦══════════════════╦══════════════════╗ ║ API level ║By code║Using XML║ ╠═══════════╬══════════════════╬══════════════════╣ ║ < 23║ FrameLayout only ║ FrameLayout only ║ ╠═══════════╬══════════════════╬══════════════════╣ ║ > =23║ FrameLayout only ║ All views║ ╚═══════════╩══════════════════╩══════════════════╝


The cause of the bug当这些属性在API级别23中移动到View时,他们对它进行了一些奇怪的修改,可以称之为bug。在从XML加载属性时,它检查View是否是FrameLayout,它不存在于我们可以用于相同目的的方法中。
查看构造函数,API级别23:
case R.styleable.View_foreground: if (targetSdkVersion > = Build.VERSION_CODES.M || this instanceof FrameLayout) { setForeground(a.getDrawable(attr)); } break;

另一答案要在android:foregroundAndroid 5.1上使用API level 22,你没有正确使用android:foreground
因为它的名字清楚地表明你可以在任何内容(如叠加)的顶部/前景上设置drawable,即你可以在FrameLayout中放置一些视图,你可以使用android:foreground。在这个FrameLayout内添加你的ImageView
Documentation:
定义drawable以绘制内容。这可以用作叠加层。如果重力设置为填充,则前景drawable参与内容的填充。
以下是用法示例:
< FrameLayout android:id="@+id/share" android:layout_width="wrap_content" android:layout_height="wrap_content" android:foreground="@drawable/ic_launcher_background> // your ImageView here < ImageView android:layout_width="match_parent" android:layout_height="match_parent"/> < /FrameLayout>

注意:对于API level > 23,它将在没有FrameLayout的情况下工作。
我希望这能帮到您。
另一答案看起来像是一次(API < 23),android:foreground只会与FrameLayout合作,正如VicJordan所暗示的那样。但是,对于API 23+,android:foreground似乎适用于任何视图类型。请参阅View.java源中的this选择:
case R.styleable.View_foreground: if (targetSdkVersion > = Build.VERSION_CODES.M || this instanceof FrameLayout) { setForeground(a.getDrawable(attr)); }

【为什么`android(foreground`属性不起作用())】以下是使用以下布局在qamxswpoi上工作的示例:
android:foreground

< androidx.constraintlayout.widget.ConstraintLayout android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> < ImageView android:layout_width="match_parent" android:layout_height="match_parent" android:foreground="@drawable/ic_launcher_foreground" android:src="https://www.songbingjia.com/android/@android:drawable/ic_delete" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" /> < /androidx.constraintlayout.widget.ConstraintLayout>
然而,在API 22上,我们看到:
为什么`android(foreground`属性不起作用())

文章图片

没有前景图片。因此,
为什么`android(foreground`属性不起作用())

文章图片
仅在API级别为23+时才有效。我同意这并没有真正记录,但这就是它的方式。
更新:API 23似乎与android:foreground有问题,所以让我们说android:foreground适用于API 24+以获取一般视图。
第二次更新:遇到了几个关于android:foreground setForeground()和here的同样问题的其他帖子。在第二个问题的接受答案中,CommonsWare将其识别为“文档错误”。

    推荐阅读