12f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian/* 22f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian * Copyright (C) 2017 The Android Open Source Project 32f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian * 42f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian * Licensed under the Apache License, Version 2.0 (the "License"); 52f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian * you may not use this file except in compliance with the License. 62f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian * You may obtain a copy of the License at 72f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian * 82f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian * http://www.apache.org/licenses/LICENSE-2.0 92f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian * 102f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian * Unless required by applicable law or agreed to in writing, software 112f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian * distributed under the License is distributed on an "AS IS" BASIS, 122f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 132f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian * See the License for the specific language governing permissions and 142f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian * limitations under the License 152f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian */ 162f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian 172f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanianpackage com.android.dialershared.bubble; 182f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian 192f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanianimport android.content.Context; 202f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanianimport android.support.v4.view.AccessibilityDelegateCompat; 212f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanianimport android.support.v4.view.ViewCompat; 222f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanianimport android.support.v4.view.accessibility.AccessibilityEventCompat; 232f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanianimport android.support.v4.view.accessibility.AccessibilityNodeInfoCompat; 242f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanianimport android.support.v7.widget.AppCompatImageButton; 252f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanianimport android.util.AttributeSet; 262f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanianimport android.view.View; 272f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanianimport android.view.accessibility.AccessibilityEvent; 282f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanianimport android.widget.Checkable; 292f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian 302f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian/** 312f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian * An {@link android.widget.ImageButton ImageButton} that implements {@link Checkable} and 322f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian * propagates the checkable state 332f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian */ 342f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanianpublic class CheckableImageButton extends AppCompatImageButton implements Checkable { 352f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian 362f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian // Copied without modification from AppCompat library 372f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian 382f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian private static final int[] DRAWABLE_STATE_CHECKED = new int[] {android.R.attr.state_checked}; 392f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian 402f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian private boolean mChecked; 412f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian 422f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian public CheckableImageButton(Context context) { 432f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian this(context, null); 442f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian } 452f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian 462f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian public CheckableImageButton(Context context, AttributeSet attrs) { 472f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian this(context, attrs, android.R.attr.imageButtonStyle); 482f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian } 492f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian 502f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian public CheckableImageButton(Context context, AttributeSet attrs, int defStyleAttr) { 512f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian super(context, attrs, defStyleAttr); 522f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian 532f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian ViewCompat.setAccessibilityDelegate( 542f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian this, 552f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian new AccessibilityDelegateCompat() { 562f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian @Override 572f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian public void onInitializeAccessibilityEvent(View host, AccessibilityEvent event) { 582f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian super.onInitializeAccessibilityEvent(host, event); 592f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian event.setChecked(isChecked()); 602f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian } 612f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian 622f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian @Override 632f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian public void onInitializeAccessibilityNodeInfo( 642f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian View host, AccessibilityNodeInfoCompat info) { 652f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian super.onInitializeAccessibilityNodeInfo(host, info); 662f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian info.setCheckable(true); 672f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian info.setChecked(isChecked()); 682f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian } 692f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian }); 702f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian } 712f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian 722f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian @Override 732f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian public void setChecked(boolean checked) { 742f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian if (mChecked != checked) { 752f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian mChecked = checked; 762f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian refreshDrawableState(); 772f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian sendAccessibilityEvent(AccessibilityEventCompat.TYPE_WINDOW_CONTENT_CHANGED); 782f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian } 792f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian } 802f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian 812f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian @Override 822f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian public boolean isChecked() { 832f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian return mChecked; 842f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian } 852f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian 862f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian @Override 872f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian public void toggle() { 882f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian setChecked(!mChecked); 892f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian } 902f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian 912f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian @Override 922f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian public int[] onCreateDrawableState(int extraSpace) { 932f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian if (mChecked) { 942f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian return mergeDrawableStates( 952f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian super.onCreateDrawableState(extraSpace + DRAWABLE_STATE_CHECKED.length), 962f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian DRAWABLE_STATE_CHECKED); 972f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian } else { 982f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian return super.onCreateDrawableState(extraSpace); 992f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian } 1002f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian } 1012f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian} 102