3

I'm trying to figure out the optimization for my custom view. I'm wondering if the calling to View.setVisibility(View.VISIBLE) forces the Android framework to update the view visibility (<- forcing the view to redraw) even if the view is already visible.

4

4 に答える 4

6

いいえ、そうではありません。

見てみましょうsetVisibility()

public void setVisibility(int visibility) {
    setFlags(visibility, VISIBILITY_MASK);
    if (mBGDrawable != null) mBGDrawable.setVisible(visibility == VISIBLE, false);
}

を呼び出すだけでsetFlags()、何も変更されていない場合はすぐに戻ります。

....
int changed = mViewFlags ^ old;
if (changed == 0) {
    return;
}

(どういうわけか)そこを通り過ぎたとしても、個々のフラグの変更をチェックし、そのうちの1つが以前と異なる場合にのみ更新します。

于 2013-09-30T15:48:41.457 に答える
3

で見てView#setVisibility:

public void setVisibility(int visibility) {
    setFlags(visibility, VISIBILITY_MASK);
    if (mBackground != null) mBackground.setVisible(visibility == VISIBLE, false);
}

setFlags(...)メソッドは次で始まります。

int old = mViewFlags;
mViewFlags = (mViewFlags & ~mask) | (flags & mask);

int changed = mViewFlags ^ old;
if (changed == 0) {
    return;
}

したがって、このメソッドは何もしないと確信しています。そうしないと、レイアウトと再描画をトリガーする以外に、多くのことを行うことになります。

Background#setVisibleも同様です:

public boolean setVisible(boolean visible, boolean restart) {
    boolean changed = mVisible != visible;
    if (changed) {
        mVisible = visible;
        invalidateSelf();
    }
    return changed;
}

iffalse になるため、これは何もしません。

ただし、、、、およびView#setVisible()によって上書きされます。他に何か特別なことを行う場合は、各実装を確認する必要があります。これらのサブクラスのいずれかを使用している可能性があります。ImageViewMediaRouteButtonProgressBarSurfaceViewViewStub

にも同じことが当てはまります:Drawable上書きする 8 つのクラスがありますDrawable#setVisible(boolean, boolean):

  1. ClipDrawable
  2. DrawableContainer
  3. AnimationDrawable - DrawableContainer から拡張
  4. InsetDrawable
  5. LayerDrawable
  6. RotateDrawble
  7. ScaleDrawable
  8. SlideDrawable

組み合わせによっては、実際には余分なことをしていることに気付く場合があるため、View使用しているのがどのような種類で、その背景の drawable がどの種類の drawable であるかを調査する必要があります。

于 2013-09-30T15:50:31.347 に答える
1

setVisibility() は内部で setFlags を呼び出すことによってビュー フラグを設定します。sdk View.setFlags() に入ると、フラグの状態が変更されていない場合、このメソッドは何もしないことがわかります。SDK View.setFlags() メソッドからのコード:int changed = mViewFlags ^ old; if (changed == 0) { return; }

于 2013-09-30T15:47:31.260 に答える
1

100%ではありませんが、そうは思いません

Viewクラスのgrepcodeから、setFlags(int flags, int mask)これは呼び出されたメソッドからのものですsetVisibility(int visibility)

int changed = mViewFlags ^ old;
if (changed == 0) {
    return;
}

この後、同じメソッドで と が呼び出されますrequestLayout()invalidate()

だから私はノーと言うだろうそれはそうではありません

于 2013-09-30T15:48:35.147 に答える