blob: 341564d64fba8de83f781f2f4cc79fdbdd2bda8a [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) {
Hans Boehm52d477a2016-04-01 17:42:50 -070092 showToolbar(true);
Justin Klaassen9d33cdc2016-02-21 14:16:14 -080093 } else {
94 hideToolbar();
95 }
96
97 return true;
98 }
99 });
Justin Klaassenb2f8b112016-07-27 15:09:39 -0700100
101 // Draw the children in reverse order so that the toolbar is on top.
102 setChildrenDrawingOrderEnabled(true);
Justin Klaassen9d33cdc2016-02-21 14:16:14 -0800103 }
104
105 @Override
106 protected void onFinishInflate() {
107 super.onFinishInflate();
108
109 mToolbar = (Toolbar) findViewById(R.id.toolbar);
110 mTransition = new Fade()
111 .setDuration(FADE_DURATION)
112 .addTarget(mToolbar);
113 }
114
115 @Override
Justin Klaassenb2f8b112016-07-27 15:09:39 -0700116 protected int getChildDrawingOrder(int childCount, int i) {
117 // Reverse the normal drawing order.
118 return (childCount - 1) - i;
119 }
120
121 @Override
Justin Klaassen9d33cdc2016-02-21 14:16:14 -0800122 protected void onAttachedToWindow() {
123 super.onAttachedToWindow();
124 mAccessibilityManager.addAccessibilityStateChangeListener(this);
125 }
126
127 @Override
128 protected void onDetachedFromWindow() {
129 super.onDetachedFromWindow();
130 mAccessibilityManager.removeAccessibilityStateChangeListener(this);
131 }
132
133 @Override
134 public void onAccessibilityStateChanged(boolean enabled) {
135 // Always show the toolbar whenever accessibility is enabled.
Hans Boehm52d477a2016-04-01 17:42:50 -0700136 showToolbar(true);
Justin Klaassen9d33cdc2016-02-21 14:16:14 -0800137 }
138
139 @Override
140 public boolean onInterceptTouchEvent(MotionEvent event) {
141 mTapDetector.onTouchEvent(event);
142 return super.onInterceptTouchEvent(event);
143 }
144
145 @Override
146 public boolean onTouchEvent(MotionEvent event) {
147 return mTapDetector.onTouchEvent(event) || super.onTouchEvent(event);
148 }
149
150 /**
151 * Returns {@code true} if the toolbar should remain visible.
152 */
153 public boolean getForceToolbarVisible() {
154 return mForceToolbarVisible || mAccessibilityManager.isEnabled();
155 }
156
157 /**
158 * Forces the toolbar to remain visible.
159 *
160 * @param forceToolbarVisible {@code true} to keep the toolbar visible
161 */
162 public void setForceToolbarVisible(boolean forceToolbarVisible) {
Hans Boehm52d477a2016-04-01 17:42:50 -0700163 if (mForceToolbarVisible != forceToolbarVisible) {
164 mForceToolbarVisible = forceToolbarVisible;
165 showToolbar(!forceToolbarVisible);
166 }
Justin Klaassen9d33cdc2016-02-21 14:16:14 -0800167 }
168
169 /**
170 * Shows the toolbar.
Hans Boehm52d477a2016-04-01 17:42:50 -0700171 * @param autoHide Automatically ide toolbar again after delay
Justin Klaassen9d33cdc2016-02-21 14:16:14 -0800172 */
Hans Boehm52d477a2016-04-01 17:42:50 -0700173 public void showToolbar(boolean autoHide) {
Justin Klaassen9d33cdc2016-02-21 14:16:14 -0800174 // Only animate if we have been laid out at least once.
175 if (isLaidOut()) {
176 TransitionManager.beginDelayedTransition(this, mTransition);
177 }
178 mToolbar.setVisibility(View.VISIBLE);
179
180 // Remove callbacks to hide the toolbar.
181 removeCallbacks(mHideToolbarRunnable);
182
183 // Auto hide the toolbar after 3 seconds.
Hans Boehm52d477a2016-04-01 17:42:50 -0700184 if (autoHide && !getForceToolbarVisible()) {
Justin Klaassen9d33cdc2016-02-21 14:16:14 -0800185 postDelayed(mHideToolbarRunnable, AUTO_HIDE_DELAY_MILLIS);
186 }
187 }
188
189 /**
190 * Hides the toolbar.
191 */
192 public void hideToolbar() {
193 if (!getForceToolbarVisible()) {
Christine Frankseeff27f2016-07-29 12:05:29 -0700194 removeCallbacks(mHideToolbarRunnable);
195 mHideToolbarRunnable.run();
Justin Klaassen9d33cdc2016-02-21 14:16:14 -0800196 }
197 }
Christine Frankseeff27f2016-07-29 12:05:29 -0700198
199 public boolean isToolbarVisible() {
200 return mToolbar.getVisibility() == View.VISIBLE;
201 }
Justin Klaassen9d33cdc2016-02-21 14:16:14 -0800202}