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