CheckableImageButton.java revision 91ce7d2a476bd04fe525049a37a2f8b2824e9724
1/* 2 * Copyright (C) 2017 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License 15 */ 16 17package com.android.dialershared.bubble; 18 19import android.content.Context; 20import android.support.v4.view.AccessibilityDelegateCompat; 21import android.support.v4.view.ViewCompat; 22import android.support.v4.view.accessibility.AccessibilityEventCompat; 23import android.support.v4.view.accessibility.AccessibilityNodeInfoCompat; 24import android.support.v7.widget.AppCompatImageButton; 25import android.util.AttributeSet; 26import android.view.View; 27import android.view.accessibility.AccessibilityEvent; 28import android.widget.Checkable; 29 30/** 31 * An {@link android.widget.ImageButton ImageButton} that implements {@link Checkable} and 32 * propagates the checkable state 33 */ 34public class CheckableImageButton extends AppCompatImageButton implements Checkable { 35 36 // Copied without modification from AppCompat library 37 38 private static final int[] DRAWABLE_STATE_CHECKED = new int[] {android.R.attr.state_checked}; 39 40 private boolean mChecked; 41 42 public CheckableImageButton(Context context) { 43 this(context, null); 44 } 45 46 public CheckableImageButton(Context context, AttributeSet attrs) { 47 this(context, attrs, android.R.attr.imageButtonStyle); 48 } 49 50 public CheckableImageButton(Context context, AttributeSet attrs, int defStyleAttr) { 51 super(context, attrs, defStyleAttr); 52 53 ViewCompat.setAccessibilityDelegate( 54 this, 55 new AccessibilityDelegateCompat() { 56 @Override 57 public void onInitializeAccessibilityEvent(View host, AccessibilityEvent event) { 58 super.onInitializeAccessibilityEvent(host, event); 59 event.setChecked(isChecked()); 60 } 61 62 @Override 63 public void onInitializeAccessibilityNodeInfo( 64 View host, AccessibilityNodeInfoCompat info) { 65 super.onInitializeAccessibilityNodeInfo(host, info); 66 info.setCheckable(true); 67 info.setChecked(isChecked()); 68 } 69 }); 70 } 71 72 @Override 73 public void setChecked(boolean checked) { 74 if (mChecked != checked) { 75 mChecked = checked; 76 refreshDrawableState(); 77 sendAccessibilityEvent(AccessibilityEventCompat.TYPE_WINDOW_CONTENT_CHANGED); 78 } 79 } 80 81 @Override 82 public boolean isChecked() { 83 return mChecked; 84 } 85 86 @Override 87 public void toggle() { 88 setChecked(!mChecked); 89 } 90 91 @Override 92 public int[] onCreateDrawableState(int extraSpace) { 93 if (mChecked) { 94 return mergeDrawableStates( 95 super.onCreateDrawableState(extraSpace + DRAWABLE_STATE_CHECKED.length), 96 DRAWABLE_STATE_CHECKED); 97 } else { 98 return super.onCreateDrawableState(extraSpace); 99 } 100 } 101} 102