真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

ViewCompat在Android中有什么用

ViewCompat在Android 中有什么用?很多新手對此不是很清楚,為了幫助大家解決這個難題,下面小編將為大家詳細(xì)講解,有這方面需求的人可以來學(xué)習(xí)下,希望你能有所收獲。

創(chuàng)新互聯(lián)是一家集網(wǎng)站建設(shè),阿拉山口企業(yè)網(wǎng)站建設(shè),阿拉山口品牌網(wǎng)站建設(shè),網(wǎng)站定制,阿拉山口網(wǎng)站建設(shè)報(bào)價(jià),網(wǎng)絡(luò)營銷,網(wǎng)絡(luò)優(yōu)化,阿拉山口網(wǎng)站推廣為一體的創(chuàng)新建站企業(yè),幫助傳統(tǒng)企業(yè)提升企業(yè)形象加強(qiáng)企業(yè)競爭力??沙浞譂M足這一群體相比中小企業(yè)更為豐富、高端、多元的互聯(lián)網(wǎng)需求。同時(shí)我們時(shí)刻保持專業(yè)、時(shí)尚、前沿,時(shí)刻以成就客戶成長自我,堅(jiān)持不斷學(xué)習(xí)、思考、沉淀、凈化自己,讓我們?yōu)楦嗟钠髽I(yè)打造出實(shí)用型網(wǎng)站。

詳解Android ViewCompat的作用

ViewCompat類主要是用來提供兼容性的, 比如我最近看的比較的多的canScrollVertically方法, 在ViewCompat里面針對幾個版本有不同的實(shí)現(xiàn), 原理上還是根據(jù)版本判斷, 有時(shí)甚至還要判斷傳入?yún)?shù)的類型. 但是要注意的是, ViewCompat僅僅讓你調(diào)用不崩潰, 并不保證你調(diào)用的結(jié)果在不同版本的機(jī)器上一致.

關(guān)于如何優(yōu)雅的組織代碼, ViewCompat類的結(jié)構(gòu)非常適合我們參考.

ViewCompat里面定義了一個接口, 這個接口列出了所有它支持的方法

interface ViewCompatImpl {
    public boolean canScrollHorizontally(View v, int direction);
    public boolean canScrollVertically(View v, int direction);
    public int getOverScrollMode(View v);
    public void setOverScrollMode(View v, int mode);
    ......
}

ViewCompat類并非是在方法層面進(jìn)行版本判斷然后調(diào)用不同的方法, 而是在類的層面上做的, 也就是說在調(diào)用方法時(shí)并沒有判斷版本的調(diào)用, 因?yàn)橐慌_手機(jī)的版本在開機(jī)到關(guān)機(jī)期間是不可能發(fā)生變化的, 所以只需要判斷一次, 而這次判斷放在了類的靜態(tài)初始化塊里.

static final ViewCompatImpl IMPL;
  static {
    final int version = android.os.Build.VERSION.SDK_INT;
    if (version >= 21) {
      IMPL = new LollipopViewCompatImpl();
    } else if (version >= 19) {
      IMPL = new KitKatViewCompatImpl();
    } else if (version >= 17) {
      IMPL = new JbMr1ViewCompatImpl();
    } else if (version >= 16) {
      IMPL = new JBViewCompatImpl();
    } else if (version >= 14) {
      IMPL = new ICSViewCompatImpl();
    } else if (version >= 11) {
      IMPL = new HCViewCompatImpl();
    } else if (version >= 9) {
      IMPL = new GBViewCompatImpl();
    } else if (version >= 7) {
      IMPL = new EclairMr1ViewCompatImpl();
    } else {
      IMPL = new BaseViewCompatImpl();
    }
  }

這樣我們就得到了針對各個版本的不同實(shí)現(xiàn).

但是有些方法的實(shí)現(xiàn)在跨越幾個版本的時(shí)候是不變的, 有些方法又有可能每次都變, 如何實(shí)現(xiàn)高效的代碼復(fù)用呢? 那就是繼承+重寫.

比如BaseViewCompatImpl這個類是基類, 實(shí)現(xiàn)ViewCompatImpl接口, 把所有的方法都實(shí)現(xiàn)一次

