api<17 layer-list定義的drawable嵌套的bitmap部分無法顯示

標(biāo)簽(空格分隔): android 問題集


由于特殊效果需要,drawable中定義很多l(xiāng)ayer-list的xml文件钧忽,然而在android 4.1.2的機型上卻無法顯示葡粒。問題重現(xiàn):
developer官方的介紹使用的layer-list的文件 bg.xml

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item>
        <bitmap android:src="@mipmap/android_orange"
            android:gravity="center" />
    </item>
    <item android:top="10dp" android:left="10dp">
        <bitmap android:src="@mipmap/android_yellow"
            android:gravity="center" />
    </item>
    <item android:top="20dp" android:left="20dp">
        <bitmap android:src="@mipmap/android_green"
            android:gravity="center" />
    </item>
</layer-list>

布局文件

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.example.zhugejiao.testapp.MainActivity">

    <ImageView
        android:id="@+id/image"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:src="@drawable/bg"
        />
</RelativeLayout>

運行在api>16的機子都能正常顯示(圖片有拉伸,不是我們關(guān)注的問題)黎炉,但是在android 4.1.2(leve 16) 的機子什么也木有VΤ印!慷嗜!

于是我分別在代碼里常試了以下兩中方法:

  1. imageView.setImageResource(R.drawable.bg);
  1. imageView.setImageDrawable(ContextCompat.getDrawable(this, R.drawable.bg));

第二種方法能正常顯示淀弹,開發(fā)版本是23,ImageView實例是AppCompatImageView.實際上是調(diào)用的AppCompatImageHelp.setImageResource(resId)

 void setImageResource(int resId) {
        if (resId != 0) {
            mView.setImageDrawable(mTintManager != null
                    ? mTintManager.getDrawable(resId)
                    : ContextCompat.getDrawable(mView.getContext(), resId));
        } else {
            mView.setImageDrawable(null);
        }
    }

由此可見庆械,問題發(fā)生TintManager.getDrawable上,該實例在AppCompatImageView中實例化的薇溃。進入后可以看到

public Drawable getDrawable(int resId, boolean failIfNotKnown) {
        final Context context = mContextRef.get();
        if (context == null) return null;

        Drawable drawable = ContextCompat.getDrawable(context, resId);

        if (drawable != null) {
            if (Build.VERSION.SDK_INT >= 8) {
                // Mutate can cause NPEs on 2.1
                drawable = drawable.mutate();
            }

            ......
        }
        return drawable;
    }

差多問題已經(jīng)很明確了,再執(zhí)行drawable = drawable.mutate();LayerDrawble.mLayerState.mChildren中的每個BitmapDrable的mBitMapHeight mBitMapWidth mTargetDensity都是正常的缭乘。但是執(zhí)行過后就被清零了沐序。why

查看Drawabler.mutate方法官方介紹可知,默認(rèn)情況下堕绩,所有從同一資源加載的drawable都共用一個狀態(tài)XXState extends ConstantState ,更改任何實現(xiàn)的狀態(tài)策幼,其他實例都會收到相應(yīng)通知并改,mutate操作后使用drawable狀態(tài)不定奴紧,保證不與其他實例共享它的狀態(tài)特姐。(顯然這個方法還是必要的,而api 17的也執(zhí)行了此方法為什么沒有被清零黍氮?)

看一下LayerDrawble.mutate 都做了些什么:

@Override
    public Drawable mutate() {
        if (!mMutated && super.mutate() == this) {
            ......
            mLayerState = new LayerState(mLayerState, this, null);
            final ChildDrawable[] array = mLayerState.mChildren;
            final int N = mLayerState.mNum;
            for (int i = 0; i < N; i++) {
                array[i].mDrawable.mutate();
            }
            mMutated = true;
        }
        return this;
    }

只是把mLayerState替換了一個新的對象嘛也沒干嘛唐含,但是替換后發(fā)現(xiàn)其mChildren的值就不一樣了。

