View.setSelected()
/**
* Changes the selection state of this view. A view can be selected or not.
* 改变该视图的选择项状态。一个视图能被选中或者不被选中两种状态。
*
* Note that selection is not the same as focus. Views are typically
* selected in the context of an AdapterView like ListView or GridView;
* the selected view is the view that is highlighted.
*
* 选中和焦点是不同的。视图典型的内容选中是象ListView或者GridView一样。
* 选中的视图是高亮的。
*
* @param selected true if the view must be selected, false otherwise
*/
public void setSelected(boolean selected) {
//如果当前逻辑标志有 SELECTED 属性位,并且不等于将要设置的 SELECTED 的属性。
if (((mPrivateFlags & SELECTED) != 0) != selected) {
//清除逻辑标记位的 SELECTED 属性,或者 添加 SELECTED 属性。
mPrivateFlags = (mPrivateFlags & ~SELECTED) | (selected ? SELECTED : 0);
//如果设置后的属性为不选中,那么就重置按下状态。该函数内部仅仅是清除了PRESSED的标志位,并调用 removeLongPressCallback,清除长按的回调。
//注意:当视图正处于PRESSED状态时,我们主动又给该视图添加非SELECTED状态,那么该视图将会同时失去PRESSED状态,并忽略后续的长按消息处理。
if (!selected) resetPressedState();
//因为 SELECTED 属性也会造成视图的显示改变,所以需要重绘。
invalidate();
//重绘状态
refreshDrawableState();
//应用程序可以重载该该函数以便此刻进行的其他操作。
dispatchSetSelected(selected);
}
}
View.resetPressedState()
private void resetPressedState() {
//如果视图标记的 可视标记位 为 不显示,直接return掉。
if ((mViewFlags & ENABLED_MASK) == DISABLED) {
return;
}
//如果当前是按下的状态
if (isPressed()) {
//取消按下状态
setPressed(false);
//如果存在长按监听没有触发
if (!mHasPerformedLongPress) {
//删除长按回调
removeLongPressCallback();
}
}
}