static class BaseViewCompatImpl implements ViewCompatImpl {
    ......
    public boolean canScrollHorizontally(View v, int direction) {
      return (v instanceof ScrollingView) &&
        canScrollingViewScrollHorizontally((ScrollingView) v, direction);
    }
    public boolean canScrollVertically(View v, int direction) {
      return (v instanceof ScrollingView) &&
          canScrollingViewScrollVertically((ScrollingView) v, direction);
    }
    ......
    @Override
    public boolean isOpaque(View view) {
      final Drawable bg = view.getBackground();
      if (bg != null) {
        return bg.getOpacity() == PixelFormat.OPAQUE;
      }
      return false;
    }
    ......
    }

但是這些實(shí)現(xiàn)基本上都是空的, 或者無效的, 或者是一些workaround, 這也很正常, 因?yàn)榇_實(shí)不可能讓每個方法都做到兼容, 只能盡量讓他的版本支持多一點(diǎn), 兼容性方法本來就有很多問題. 以上面這三個方法為例, 前兩個方法都是api 14出現(xiàn)的方法, 在14以下基本上等于是直接返回了false(這里低版本是僅對ScollingView提供了支持, ScollingView有三個基類, 其中一個是RecyclerView), google顯然沒有想到什么好的方法在低版本提供對這個方法的支持, 所以干脆就在api小于14時(shí)一直使用這個實(shí)現(xiàn), 而isOpaque則是類似workaround的方法, 在api 7時(shí), isOpaque被正式添加到View類中, 所以在api 7我們可以直接調(diào)View的isOpaque, 那么應(yīng)該怎么寫代碼呢? 應(yīng)當(dāng)新建一個類, 繼承BaseViewCompatImpl, 重寫isOpaque方法, 也就是下面這樣:

static class EclairMr1ViewCompatImpl extends BaseViewCompatImpl {
    @Override
    public boolean isOpaque(View view) {
      return ViewCompatEclairMr1.isOpaque(view);
    }

    ......
  }

而其他沒有更好兼容方案的方法我們都不管, 那么api 9如果某些方法又有了更好的實(shí)現(xiàn), 或者可以直接調(diào)用系統(tǒng)的api了, 就再新建一個類GBViewCompatImpl, 這個類需要繼承EclairMr1ViewCompatImpl.

同理, 我們在api 14對應(yīng)的類ICSViewCompatImpl中自然就會看到canScrollHorizontally和canScrollVertically的新的實(shí)現(xiàn), 而ICSViewCompatImpl必然繼承自HCViewCompatImpl.

就這樣慢慢的演化, 像串銅錢一樣, 每一個新的類對應(yīng)一個新的版本(版本之間不需要連續(xù)), 同時(shí)繼承自前一個版本的類, 在實(shí)現(xiàn)類的繼承樹上越接近葉子, 這個實(shí)現(xiàn)類的能力就越強(qiáng).

最后看一下我們在代碼里面使用這個類時(shí)的調(diào)用代碼, 比如我要調(diào)用canScrollVertically方法, 那么我的代碼一定是ViewCompat. canScrollVertically(v, dy), 看看這個方法對應(yīng)的代碼

public static boolean canScrollHorizontally(View v, int direction) {
    return IMPL.canScrollHorizontally(v, direction);
} 

ViewCompat相當(dāng)于是一個中介, 它自己其實(shí)什么都不懂, 但是它認(rèn)識一個懂的人IMPL, 它將所有的調(diào)用都交給了IMPL, 而IMPL在ViewCompat這個類加載時(shí)就已經(jīng)根據(jù)當(dāng)前系統(tǒng)版本實(shí)例化了, 不需要再判斷版本了.

看完上述內(nèi)容是否對您有幫助呢?如果還想對相關(guān)知識有進(jìn)一步的了解或閱讀更多相關(guān)文章,請關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,感謝您對創(chuàng)新互聯(lián)的支持。


分享標(biāo)題:ViewCompat在Android中有什么用
標(biāo)題URL:http://weahome.cn/article/pseise.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部