From: Julia Reynolds Date: Wed, 10 Jan 2018 17:53:40 +0000 (-0500) Subject: Volume dialog redesign X-Git-Tag: android-x86-9.0-r1~259^2~50^2 X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=0a22856a2acb3e8a3019ae6e658ddd3b3e6a1fc9;p=android-x86%2Fframeworks-base.git Volume dialog redesign Bug: 63096355 Test: manual, change volume with buttons and by touching the slider in each orientation Change-Id: I949425ca09c98f8826da5e29a2a479a74acdcf34 --- diff --git a/packages/SystemUI/res/layout/volume_dialog.xml b/packages/SystemUI/res/layout/volume_dialog.xml index f0d23469a49a..748c9a5ec7ed 100644 --- a/packages/SystemUI/res/layout/volume_dialog.xml +++ b/packages/SystemUI/res/layout/volume_dialog.xml @@ -17,130 +17,76 @@ xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" + android:background="@android:color/transparent" android:theme="@style/qs_theme" android:clipChildren="false" > - - - + android:paddingTop="12dp" + android:paddingBottom="12dp" + android:background="@drawable/rounded_bg_full" + android:orientation="horizontal" > - - - + + android:id="@+id/footer" + android:layout_width="@dimen/volume_dialog_panel_width" + android:layout_height="@dimen/volume_dialog_panel_width" + android:clipChildren="false" + android:clipToPadding="false" + android:layout_marginTop="6dp" + android:layout_marginBottom="6dp" + android:layout_below="@id/volume_dialog_rows" + android:background="@drawable/rounded_bg_full" + android:gravity="center" + android:orientation="vertical" > + - - - - - - - - - - - + android:layout_centerVertical="true" + android:textColor="?android:attr/colorControlNormal" + android:textAppearance="?android:attr/textAppearanceSmall" /> - - - + + + + + \ No newline at end of file diff --git a/packages/SystemUI/res/layout/volume_dialog_row.xml b/packages/SystemUI/res/layout/volume_dialog_row.xml index bf76e78c94a2..3590b768c91b 100644 --- a/packages/SystemUI/res/layout/volume_dialog_row.xml +++ b/packages/SystemUI/res/layout/volume_dialog_row.xml @@ -15,48 +15,70 @@ --> - - - + android:gravity="center" + android:padding="10dp"> + + - - + android:id="@+id/output_chooser" + style="@style/VolumeButtons" + android:background="?android:selectableItemBackgroundBorderless" + android:layout_width="@dimen/volume_button_size" + android:layout_height="wrap_content" + android:layout_centerVertical="true" + android:src="@drawable/ic_volume_expand_animation" + android:soundEffectsEnabled="false" /> + + + - + \ No newline at end of file diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml index a510c4a6c503..178c1c0ebf8b 100644 --- a/packages/SystemUI/res/values/dimens.xml +++ b/packages/SystemUI/res/values/dimens.xml @@ -264,7 +264,7 @@ @dimen/notification_panel_width - 315dp + 120dp 0x31 diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogComponent.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogComponent.java index bc98140f5af5..efa8386802e2 100644 --- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogComponent.java +++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogComponent.java @@ -52,7 +52,7 @@ public class VolumeDialogComponent implements VolumeComponent, TunerService.Tuna public static final String VOLUME_UP_SILENT = "sysui_volume_up_silent"; public static final String VOLUME_SILENT_DO_NOT_DISTURB = "sysui_do_not_disturb"; - public static final boolean DEFAULT_VOLUME_DOWN_TO_ENTER_SILENT = true; + public static final boolean DEFAULT_VOLUME_DOWN_TO_ENTER_SILENT = false; public static final boolean DEFAULT_VOLUME_UP_TO_EXIT_SILENT = true; public static final boolean DEFAULT_DO_NOT_DISTURB_WHEN_SILENT = true; diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java index 7b91f1475ca2..5a19a7677649 100644 --- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java +++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java @@ -20,6 +20,7 @@ import static android.accessibilityservice.AccessibilityServiceInfo.FEEDBACK_ALL import static android.accessibilityservice.AccessibilityServiceInfo.FEEDBACK_GENERIC; import static com.android.systemui.volume.Events.DISMISS_REASON_OUTPUT_CHOOSER; +import static com.android.systemui.volume.Events.DISMISS_REASON_SETTINGS_CLICKED; import static com.android.systemui.volume.Events.DISMISS_REASON_TOUCH_OUTSIDE; import android.accessibilityservice.AccessibilityServiceInfo; @@ -30,14 +31,13 @@ import android.app.Dialog; import android.app.KeyguardManager; import android.content.Context; import android.content.DialogInterface; +import android.content.Intent; import android.content.pm.PackageManager; import android.content.res.ColorStateList; import android.content.res.Resources; import android.graphics.Color; import android.graphics.Rect; -import android.graphics.drawable.AnimatedVectorDrawable; import android.graphics.drawable.ColorDrawable; -import android.graphics.drawable.Drawable; import android.media.AudioManager; import android.media.AudioSystem; import android.os.Debug; @@ -45,9 +45,8 @@ import android.os.Handler; import android.os.Looper; import android.os.Message; import android.os.SystemClock; +import android.provider.Settings; import android.provider.Settings.Global; -import android.transition.AutoTransition; -import android.transition.TransitionManager; import android.util.Log; import android.util.Slog; import android.util.SparseBooleanArray; @@ -72,7 +71,6 @@ import android.widget.TextView; import com.android.settingslib.Utils; import com.android.systemui.Dependency; -import com.android.systemui.Interpolators; import com.android.systemui.R; import com.android.systemui.plugins.VolumeDialog; import com.android.systemui.plugins.VolumeDialogController; @@ -104,7 +102,6 @@ public class VolumeDialogImpl implements VolumeDialog { private CustomDialog mDialog; private ViewGroup mDialogView; private ViewGroup mDialogRowsView; - private ImageButton mExpandButton; private ImageButton mRingerIcon; private ImageButton mOutputChooser; private TextView mRingerStatus; @@ -120,8 +117,6 @@ public class VolumeDialogImpl implements VolumeDialog { private final ColorStateList mInactiveSliderTint; private boolean mShowing; - private boolean mExpanded; - private boolean mExpandButtonAnimationRunning; private boolean mShowA11yStream; private int mActiveStream; @@ -182,11 +177,11 @@ public class VolumeDialogImpl implements VolumeDialog { mDialog.setContentView(R.layout.volume_dialog); mDialog.setOnShowListener(dialog -> { - mDialogView.setTranslationY(-mDialogView.getHeight()); + mDialogView.setTranslationX(mDialogView.getWidth() / 2); mDialogView.setAlpha(0); mDialogView.animate() .alpha(1) - .translationY(0) + .translationX(0) .setDuration(300) .setInterpolator(new SystemUIInterpolators.LogDecelerateInterpolator()) .withEndAction(() -> { @@ -205,20 +200,10 @@ public class VolumeDialogImpl implements VolumeDialog { VolumeUiLayout hardwareLayout = VolumeUiLayout.get(mDialogView); hardwareLayout.setOutsideTouchListener(view -> dismiss(DISMISS_REASON_TOUCH_OUTSIDE)); - ViewGroup dialogContentView = mDialog.findViewById(R.id.volume_dialog_content); - mDialogRowsView = dialogContentView.findViewById(R.id.volume_dialog_rows); + mDialogRowsView = mDialog.findViewById(R.id.volume_dialog_rows); mRingerIcon = mDialog.findViewById(R.id.ringer_icon); mRingerStatus = mDialog.findViewById(R.id.ringer_status); - mExpanded = false; - mExpandButton = mDialogView.findViewById(R.id.volume_expand_button); - mExpandButton.setOnClickListener(mClickExpand); - mExpandButton.setVisibility( - AudioSystem.isSingleVolume(mContext) ? View.GONE : View.VISIBLE); - - mOutputChooser = mDialogView.findViewById(R.id.output_chooser); - mOutputChooser.setOnClickListener(mClickOutputChooser); - if (mRows.isEmpty()) { addRow(AudioManager.STREAM_MUSIC, R.drawable.ic_volume_media, R.drawable.ic_volume_media_mute, true, true); @@ -239,6 +224,10 @@ public class VolumeDialogImpl implements VolumeDialog { } else { addExistingRows(); } + + mOutputChooser = mDialogView.findViewById(R.id.output_chooser); + mOutputChooser.setOnClickListener(mClickOutputChooser); + updateRowsH(getActiveRow()); initRingerH(); } @@ -273,11 +262,9 @@ public class VolumeDialogImpl implements VolumeDialog { VolumeRow row = new VolumeRow(); initRow(row, stream, iconRes, iconMuteRes, important, defaultStream); int rowSize; - int viewSize; - if (mShowA11yStream && dynamic && (rowSize = mRows.size()) > 1 - && (viewSize = mDialogRowsView.getChildCount()) > 1) { - // A11y Stream should be the last in the list - mDialogRowsView.addView(row.view, viewSize - 2); + if (mShowA11yStream && dynamic && (rowSize = mRows.size()) > 1) { + // A11y Stream should be the first in the list, so it's shown to start of other rows + mDialogRowsView.addView(row.view, 0); mRows.add(rowSize - 2, row); } else { mDialogRowsView.addView(row.view); @@ -315,7 +302,6 @@ public class VolumeDialogImpl implements VolumeDialog { public void dump(PrintWriter writer) { writer.println(VolumeDialogImpl.class.getSimpleName() + " state:"); writer.print(" mShowing: "); writer.println(mShowing); - writer.print(" mExpanded: "); writer.println(mExpanded); writer.print(" mActiveStream: "); writer.println(mActiveStream); writer.print(" mDynamic: "); writer.println(mDynamic); writer.print(" mAutomute: "); writer.println(mAutomute); @@ -432,6 +418,13 @@ public class VolumeDialogImpl implements VolumeDialog { } updateRingerH(); }); + mRingerIcon.setOnLongClickListener(v -> { + Intent intent = new Intent(Settings.ACTION_SOUND_SETTINGS); + intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + dismissH(DISMISS_REASON_SETTINGS_CLICKED); + mContext.startActivity(intent); + return true; + }); updateRingerH(); } @@ -468,7 +461,6 @@ public class VolumeDialogImpl implements VolumeDialog { private int computeTimeoutH() { if (mAccessibility.mFeedbackEnabled) return 20000; if (mHovering) return 16000; - if (mExpanded) return 5000; if (mSafetyWarning != null) return 5000; return 3000; } @@ -480,13 +472,11 @@ public class VolumeDialogImpl implements VolumeDialog { mDialogView.animate().cancel(); mShowing = false; - updateExpandedH(false /* expanding */, true /* dismissing */); - - mDialogView.setTranslationY(0); + mDialogView.setTranslationX(0); mDialogView.setAlpha(1); mDialogView.animate() .alpha(0) - .translationY(-mDialogView.getHeight()) + .translationX(mDialogView.getWidth() / 2) .setDuration(250) .setInterpolator(new SystemUIInterpolators.LogAccelerateInterpolator()) .withEndAction(() -> mHandler.postDelayed(() -> { @@ -514,67 +504,6 @@ public class VolumeDialogImpl implements VolumeDialog { } } - private void updateExpandedH(final boolean expanded, final boolean dismissing) { - if (D.BUG) Log.d(TAG, "updateExpandedH " + expanded); - - if (mExpanded == expanded) return; - mExpanded = expanded; - mExpandButtonAnimationRunning = isAttached(); - updateExpandButtonH(); - TransitionManager.endTransitions(mDialogView); - final VolumeRow activeRow = getActiveRow(); - if (!dismissing) { - mWindow.setLayout(mWindow.getAttributes().width, ViewGroup.LayoutParams.MATCH_PARENT); - TransitionManager.beginDelayedTransition(mDialogView, getTransition()); - } - updateRowsH(activeRow); - rescheduleTimeoutH(); - } - - private AutoTransition getTransition() { - AutoTransition transition = new AutoTransition(); - transition.setDuration(300); - transition.setInterpolator(Interpolators.LINEAR_OUT_SLOW_IN); - return transition; - } - - private void updateExpandButtonH() { - if (D.BUG) Log.d(TAG, "updateExpandButtonH"); - - mExpandButton.setClickable(!mExpandButtonAnimationRunning); - if (!(mExpandButtonAnimationRunning && isAttached())) { - final int res = mExpanded ? R.drawable.ic_volume_collapse_animation - : R.drawable.ic_volume_expand_animation; - if (hasTouchFeature()) { - mExpandButton.setImageResource(res); - } else { - // if there is no touch feature, show the volume ringer instead - mExpandButton.setImageResource(R.drawable.ic_volume_ringer); - mExpandButton.setBackgroundResource(0); // remove gray background emphasis - } - mExpandButton.setContentDescription(mContext.getString(mExpanded ? - R.string.accessibility_volume_collapse : R.string.accessibility_volume_expand)); - } - if (mExpandButtonAnimationRunning) { - final Drawable d = mExpandButton.getDrawable(); - if (d instanceof AnimatedVectorDrawable) { - // workaround to reset drawable - final AnimatedVectorDrawable avd = (AnimatedVectorDrawable) d.getConstantState() - .newDrawable(); - mExpandButton.setImageDrawable(avd); - avd.start(); - mHandler.postDelayed(new Runnable() { - @Override - public void run() { - mExpandButtonAnimationRunning = false; - updateExpandButtonH(); - rescheduleTimeoutH(); - } - }, 300); - } - } - } - private boolean isAttached() { return mDialogView != null && mDialogView.isAttachedToWindow(); } @@ -597,7 +526,7 @@ public class VolumeDialogImpl implements VolumeDialog { return true; } - return row.defaultStream || isActive || (mExpanded && row.important); + return row.defaultStream || isActive; } private void updateRowsH(final VolumeRow activeRow) { @@ -954,16 +883,6 @@ public class VolumeDialogImpl implements VolumeDialog { } } - private final OnClickListener mClickExpand = new OnClickListener() { - @Override - public void onClick(View v) { - mExpandButton.animate().cancel(); - final boolean newExpand = !mExpanded; - Events.writeEvent(mContext, Events.EVENT_EXPAND, newExpand); - updateExpandedH(newExpand, false /* dismissing */); - } - }; - private final OnClickListener mClickOutputChooser = new OnClickListener() { @Override public void onClick(View v) { diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeUiLayout.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeUiLayout.java index 49ac9b6b7ffe..1c9cbc139504 100644 --- a/packages/SystemUI/src/com/android/systemui/volume/VolumeUiLayout.java +++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeUiLayout.java @@ -14,15 +14,37 @@ package com.android.systemui.volume; +import static com.android.systemui.util.leak.RotationUtils.ROTATION_LANDSCAPE; +import static com.android.systemui.util.leak.RotationUtils.ROTATION_NONE; +import static com.android.systemui.util.leak.RotationUtils.ROTATION_SEASCAPE; + +import android.animation.Animator; +import android.animation.AnimatorListenerAdapter; +import android.animation.AnimatorSet; +import android.animation.ObjectAnimator; import android.content.Context; +import android.content.res.Configuration; import android.util.AttributeSet; +import android.view.Gravity; import android.view.View; +import android.view.ViewGroup; import android.view.ViewOutlineProvider; import android.view.ViewTreeObserver; import android.widget.FrameLayout; +import android.widget.LinearLayout; +import android.widget.SeekBar; + +import com.android.systemui.R; +import com.android.systemui.util.leak.RotationUtils; public class VolumeUiLayout extends FrameLayout { + private View mChild; + private int mOldHeight; + private boolean mAnimating; + private AnimatorSet mAnimation; + private boolean mHasOutsideTouch; + private int mRotation = ROTATION_NONE; public VolumeUiLayout(Context context, AttributeSet attrs) { super(context, attrs); } @@ -40,11 +62,245 @@ public class VolumeUiLayout extends FrameLayout { } @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + super.onMeasure(widthMeasureSpec, heightMeasureSpec); + if (mChild == null) { + if (getChildCount() != 0) { + mChild = getChildAt(0); + mOldHeight = mChild.getMeasuredHeight(); + updateRotation(); + } else { + return; + } + } + int newHeight = mChild.getMeasuredHeight(); + if (newHeight != mOldHeight) { + animateChild(mOldHeight, newHeight); + } + } + + @Override + protected void onConfigurationChanged(Configuration newConfig) { + super.onConfigurationChanged(newConfig); + updateRotation(); + } + + private void updateRotation() { + int rotation = RotationUtils.getRotation(getContext()); + if (rotation != mRotation) { + rotate(mRotation, rotation); + mRotation = rotation; + } + } + + private void rotate(View view, int from, int to, boolean swapDimens) { + if (from != ROTATION_NONE && to != ROTATION_NONE) { + // Rather than handling this confusing case, just do 2 rotations. + rotate(view, from, ROTATION_NONE, swapDimens); + rotate(view, ROTATION_NONE, to, swapDimens); + return; + } + if (from == ROTATION_LANDSCAPE || to == ROTATION_SEASCAPE) { + rotateRight(view); + } else { + rotateLeft(view); + } + if (to != ROTATION_NONE) { + if (swapDimens && view instanceof LinearLayout) { + LinearLayout linearLayout = (LinearLayout) view; + linearLayout.setOrientation(LinearLayout.HORIZONTAL); + swapDimens(view); + } + } else { + if (swapDimens && view instanceof LinearLayout) { + LinearLayout linearLayout = (LinearLayout) view; + linearLayout.setOrientation(LinearLayout.VERTICAL); + swapDimens(view); + } + } + } + + private void rotate(int from, int to) { + View footer = mChild.findViewById(R.id.footer); + rotate(footer, from, to, false); + rotate(this, from, to, true); + rotate(mChild, from, to, true); + ViewGroup rows = mChild.findViewById(R.id.volume_dialog_rows); + rotate(rows, from, to, true); + int rowCount = rows.getChildCount(); + for (int i = 0; i < rowCount; i++) { + View child = rows.getChildAt(i); + if (to == ROTATION_SEASCAPE) { + rotateSeekBars(to, 0); + } else if (to == ROTATION_LANDSCAPE) { + rotateSeekBars(to, 180); + } else { + rotateSeekBars(to, 270); + } + rotate(child, from, to, true); + } + } + + private void swapDimens(View v) { + if (v == null) { + return; + } + ViewGroup.LayoutParams params = v.getLayoutParams(); + int h = params.width; + params.width = params.height; + params.height = h; + v.setLayoutParams(params); + } + + private void rotateSeekBars(int to, int rotation) { + SeekBar seekbar = mChild.findViewById(R.id.volume_row_slider); + if (seekbar != null) { + seekbar.setRotation((float) rotation); + } + + View parent = mChild.findViewById(R.id.volume_row_slider_frame); + swapDimens(parent); + ViewGroup.LayoutParams params = seekbar.getLayoutParams(); + ViewGroup.LayoutParams parentParams = parent.getLayoutParams(); + if (to != ROTATION_NONE) { + params.height = parentParams.height; + params.width = parentParams.width; + } else { + params.height = parentParams.width; + params.width = parentParams.height; + } + seekbar.setLayoutParams(params); + } + + private int rotateGravityRight(int gravity) { + int retGravity = 0; + int layoutDirection = getLayoutDirection(); + final int absoluteGravity = Gravity.getAbsoluteGravity(gravity, layoutDirection); + final int verticalGravity = gravity & Gravity.VERTICAL_GRAVITY_MASK; + + switch (absoluteGravity & Gravity.HORIZONTAL_GRAVITY_MASK) { + case Gravity.CENTER_HORIZONTAL: + retGravity |= Gravity.CENTER_VERTICAL; + break; + case Gravity.RIGHT: + retGravity |= Gravity.BOTTOM; + break; + case Gravity.LEFT: + default: + retGravity |= Gravity.TOP; + break; + } + + switch (verticalGravity) { + case Gravity.CENTER_VERTICAL: + retGravity |= Gravity.CENTER_HORIZONTAL; + break; + case Gravity.BOTTOM: + retGravity |= Gravity.LEFT; + break; + case Gravity.TOP: + default: + retGravity |= Gravity.RIGHT; + break; + } + return retGravity; + } + + private int rotateGravityLeft(int gravity) { + if (gravity == -1) { + gravity = Gravity.TOP | Gravity.START; + } + int retGravity = 0; + int layoutDirection = getLayoutDirection(); + final int absoluteGravity = Gravity.getAbsoluteGravity(gravity, layoutDirection); + final int verticalGravity = gravity & Gravity.VERTICAL_GRAVITY_MASK; + + switch (absoluteGravity & Gravity.HORIZONTAL_GRAVITY_MASK) { + case Gravity.CENTER_HORIZONTAL: + retGravity |= Gravity.CENTER_VERTICAL; + break; + case Gravity.RIGHT: + retGravity |= Gravity.TOP; + break; + case Gravity.LEFT: + default: + retGravity |= Gravity.BOTTOM; + break; + } + + switch (verticalGravity) { + case Gravity.CENTER_VERTICAL: + retGravity |= Gravity.CENTER_HORIZONTAL; + break; + case Gravity.BOTTOM: + retGravity |= Gravity.RIGHT; + break; + case Gravity.TOP: + default: + retGravity |= Gravity.LEFT; + break; + } + return retGravity; + } + + private void rotateLeft(View v) { + if (v.getParent() instanceof FrameLayout) { + LayoutParams p = (LayoutParams) v.getLayoutParams(); + p.gravity = rotateGravityLeft(p.gravity); + } + + v.setPadding(v.getPaddingTop(), v.getPaddingRight(), v.getPaddingBottom(), + v.getPaddingLeft()); + MarginLayoutParams params = (MarginLayoutParams) v.getLayoutParams(); + params.setMargins(params.topMargin, params.rightMargin, params.bottomMargin, + params.leftMargin); + v.setLayoutParams(params); + } + + private void rotateRight(View v) { + if (v.getParent() instanceof FrameLayout) { + LayoutParams p = (LayoutParams) v.getLayoutParams(); + p.gravity = rotateGravityRight(p.gravity); + } + + v.setPadding(v.getPaddingBottom(), v.getPaddingLeft(), v.getPaddingTop(), + v.getPaddingRight()); + MarginLayoutParams params = (MarginLayoutParams) v.getLayoutParams(); + params.setMargins(params.bottomMargin, params.leftMargin, params.topMargin, + params.rightMargin); + v.setLayoutParams(params); + } + + private void animateChild(int oldHeight, int newHeight) { + if (true) return; + if (mAnimating) { + mAnimation.cancel(); + } + mAnimating = true; + mAnimation = new AnimatorSet(); + mAnimation.addListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(Animator animation) { + mAnimating = false; + } + }); + int fromTop = mChild.getTop(); + int fromBottom = mChild.getBottom(); + int toTop = fromTop - ((newHeight - oldHeight) / 2); + int toBottom = fromBottom + ((newHeight - oldHeight) / 2); + ObjectAnimator top = ObjectAnimator.ofInt(mChild, "top", fromTop, toTop); + mAnimation.playTogether(top, + ObjectAnimator.ofInt(mChild, "bottom", fromBottom, toBottom)); + } + + + @Override public ViewOutlineProvider getOutlineProvider() { return super.getOutlineProvider(); } public void setOutsideTouchListener(OnClickListener onClickListener) { + mHasOutsideTouch = true; requestLayout(); setOnClickListener(onClickListener); setClickable(true); @@ -60,7 +316,14 @@ public class VolumeUiLayout extends FrameLayout { } private final ViewTreeObserver.OnComputeInternalInsetsListener mInsetsListener = inoutInfo -> { + if (mHasOutsideTouch || (mChild == null)) { + inoutInfo.setTouchableInsets( + ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_FRAME); + return; + } inoutInfo.setTouchableInsets( - ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_FRAME); + ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_CONTENT); + inoutInfo.contentInsets.set(mChild.getLeft(), mChild.getTop(), + 0, getBottom() - mChild.getBottom()); }; }