blob: d7b0f8fc553bedda1314f73d7f43461863b306aa [file] [log] [blame]
Justin Klaassen9d33cdc2016-02-21 14:16:14 -08001/*
2 * Copyright (C) 2016 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.calculator2;
18
19import android.content.Context;
20import android.transition.Fade;
21import android.transition.Transition;
22import android.transition.TransitionManager;
23import android.util.AttributeSet;
24import android.view.GestureDetector;
25import android.view.MotionEvent;
26import android.view.View;
27import android.view.accessibility.AccessibilityManager;
Annie Chin26e159e2016-05-18 15:17:14 -070028import android.widget.LinearLayout;
Justin Klaassen9d33cdc2016-02-21 14:16:14 -080029import android.widget.Toolbar;
30
Annie Chin26e159e2016-05-18 15:17:14 -070031public class CalculatorDisplay extends LinearLayout
Justin Klaassen9d33cdc2016-02-21 14:16:14 -080032 implements AccessibilityManager.AccessibilityStateChangeListener {
33
34 /**
35 * The duration in milliseconds after which to hide the toolbar.
36 */
37 private static final long AUTO_HIDE_DELAY_MILLIS = 3000L;
38
39 /**
40 * The duration in milliseconds to fade in/out the toolbar.
41 */
42 private static final long FADE_DURATION = 200L;
43
44 private final Runnable mHideToolbarRunnable = new Runnable() {
45 @Override
46 public void run() {
47 // Remove any duplicate callbacks to hide the toolbar.
48 removeCallbacks(this);
49
50 // Only animate if we have been laid out at least once.
51 if (isLaidOut()) {
52 TransitionManager.beginDelayedTransition(CalculatorDisplay.this, mTransition);
53 }
54 mToolbar.setVisibility(View.INVISIBLE);
55 }
56 };
57
58 private final AccessibilityManager mAccessibilityManager;
59 private final GestureDetector mTapDetector;
60
61 private Toolbar mToolbar;
62 private Transition mTransition;
63
64 private boolean mForceToolbarVisible;
65
66 public CalculatorDisplay(Context context) {
67 this(context, null /* attrs */);
68 }
69
70 public CalculatorDisplay(Context context, AttributeSet attrs) {
71 this(context, attrs, 0 /* defStyleAttr */);
72 }
73
74 public CalculatorDisplay(Context context, AttributeSet attrs, int defStyleAttr) {
75 super(context, attrs, defStyleAttr);
76
77 mAccessibilityManager =
78 (AccessibilityManager) context.getSystemService(Context.ACCESSIBILITY_SERVICE);
79
80 mTapDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() {
81 @Override
82 public boolean onDown(MotionEvent e) {
83 // Remove callbacks to hide the toolbar.
84 removeCallbacks(mHideToolbarRunnable);
85
86 return true;
87 }
88
89 @Override
90 public boolean onSingleTapConfirmed(MotionEvent e) {
91 if (mToolbar.getVisibility() != View.VISIBLE) {
92 showToolbar();
93 } else {
94 hideToolbar();
95 }
96
97 return true;
98 }
99 });
100 mTapDetector.setIsLongpressEnabled(false);
101 }
102
103 @Override
104 protected void onFinishInflate() {
105 super.onFinishInflate();
106
107 mToolbar = (Toolbar) findViewById(R.id.toolbar);
108 mTransition = new Fade()
109 .setDuration(FADE_DURATION)
110 .addTarget(mToolbar);
111 }
112
113 @Override
114 protected void onAttachedToWindow() {
115 super.onAttachedToWindow();
116 mAccessibilityManager.addAccessibilityStateChangeListener(this);
117 }
118
119 @Override
120 protected void onDetachedFromWindow() {
121 super.onDetachedFromWindow();
122 mAccessibilityManager.removeAccessibilityStateChangeListener(this);
123 }
124
125 @Override
126 public void onAccessibilityStateChanged(boolean enabled) {
127 // Always show the toolbar whenever accessibility is enabled.
128 showToolbar();
129 }
130
131 @Override
132 public boolean onInterceptTouchEvent(MotionEvent event) {
133 mTapDetector.onTouchEvent(event);
134 return super.onInterceptTouchEvent(event);
135 }
136
137 @Override
138 public boolean onTouchEvent(MotionEvent event) {
139 return mTapDetector.onTouchEvent(event) || super.onTouchEvent(event);
140 }
141
142 /**
143 * Returns {@code true} if the toolbar should remain visible.
144 */
145 public boolean getForceToolbarVisible() {
146 return mForceToolbarVisible || mAccessibilityManager.isEnabled();
147 }
148
149 /**
150 * Forces the toolbar to remain visible.
151 *
152 * @param forceToolbarVisible {@code true} to keep the toolbar visible
153 */
154 public void setForceToolbarVisible(boolean forceToolbarVisible) {
155 mForceToolbarVisible = forceToolbarVisible;
156 showToolbar();
157 }
158
159 /**
160 * Shows the toolbar.
161 */
162 public void showToolbar() {
163 // Only animate if we have been laid out at least once.
164 if (isLaidOut()) {
165 TransitionManager.beginDelayedTransition(this, mTransition);
166 }
167 mToolbar.setVisibility(View.VISIBLE);
168
169 // Remove callbacks to hide the toolbar.
170 removeCallbacks(mHideToolbarRunnable);
171
172 // Auto hide the toolbar after 3 seconds.
173 if (!getForceToolbarVisible()) {
174 postDelayed(mHideToolbarRunnable, AUTO_HIDE_DELAY_MILLIS);
175 }
176 }
177
178 /**
179 * Hides the toolbar.
180 */
181 public void hideToolbar() {
182 if (!getForceToolbarVisible()) {
183 post(mHideToolbarRunnable);
184 }
185 }
186}