1 /*
2  * Copyright 2012 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 
17 package com.example.android.animationsdemo;
18 
19 import android.content.Context;
20 import android.content.res.TypedArray;
21 import android.graphics.Canvas;
22 import android.graphics.Rect;
23 import android.graphics.drawable.Drawable;
24 import android.util.AttributeSet;
25 import android.widget.ImageButton;
26 
27 /**
28  * An image button that uses a blue highlight (@link android.R.attr.selectableItemBackground} to
29  * indicate pressed and focused states.
30  */
31 public class TouchHighlightImageButton extends ImageButton {
32     /**
33      * The highlight drawable. This generally a {@link android.graphics.drawable.StateListDrawable}
34      * that's transparent in the default state, and contains a semi-transparent overlay
35      * for the focused and pressed states.
36      */
37     private Drawable mForegroundDrawable;
38 
39     /**
40      * The cached bounds of the view.
41      */
42     private Rect mCachedBounds = new Rect();
43 
TouchHighlightImageButton(Context context)44     public TouchHighlightImageButton(Context context) {
45         super(context);
46         init();
47     }
48 
TouchHighlightImageButton(Context context, AttributeSet attrs)49     public TouchHighlightImageButton(Context context, AttributeSet attrs) {
50         super(context, attrs);
51         init();
52     }
53 
TouchHighlightImageButton(Context context, AttributeSet attrs, int defStyle)54     public TouchHighlightImageButton(Context context, AttributeSet attrs, int defStyle) {
55         super(context, attrs, defStyle);
56         init();
57     }
58 
59     /**
60      * General view initialization used common to all constructors of the view.
61      */
init()62     private void init() {
63         // Reset default ImageButton background and padding.
64         setBackgroundColor(0);
65         setPadding(0, 0, 0, 0);
66 
67         // Retrieve the drawable resource assigned to the android.R.attr.selectableItemBackground
68         // theme attribute from the current theme.
69         TypedArray a = getContext()
70                 .obtainStyledAttributes(new int[]{android.R.attr.selectableItemBackground});
71         mForegroundDrawable = a.getDrawable(0);
72         mForegroundDrawable.setCallback(this);
73         a.recycle();
74     }
75 
76     @Override
drawableStateChanged()77     protected void drawableStateChanged() {
78         super.drawableStateChanged();
79 
80         // Update the state of the highlight drawable to match
81         // the state of the button.
82         if (mForegroundDrawable.isStateful()) {
83             mForegroundDrawable.setState(getDrawableState());
84         }
85 
86         // Trigger a redraw.
87         invalidate();
88     }
89 
90     @Override
onDraw(Canvas canvas)91     protected void onDraw(Canvas canvas) {
92         // First draw the image.
93         super.onDraw(canvas);
94 
95         // Then draw the highlight on top of it. If the button is neither focused
96         // nor pressed, the drawable will be transparent, so just the image
97         // will be drawn.
98         mForegroundDrawable.setBounds(mCachedBounds);
99         mForegroundDrawable.draw(canvas);
100     }
101 
102     @Override
onSizeChanged(int w, int h, int oldw, int oldh)103     protected void onSizeChanged(int w, int h, int oldw, int oldh) {
104         super.onSizeChanged(w, h, oldw, oldh);
105 
106         // Cache the view bounds.
107         mCachedBounds.set(0, 0, w, h);
108     }
109 }
110