Android疑难解决-RecyclerView中setBackground后view大小改变

Android疑难解决-RecyclerView中setBackground后view大小改变,第1张

Android疑难解决-RecyclerView中setBackground后view大小改变 setBackground后view大小改变
  private Drawable selDrawable, unDrawable;
		selDrawable = ....;
		unDrawable = ....;

	//setOnClickListener内
		layout.setBackground(
 			//控制变量 boolean改变Background
 			? selDrawable : unDrawable
		 );
解决方法

在改变Background前使用

layout.setBackgroundResource(0);
//或者
layout.setBackground(null);
总结

背景设置为给定的 Drawable,或删除背景。 如果背景有填充,则此视图的填充设置为背景的填充。
但是,当移除背景时,不会触及此视图的填充。 如果需要设置填充,请使用setPadding(int, int, int, int) 。

参数: background – 用作背景的 Drawable,或 null 以删除背景

 
    public void setBackground(Drawable background) {
        //noinspection deprecation
        setBackgroundDrawable(background);
    }

	//setBackground
	//setBackgroundResource
	//setBackgroundColor
	//都会走这个方法
 @Deprecated
    public void setBackgroundDrawable(Drawable background) {
	    //计算不透明度
        computeOpaqueFlags();

        if (background == mBackground) {
            return;
        }

        boolean requestLayout = false;

        mBackgroundResource = 0;

        
        if (mBackground != null) {
            if (isAttachedToWindow()) {
                mBackground.setVisible(false, false);
            }
            mBackground.setCallback(null);
            unscheduleDrawable(mBackground);
        }

        if (background != null) {
            Rect padding = sThreadLocal.get();
            if (padding == null) {
                padding = new Rect();
                sThreadLocal.set(padding);
            }
            resetResolvedDrawablesInternal();
            background.setLayoutDirection(getLayoutDirection());
            if (background.getPadding(padding)) {
                resetResolvedPaddingInternal();
                switch (background.getLayoutDirection()) {
                    case LAYOUT_DIRECTION_RTL:
                        mUserPaddingLeftInitial = padding.right;
                        mUserPaddingRightInitial = padding.left;
                        internalSetPadding(padding.right, padding.top, padding.left, padding.bottom);
                        break;
                    case LAYOUT_DIRECTION_LTR:
                    default:
                        mUserPaddingLeftInitial = padding.left;
                        mUserPaddingRightInitial = padding.right;
                        internalSetPadding(padding.left, padding.top, padding.right, padding.bottom);
                }
                mLeftPaddingDefined = false;
                mRightPaddingDefined = false;
            }

            // Compare the minimum sizes of the old Drawable and the new.  If there isn't an old or
            // if it has a different minimum size, we should layout again
            //比较旧 Drawable 和新 Drawable 的最小尺寸。
            //如果没有旧的或者最小尺寸不同,我们应该重新布局
            if (mBackground == null
                    || mBackground.getMinimumHeight() != background.getMinimumHeight()
                    || mBackground.getMinimumWidth() != background.getMinimumWidth()) {
                requestLayout = true;
            }

            // Set mBackground before we set this as the callback and start making other
            // background drawable state change calls. In particular, the setVisible call below
            // can result in drawables attempting to start animations or otherwise invalidate,
            // which requires the view set as the callback (us) to recognize the drawable as
            // belonging to it as per verifyDrawable.
            //在我们将其设置为回调之前设置 mBackground 并开始进行其他后台可绘制状态更改调用。
            //特别是,下面的 setVisible 调用可能导致可绘制对象尝试启动动画或以其他方式无效,
            //这需要将视图设置为回调(我们)以根据 verifyDrawable 将可绘制对象识别为属于它。
            mBackground = background;
            if (background.isStateful()) {
                background.setState(getDrawableState());
            }
            if (isAttachedToWindow()) {
                background.setVisible(getWindowVisibility() == VISIBLE && isShown(), false);
            }

            applyBackgroundTint();

            // Set callback last, since the view may still be initializing.
            //最后设置回调,因为视图可能仍在初始化
            background.setCallback(this);

            if ((mPrivateFlags & PFLAG_SKIP_DRAW) != 0) {
                mPrivateFlags &= ~PFLAG_SKIP_DRAW;
                requestLayout = true;
            }
        } else {
            
            //删除背景
            mBackground = null;
            if ((mViewFlags & WILL_NOT_DRAW) != 0
                    && (mDefaultFocusHighlight == null)
                    && (mForegroundInfo == null || mForegroundInfo.mDrawable == null)) {
                mPrivateFlags |= PFLAG_SKIP_DRAW;
            }

            

            // The old background's minimum size could have affected this
            // View's layout, so let's requestLayout
            //旧背景的最小尺寸可能会影响这个视图的布局,所以让我们 requestLayout
            requestLayout = true;
        }

        computeOpaqueFlags();

        if (requestLayout) {
            requestLayout();
        }

        mBackgroundSizeChanged = true;
        invalidate(true);
        invalidateOutline();
    }

初步判断:
如果setBackgroundDrawable(null)
此view会requestLayout()重新测量

如果setBackgroundDrawable(不是null)
此view会invalidate()

invalidate();
只会触发执行onDraw方法,只会改变绘制里面的内容,条目的绘制

postInvalidate();
只会触发执行onDraw方法,但是可以在子线程中刷新

requestLayout();
view的布局参数改变之后刷新,比如view的宽度和高度都修改了,只能通过requestLayout()方法刷新

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zaji/5686014.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-17
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存