为什么`android:foreground`属性不起作用?

sag*_*aga 9 xml android android-layout

看看这个小的Android应用程序:

MainActivity.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);
    }
}
Run Code Online (Sandbox Code Playgroud)

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" />
Run Code Online (Sandbox Code Playgroud)

指示的图像android:foreground不会显示,但如果我更改foregroundsrcbackground中,则会显示activity_main.xml.此代码似乎遵循此处描述的说明:

https://developer.android.com/reference/android/view/View.html#attr_android:foreground

为什么android:foreground标签在上面的代码中不起作用?

注意:

minSdkVersion是的19,我正在运行这个应用程序Android 5.1(API level 22)

Ber*_*yle 24

简短的回答

这是由于API级别23以来Android中存在的错误.


关于行为的更多细节

下面列出了所有方法和相应的XML属性,这些方法和相应的XML属性与将前景drawables设置为视图,并通过它们引入API级别FrameLayout.但是,这些稍后将进入ViewAPI级别23.

??????????????????????????????????????????????????????????????????????????????????????????????
?       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          ?
??????????????????????????????????????????????????????????????????????????????????????????????
Run Code Online (Sandbox Code Playgroud)
  • Android doc说setForeground(Drawable)是在API 1 中添加,setForegroundTintList (ColorStateList tint)setForegroundTintMode (PorterDuff.Mode tintMode)在API级别21中添加View.这是错误的.有中FrameLayout到API 23.

  • 在API级别<23,即使不需要,您也会收到警告.你可以压制它.看到这个.


现在来看看这些属性如何在不同版本上运行.

???????????????????????????????????????????????????
? API level ?      By code     ?     Using XML    ?
???????????????????????????????????????????????????
? <23       ? FrameLayout only ? FrameLayout only ?
???????????????????????????????????????????????????
? >=23      ? FrameLayout only ? All views        ?
???????????????????????????????????????????????????
Run Code Online (Sandbox Code Playgroud)


这个bug的原因

当这些属性移到ViewAPI级别23时,他们对它进行了一些奇怪的修改,可以称之为bug.虽然从加载XML属性,它会检查是否ViewFrameLayout它不存在,我们可以使用同样的目的方法里面.

查看构造函数,API级别23:

case R.styleable.View_foreground:
    if (targetSdkVersion >= Build.VERSION_CODES.M || this instanceof FrameLayout) {
        setForeground(a.getDrawable(attr));
    }
    break;
Run Code Online (Sandbox Code Playgroud)


Vik*_*ngh 6

android:foregroundAndroid 5.1ie上使用API level 22,则使用不android:foreground正确。

正如它的名字清楚地表明,你可以设置绘制上的任何内容的顶部/前景像叠加,即你可以把一些视图FrameLayout中,您可以使用android:foreground。在此FrameLayout中添加您的ImageView

说明文件

定义可绘制内容的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>
Run Code Online (Sandbox Code Playgroud)

注意: 因为API level > 23它可以不带FrameLayout

我希望这能帮到您。