Drawable 已经属于另一个所有者,但没有公开一个常量状态

Posted

技术标签:

【中文标题】Drawable 已经属于另一个所有者,但没有公开一个常量状态【英文标题】:Drawable already belongs to another owner but does not expose a constant state 【发布时间】:2018-09-12 05:35:39 【问题描述】:

错误:添加到 LayerDrawable 中的可绘制对象无效! Drawable 已经属于另一个所有者,但不公开常量状态。

我今天突然注意到这个错误,不知道是不是因为我刚刚将我的测试设备更新到了 android 8.0。错误消息清楚地表明在浮动操作按钮上设置波纹效果有问题,按下按钮时确实没有波纹效果。但是,我不确定是什么导致了这个问题。实际上,完全相同的错误连续抛出两次。任何帮助将非常感激!该应用程序的其余部分仍然可以正常运行,但是该错误确实困扰着我。

附言minSdkVersion 为 22,targetSdkVersion 和compiledSdkVersion 为27

在 MyActivity 中,第 117 行是数据绑定和设置内容视图。

ActivityMyBinding binding = DataBindingUtil.setContentView(
            this, R.layout.activity_my);

这是完整的堆栈跟踪:

W/LayerDrawable: Invalid drawable added to LayerDrawable! Drawable already belongs to another owner but does not expose a constant state.
             java.lang.RuntimeException
                 at android.graphics.drawable.LayerDrawable$ChildDrawable.<init>(LayerDrawable.java:1855)
                 at android.graphics.drawable.LayerDrawable$LayerState.<init>(LayerDrawable.java:1975)
                 at android.graphics.drawable.LayerDrawable.createConstantState(LayerDrawable.java:168)
                 at android.graphics.drawable.LayerDrawable.mutate(LayerDrawable.java:1779)
                 at android.graphics.drawable.LayerDrawable.mutate(LayerDrawable.java:1785)
                 at android.graphics.drawable.RippleDrawable.mutate(RippleDrawable.java:997)
                 at android.view.View.applyBackgroundTint(View.java:21809)
                 at android.view.View.setBackgroundDrawable(View.java:21680)
                 at android.support.design.widget.FloatingActionButton.access$001(FloatingActionButton.java:68)
                 at android.support.design.widget.FloatingActionButton$ShadowDelegateImpl.setBackgroundDrawable(FloatingActionButton.java:824)
                 at android.support.design.widget.FloatingActionButtonLollipop.setBackgroundDrawable(FloatingActionButtonLollipop.java:73)
                 at android.support.design.widget.FloatingActionButton.<init>(FloatingActionButton.java:179)
                 at android.support.design.widget.FloatingActionButton.<init>(FloatingActionButton.java:151)
                 at java.lang.reflect.Constructor.newInstance0(Native Method)
                 at java.lang.reflect.Constructor.newInstance(Constructor.java:334)
                 at android.view.LayoutInflater.createView(LayoutInflater.java:647)
                 at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:790)
                 at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:730)
                 at android.view.LayoutInflater.rInflate(LayoutInflater.java:863)
                 at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:824)
                 at android.view.LayoutInflater.inflate(LayoutInflater.java:515)
                 at android.view.LayoutInflater.inflate(LayoutInflater.java:423)
                 at android.view.LayoutInflater.inflate(LayoutInflater.java:374)
                 at android.support.v7.app.AppCompatDelegateImplV9.setContentView(AppCompatDelegateImplV9.java:287)
                 at android.support.v7.app.AppCompatActivity.setContentView(AppCompatActivity.java:139)
                 at android.databinding.DataBindingUtil.setContentView(DataBindingUtil.java:276)
                 at android.databinding.DataBindingUtil.setContentView(DataBindingUtil.java:261)
                 at com.generica.genericb.genericc.MyActivity.onCreate(MyActivity.java:117)
                 at android.app.Activity.performCreate(Activity.java:7174)
                 at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1220)
                 at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2908)
                 at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3030)
                 at android.app.ActivityThread.-wrap11(Unknown Source:0)
                 at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1696)
                 at android.os.Handler.dispatchMessage(Handler.java:105)
                 at android.os.Looper.loop(Looper.java:164)
                 at android.app.ActivityThread.main(ActivityThread.java:6938)
                 at java.lang.reflect.Method.invoke(Native Method)
                 at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:327)
                 at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1374)

【问题讨论】:

【参考方案1】:

我需要使用app:backgroundTint 而不是android:backgroundTint

【讨论】:

【参考方案2】:

app:srcCompat="@android:drawable/..." 更改为android:src="@android:drawable/..." 已为我解决了这个问题。

奇怪...之前发布答案的人向我指出了解决方案,但他们删除了他们的答案。 =/

他们提到了 Drawable 是如何具有状态的,如果你将它分配给多个浮动操作按钮,那么跟踪 Drawable 的状态就会出现问题。显然通过最近的更新,这个问题得到了解决。这让我意识到我正在使用 app:srcCompat 而不是 android:src 设置 FAB 的源。

【讨论】:

【参考方案3】:

如果活动 xml 中有 Fab,请保留以下代码并删除 android:backgroundTint="@color/colorPrimary" 这解决了问题。

<android.support.design.widget.FloatingActionButton
android:id="@+id/fab"
android:layout_
android:layout_
android:layout_marginStart="@dimen/list_fab_margin"
android:layout_marginTop="@dimen/list_fab_margin"
android:layout_marginEnd="@dimen/list_fab_margin"
android:layout_marginBottom="@dimen/list_fab_margin"
app:backgroundTint="@color/colorPrimary"
app:fabSize="mini"
app:srcCompat="@drawable/ic_edit"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:layout_editor_absoluteX="41dp"
tools:layout_editor_absoluteY="16dp" />

【讨论】:

以上是关于Drawable 已经属于另一个所有者,但没有公开一个常量状态的主要内容,如果未能解决你的问题,请参考以下文章

如何将android位图别名为另一个尺寸的drawable(drawable-large-mdpi别名为drawable-hdpi)

Kendo Scheduler删除其他月份的Line

C#两个DataTable拷贝问题:该行已经属于另一个表的解决方法

重用数据表或我是以错误的方式...:DataTable已经属于另一个DataSet

该行已经属于另一个表.怎么解决

DataTable 已经属于另一个 DataSet