AdapterView类mBlockLayoutRequests、mInLayout变量简介

之前在写Spinner和ListView的文章中有提到过mBlockLayoutRequests、mInLayout这两个变量,现在就来简单说说这两个变量的作用吧。
先来看看源码注释吧

/**
 * Indicates that this view is currently being laid out.
 * 标志视图是否正在进行布局
 */
 boolean mInLayout = false;
/**
 * When set to true, calls to requestLayout() will not propagate up the parent hierarchy.
 * This is used to layout the children during a layout pass.
 * 当设置为true时,调用requestLayout()方法就不会传递到父布局
 * 用于布局过程中
 */
 boolean mBlockLayoutRequests = false;

AdapterView中只有在执行ItemSelected回调的时候用到:

void selectionChanged() {
    // We're about to post or run the selection notifier, so we don't need
    // a pending notifier.
    mPendingSelectionNotifier = null;

    if (mOnItemSelectedListener != null
            || AccessibilityManager.getInstance(mContext).isEnabled()) {
        // 如果mInLayout或mBlockLayoutRequests使能,那么通过消息机制进行回调
        // 否则直接进行回调
        if (mInLayout || mBlockLayoutRequests) {
            // If we are in a layout traversal, defer notification
            // by posting. This ensures that the view tree is
            // in a consistent state and is able to accommodate
            // new layout or invalidate requests.
            if (mSelectionNotifier == null) {
                mSelectionNotifier = new SelectionNotifier();
            } else {
                removeCallbacks(mSelectionNotifier);
            }
            post(mSelectionNotifier);
        } else {
            dispatchOnItemSelected();
        }
    }
}

那ListView和Spinner是如何使用这两个变量的呢?

Spinner

其实Spinner并没有使用mInLayout,只是在onLayout方法中使能了mInLayout:

@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
    super.onLayout(changed, l, t, r, b);
    mInLayout = true;
    layout(0, false);
    mInLayout = false;
}

mBlockLayoutRequests也只有在AbsSpinner中使用过一次,就是在requestLayout方法中:

@Override
public void requestLayout() {
    if (!mBlockLayoutRequests) {
        super.requestLayout();
    }
}

然后在某些地方使能了改变量而已。

ListView

ListView也没有使用mInLayout和mBlockLayoutRequests,只是在两个地方分别使能了这两个变量:

boolean arrowScroll(int direction) {
    try {
        mInLayout = true;
        final boolean handled = arrowScrollImpl(direction);
        if (handled) {
            playSoundEffect(SoundEffectConstants.getContantForFocusDirection(direction));
        }
        return handled;
    } finally {
        mInLayout = false;
    }
}
@Override
protected void layoutChildren() {
    final boolean blockLayoutRequests = mBlockLayoutRequests;
    if (blockLayoutRequests) {
        return;
    }
    mBlockLayoutRequests = true;
    try{
        // ...
    }finally{
        if (!blockLayoutRequests) {
            mBlockLayoutRequests = false;
        }
    }
}

AbsListView中在两个地方使用了:

@Override
public void requestLayout() {
    if (!mBlockLayoutRequests && !mInLayout) {
        super.requestLayout();
    }
}
public void setItemChecked(int position, boolean value) {

    // ...

    // 在布局过程中屏蔽Checked状态改变所引起的DataChanged事件
    if (!mInLayout && !mBlockLayoutRequests) {
        mDataChanged = true;
        rememberSyncState();
        requestLayout();
    }
}

然后还有几个地方使能了这两个变量。

尾声

到这里,其实我们已经知道了这两个变量作用,以及在Spinner和ListView这两个类中的应用场景中的一些区别。其实还可以深入的,比如ListView在哪些地方使能了这两个变量,以及为什么?人懒,就先这样吧。。。

以上。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值