Android: дочернее представление делится нажатым состоянием из родительского представления в Jelly Bean

Комментарий к коду: 1. Атрибут RelativeLayout Clickable имеет значение true, для дочернего представления которого атрибут Clickable имеет значение false. 2. Нет атрибута duplicateParentState, другими словами, duplicateParentState имеет значение false. 3. Дочерним представлением является TextView, textColor которого является селектором цвета, поэтому он может проверять нажатое состояние.

Поведение: до уровня 16, при нажатии RelativeLayout, нажатое состояние не передается его представлению chlid. Однако на уровне 16 или позже, это возможно.

Причина: setPressed ------>dispatchSetPressed ------>передать нажатое состояние для просмотра детьми ----->childView.setPressed

View.java onTouchEvent на уровне 15,

case MotionEvent.ACTION_DOWN:
                mHasPerformedLongPress = false;

                if (performButtonActionOnTouchDown(event)) {
                    break;
                }

                // Walk up the hierarchy to determine if we're inside a scrolling container.
                boolean isInScrollingContainer = isInScrollingContainer();

                // For views inside a scrolling container, delay the pressed feedback for
                // a short period in case this is a scroll.
                if (isInScrollingContainer) {
                    mPrivateFlags |= PREPRESSED;
                    if (mPendingCheckForTap == null) {
                        mPendingCheckForTap = new CheckForTap();
                    }
                    postDelayed(mPendingCheckForTap, ViewConfiguration.getTapTimeout());
                } else {
                    // Not inside a scrolling container, so show the feedback right away
                    mPrivateFlags |= PRESSED; //comment by bran
                    refreshDrawableState();
                    checkForLongClick(0);
                }
                break;

View.java onTouchEvent на уровне 16,

case MotionEvent.ACTION_DOWN:
                 mHasPerformedLongPress = false;

                 if (performButtonActionOnTouchDown(event)) {
                     break;
                 }

                 // Walk up the hierarchy to determine if we're inside a scrolling container.
                 boolean isInScrollingContainer = isInScrollingContainer();

                 // For views inside a scrolling container, delay the pressed feedback for
                 // a short period in case this is a scroll.
                 if (isInScrollingContainer) {
                     mPrivateFlags |= PREPRESSED;
                     if (mPendingCheckForTap == null) {
                         mPendingCheckForTap = new CheckForTap();
                     }
                     postDelayed(mPendingCheckForTap, ViewConfiguration.getTapTimeout());
                 } else {
                     // Not inside a scrolling container, so show the feedback right away
                     setPressed(true); //comment by bran
                     checkForLongClick(0);
                 }
                 break;

Обратите внимание на строку кода от Брана, они разные. setPressed (истина); это не только mPrivateFlags | = PRESSED; и refreshDrawableState (); , но отправка SetPressed.

Если какой-либо разработчик Android SDK в Google, вы бы хотели рассказать мне, почему вы меняете mPrivateFlags | = PRESSED на setPressed (true) ;.