android - 为什么viewgroup invalidate,他的子view没有回调draw方法

浏览:37日期:2022-11-02

问题描述

我自定义了一个viewgroup(FloatBorderLayout),里面放置了几个ImageView,然后在viewgroup内部invalidate(),那么应该会进入viewrootimpl执行performTraversal方法遍历view树对吧,那么viewgroup内所有的ImageView都会重新走一遍绘制流程,事实上并没有,viewgroup内部Imageview内容,大小,布局都没变,所以都不会执行吗?如果我重写viewgroup的ondraw方法,在canvas上绘制图形,每一次调用invalidate之前的图形都会被擦除,难道canvas每次invalidate都会重新创建吗,如果是的话,为什么Imageview的绘制流程方法都没有回调,很困惑,希望有人解答一下。

一句话:为什么viewgroup invalidate后所有ImageView都没有回调measure,layout,draw方法,canvas上的绘制的圆角框却改变了?

public class FloatBorderLayout extends RelativeLayout implements View.OnFocusChangeListener, View.OnClickListener { private Paint mPaint; private RectF mRectF; private RectF oRectF; private boolean isInit; public FloatBorderLayout(Context context) {this(context, null); } public FloatBorderLayout(Context context, AttributeSet attr) {this(context, attr, 0); } public FloatBorderLayout(Context context, AttributeSet attr, int style) {super(context, attr, style);initBorderView(); } private void initBorderView() {setClickable(false);setClipChildren(false);oRectF = new RectF();mRectF = new RectF();mPaint = new Paint();mPaint.setAntiAlias(true);mPaint.setStrokeWidth(3);mPaint.setStyle(Paint.Style.STROKE); } @Override protected void onDraw(Canvas canvas) {super.onDraw(canvas);canvas.drawRoundRect(mRectF, 10, 10, mPaint); } @Override protected void onFinishInflate() {super.onFinishInflate();if (!isInit) { isInit = !isInit; for (int i = 0; i < getChildCount(); i++) {getChildAt(i).setOnClickListener(this);getChildAt(i).setOnFocusChangeListener(this); }} } @Override public void onFocusChange(View view, boolean hasFocus) {if (hasFocus) { borderFly(getLocation(view, 1.2f, 1.2f), view); imgScaleAnim(1.0f, 1.2f, 1.0f, 1.2f, 100, view);} else { imgScaleAnim(1.2f, 1.0f, 1.2f, 1.0f, 100, view);} } private RectF getLocation(View view, float xScale, float yScale) {RectF rectF = new RectF();float left = view.getLeft();float top = view.getTop();float right = view.getRight();float bottom = view.getBottom();float oWidth = right - left;float oHeight = bottom - top;float deltaX = oWidth * (xScale - 1) / 2;float deltaY = oHeight * (yScale - 1) / 2;rectF.left = view.getLeft() - deltaX - 1;rectF.top = view.getTop() - deltaY - 1;rectF.right = view.getRight() + deltaX + 1;rectF.bottom = view.getBottom() + deltaY + 1;return rectF; } public void imgScaleAnim(float fromXscale, float toXscale, float fromYscale, float toYscale, long duration, View v) {ScaleAnimation scaleAnimation = new ScaleAnimation(fromXscale, toXscale, fromYscale, toYscale,Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);scaleAnimation.setInterpolator(new AccelerateInterpolator());scaleAnimation.setFillAfter(true);scaleAnimation.setDuration(duration);v.startAnimation(scaleAnimation); } public void borderFly(final RectF rect, final View view) {switch (view.getId()) { case R.id.category_movie:mPaint.setColor(0xfffec96a);break; case R.id.category_music:mPaint.setColor(0xffffa1b9);break; case R.id.category_game:mPaint.setColor(0xffc8a5fd);break; case R.id.category_icontrol:mPaint.setColor(0xffa0dbff);break; case R.id.category_setting:mPaint.setColor(0xff93ffc2);break;}valueAnimator = ValueAnimator.ofObject(new TypeEvaluator() { @Override public Object evaluate(float fraction, Object startValue, Object endValue) {RectF startRF = (RectF) startValue;RectF endRF = (RectF) endValue;float left = startRF.left + fraction * (endRF.left - startRF.left);float right = startRF.right + fraction * (endRF.right - startRF.right);float top = startRF.top + fraction * (endRF.top - startRF.top);float bottom = startRF.bottom + fraction * (endRF.bottom - startRF.bottom);return new RectF(left, top, right, bottom); }}, oRectF, rect);valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) {mRectF = (RectF) animation.getAnimatedValue();invalidate(); }});valueAnimator.setDuration(300);valueAnimator.start();valueAnimator.addListener(new Animator.AnimatorListener() { @Override public void onAnimationStart(Animator animation) { } @Override public void onAnimationEnd(Animator animation) {oRectF = mRectF; } @Override public void onAnimationCancel(Animator animation) { } @Override public void onAnimationRepeat(Animator animation) { }}); }}

问题解答

回答1:

你在初始化自定义布局的时候添加上setWillNotDraw(false)试试看。

相关文章: