看源码理解几种设置View背景的区别

QuibblerQuibbler 2019-12-24 约 9 分钟 2422 次阅读

看源码理解几种设置View背景的区别

在写代码的时候给一个布局View设置背景,一开始使用的是setsetBackgroundResource()由于某种原因没有效果,换成setBackground()就可以了。很好奇,这其中的原理,虽然这些都是用来给View设置背景的,最大的不同无外乎参数不同:

  • setBackground(Drawable background):其参数为一个Drawable对象,目的是设置view的背景图片,Drawable对象可以这样获取getResources().getDrawable(R.drawable.xx),还可以是Context.getResource().getColor(R.color.white)

  • setBackgroundColor(int color):其参数为一个颜色值,其目的是设置一个view的背景颜色

  • setBackgroundDrawable(Drawable background):和SetBackground有异曲同工之妙,都是通过传入一个Drawable对象设置view控件的背景图片

  • setBackgroundResource(int resid):它也是设置一个view的背景图片,只不过传入的是一个drawable的id值或者color颜色值

先来看第一个setBackground(Drawable background)的源码,内部调用setBackgroundDrawable(Drawable background)方法

/**
     * 将背景设置为给定的Drawable,或删除背景。 如果
     * background has padding, this View's padding is set to the background's
     * padding. However, when a background is removed, this View's padding isn't
     * touched. If setting the padding is desired, please use
     * {@link #setPadding(int, int, int, int)}.
     *
     * @param background The Drawable to use as the background, or null to remove the
     *        background
     */
    public void setBackground(Drawable background) {
        //noinspection deprecation
        setBackgroundDrawable(background);
    }

再看setBackgroundDrawable(Drawable background)的内部实现,很复杂,这里没有全部列出来。虽然已经被标记为deprecated,不建议当做API直接调用,猜测可能Google想把这个API最终hide或者private作为内部实现方法,因为其它几个设置背景的最终都是通过这个来实现的:

/**
     * @deprecated use {@link #setBackground(Drawable)} instead
     */
    @Deprecated
    public void setBackgroundDrawable(Drawable background) {
        computeOpaqueFlags();
        if (background == mBackground) {
            return;
        }
        ... ...
    }

设置视图的背景色 方法setBackgroundColor(@ColorInt int color)也会调用到setBackground->setBackgroundDrawable

/**
     * 设置此视图的背景色。
     * @param color the color of the background
     */
    @RemotableViewMethod
    public void setBackgroundColor(@ColorInt int color) {
        if (mBackground instanceof ColorDrawable) {
            ((ColorDrawable) mBackground.mutate()).setColor(color);
            computeOpaqueFlags();
            mBackgroundResource = 0;
        } else {
            setBackground(new ColorDrawable(color));
        }
    }

setBackgroundResource(@DrawableRes int resid)是设置view的背景图片,内部实现也是通过调用链:setBackground->setBackgroundDrawable来实现的。不过需要注意的是如果设置的资源和上次一样就不会重新设置而是直接返回,除了再次设置的resid和上一次设置的不一样才会通过资源id获取到Drawable对象再调用setBackground进行设置。【这就不难解释之前为什么用setBackgroundResource方法不管用,因为两次设置了同样的资源ID】

/**
     * 将背景设置为给定的资源。 资源应引用Drawable对象或0以删除背景。
     * @param resid The identifier of the resource.
     *
     * @attr ref android.R.styleable#View_background
     */
    @RemotableViewMethod
    public void setBackgroundResource(@DrawableRes int resid) {
        if (resid != 0 && resid == mBackgroundResource) {
            return;
        }
        Drawable d = null;
        if (resid != 0) {
            d = mContext.getDrawable(resid);
        }
        setBackground(d);
        mBackgroundResource = resid;
    }

参考博客:

        《setBackground(),setBackgroundResource(),setBackgroundColor(),setBackgroundDrawable()的区别和用法》

        《setBackgroundDrawable跟setBackgroundResource的区别》

        《setBackgroundDrawable跟setBackgroundResource的区别》

相关推荐

精选
ViewPager和PagerAdapter、FragmentPagerAdapter、FragmentStatePager
Android

ViewPager和PagerAdapter、FragmentPagerAdapter、FragmentStatePager

ViewPager1、ViewPagerandroidx.viewpager.widget.ViewPager,Android中使用非常广泛的控件,可以说是APP必备:首次打开引导页、页面Banner广告等。常用方法:setAdapter() 设置适配器setOffscreenPageLimit() 设置缓存的页面个数,默认是 1setCurrentItem() 跳转到特定的页面setOnPage

1.1k
获取Android内置WebView内核版本
Android

获取Android内置WebView内核版本

获取Android内置WebView内核版本竟然能遇到这样奇葩的事情,网页用的技术过于新颖,以至于只支持高版本Chromium内核的,低版本安卓系统中内置的内核版本较低,无法加载前端页面。1、设置查看在系统设置里 > 应用 > 应用管理 > 显示系统应用,查看WebView组件:2、页面查看通过WebView发起的网络请求,都会带上浏览器的UA,通常页面都可以通过UA判断浏览器的内核版本。这里有两

1.1w
Android 14适配总结
Android

Android 14适配总结

Android 14适配总结毕业工作至今已经适配了三个Android大版本,从Android 11到Android 12、再到Android 13。2023年,Google即将推出的Android 14,上半年已经开始第一批适配。现在,第四个Android版本已经适配完,总结记录一下。1、Android 14计划Google一般会在2月份对外发布预告,同时放出开发者预览版。“拉通”各大平台、厂商以

1.1w