翻看LayerState構(gòu)造函數(shù)可知其mChildren都是調(diào)用原來BitmapDrable的ConstantState新生成的沫浆。在構(gòu)造BitmapDrable的時候調(diào)用setBitmap()接著調(diào)用computeBitmapSize()重新測量大小

 private void computeBitmapSize() {
        mBitmapWidth = mBitmap.getScaledWidth(mTargetDensity);
        mBitmapHeight = mBitmap.getScaledHeight(mTargetDensity);
    }

最后問題找著了捷枯,因為原來的BitmapDrable中的BitmapState中的(mTargetDensity=0,系統(tǒng)沒有給值bug.),Bitpmapt.getScaleDXXX()都返回是Bitamp.scaleFromDensity(size,mDensity,targetDensity)

static public int scaleFromDensity(int size, int sdensity, int tdensity) {
        if (sdensity == DENSITY_NONE || sdensity == tdensity) {
            return size;
        }
        // Scale by tdensity / sdensity, rounding up.
        return ((size * tdensity) + (sdensity >> 1)) / sdensity;
    }

大小為0了當(dāng)然顯示不出來了专执。
api>16的重新寫了此函數(shù)淮捆,故能正常顯示。

似乎沒什么好的解決辦法他炊,盡量繞道吧。setBackground不會調(diào)用mutate,能正常顯示已艰。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末痊末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子哩掺,更是在濱河造成了極大的恐慌凿叠,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,277評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異盒件,居然都是意外死亡蹬碧,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,689評論 3 393
  • 文/潘曉璐 我一進店門炒刁,熙熙樓的掌柜王于貴愁眉苦臉地迎上來恩沽,“玉大人,你說我怎么就攤上這事翔始÷扌模” “怎么了?”我有些...
    開封第一講書人閱讀 163,624評論 0 353
  • 文/不壞的土叔 我叫張陵城瞎,是天一觀的道長渤闷。 經(jīng)常有香客問我,道長脖镀,這世上最難降的妖魔是什么飒箭? 我笑而不...
    開封第一講書人閱讀 58,356評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮蜒灰,結(jié)果婚禮上弦蹂,老公的妹妹穿的比我還像新娘。我一直安慰自己卷员,他們只是感情好盈匾,可當(dāng)我...
    茶點故事閱讀 67,402評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著毕骡,像睡著了一般削饵。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上未巫,一...
    開封第一講書人閱讀 51,292評論 1 301
  • 那天窿撬,我揣著相機與錄音,去河邊找鬼叙凡。 笑死劈伴,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的握爷。 我是一名探鬼主播跛璧,決...
    沈念sama閱讀 40,135評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼新啼!你這毒婦竟也來了追城?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,992評論 0 275
  • 序言:老撾萬榮一對情侶失蹤燥撞,失蹤者是張志新(化名)和其女友劉穎座柱,沒想到半個月后迷帜,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,429評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡色洞,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,636評論 3 334
  • 正文 我和宋清朗相戀三年戏锹,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片火诸。...
    茶點故事閱讀 39,785評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡锦针,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出惭蹂,到底是詐尸還是另有隱情伞插,我是刑警寧澤,帶...
    沈念sama閱讀 35,492評論 5 345
  • 正文 年R本政府宣布盾碗,位于F島的核電站媚污,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏廷雅。R本人自食惡果不足惜耗美,卻給世界環(huán)境...
    茶點故事閱讀 41,092評論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望航缀。 院中可真熱鬧商架,春花似錦、人聲如沸芥玉。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,723評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽灿巧。三九已至赶袄,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間抠藕,已是汗流浹背饿肺。 一陣腳步聲響...
    開封第一講書人閱讀 32,858評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留盾似,地道東北人敬辣。 一個月前我還...
    沈念sama閱讀 47,891評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像零院,于是被迫代替她去往敵國和親溉跃。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,713評論 2 354

推薦閱讀更多精彩內(nèi)容