Adrian Roos | 497ab02 | 2015-02-10 20:49:33 +0100 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (C) 2015 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.android.systemui.statusbar.policy; |
| 18 | |
Adrian Roos | 497ab02 | 2015-02-10 20:49:33 +0100 | [diff] [blame] | 19 | import android.app.PendingIntent; |
| 20 | import android.app.RemoteInput; |
| 21 | import android.content.Context; |
| 22 | import android.content.Intent; |
Adrian Roos | dc5b453 | 2016-01-06 20:49:41 +0100 | [diff] [blame] | 23 | import android.graphics.Rect; |
Adrian Roos | 497ab02 | 2015-02-10 20:49:33 +0100 | [diff] [blame] | 24 | import android.graphics.drawable.Drawable; |
| 25 | import android.os.Bundle; |
Adrian Roos | 245aa87 | 2015-12-07 14:53:53 -0800 | [diff] [blame] | 26 | import android.text.Editable; |
| 27 | import android.text.TextWatcher; |
Adrian Roos | 497ab02 | 2015-02-10 20:49:33 +0100 | [diff] [blame] | 28 | import android.util.AttributeSet; |
| 29 | import android.util.Log; |
| 30 | import android.view.KeyEvent; |
| 31 | import android.view.LayoutInflater; |
Adrian Roos | 0bd8a4b | 2016-03-14 16:21:44 -0700 | [diff] [blame] | 32 | import android.view.MotionEvent; |
Adrian Roos | 497ab02 | 2015-02-10 20:49:33 +0100 | [diff] [blame] | 33 | import android.view.View; |
| 34 | import android.view.ViewGroup; |
Adrian Roos | 0bd8a4b | 2016-03-14 16:21:44 -0700 | [diff] [blame] | 35 | import android.view.ViewParent; |
Adrian Roos | fe84e1f | 2015-11-04 15:55:39 -0800 | [diff] [blame] | 36 | import android.view.inputmethod.CompletionInfo; |
Adrian Roos | 497ab02 | 2015-02-10 20:49:33 +0100 | [diff] [blame] | 37 | import android.view.inputmethod.EditorInfo; |
Adrian Roos | 1c0ca50 | 2015-10-07 12:20:42 -0700 | [diff] [blame] | 38 | import android.view.inputmethod.InputConnection; |
Adrian Roos | 497ab02 | 2015-02-10 20:49:33 +0100 | [diff] [blame] | 39 | import android.view.inputmethod.InputMethodManager; |
| 40 | import android.widget.EditText; |
Adrian Roos | fe84e1f | 2015-11-04 15:55:39 -0800 | [diff] [blame] | 41 | import android.widget.ImageButton; |
| 42 | import android.widget.LinearLayout; |
Adrian Roos | 497ab02 | 2015-02-10 20:49:33 +0100 | [diff] [blame] | 43 | import android.widget.ProgressBar; |
| 44 | import android.widget.TextView; |
| 45 | |
Winson | c0d7058 | 2016-01-29 10:24:39 -0800 | [diff] [blame] | 46 | import com.android.systemui.R; |
| 47 | import com.android.systemui.statusbar.NotificationData; |
| 48 | import com.android.systemui.statusbar.RemoteInputController; |
Adrian Roos | 5153d4a | 2016-03-22 10:01:56 -0700 | [diff] [blame] | 49 | import com.android.systemui.statusbar.stack.ScrollContainer; |
Adrian Roos | 1c0ca50 | 2015-10-07 12:20:42 -0700 | [diff] [blame] | 50 | |
Adrian Roos | 497ab02 | 2015-02-10 20:49:33 +0100 | [diff] [blame] | 51 | /** |
| 52 | * Host for the remote input. |
| 53 | */ |
Adrian Roos | 245aa87 | 2015-12-07 14:53:53 -0800 | [diff] [blame] | 54 | public class RemoteInputView extends LinearLayout implements View.OnClickListener, TextWatcher { |
Adrian Roos | 497ab02 | 2015-02-10 20:49:33 +0100 | [diff] [blame] | 55 | |
| 56 | private static final String TAG = "RemoteInput"; |
| 57 | |
Adrian Roos | fe84e1f | 2015-11-04 15:55:39 -0800 | [diff] [blame] | 58 | // A marker object that let's us easily find views of this class. |
| 59 | public static final Object VIEW_TAG = new Object(); |
| 60 | |
Adrian Roos | 497ab02 | 2015-02-10 20:49:33 +0100 | [diff] [blame] | 61 | private RemoteEditText mEditText; |
Adrian Roos | fe84e1f | 2015-11-04 15:55:39 -0800 | [diff] [blame] | 62 | private ImageButton mSendButton; |
Adrian Roos | 497ab02 | 2015-02-10 20:49:33 +0100 | [diff] [blame] | 63 | private ProgressBar mProgressBar; |
| 64 | private PendingIntent mPendingIntent; |
Adrian Roos | fe84e1f | 2015-11-04 15:55:39 -0800 | [diff] [blame] | 65 | private RemoteInput[] mRemoteInputs; |
Adrian Roos | 497ab02 | 2015-02-10 20:49:33 +0100 | [diff] [blame] | 66 | private RemoteInput mRemoteInput; |
Adrian Roos | 1c0ca50 | 2015-10-07 12:20:42 -0700 | [diff] [blame] | 67 | private RemoteInputController mController; |
Adrian Roos | fe84e1f | 2015-11-04 15:55:39 -0800 | [diff] [blame] | 68 | |
Adrian Roos | 1c0ca50 | 2015-10-07 12:20:42 -0700 | [diff] [blame] | 69 | private NotificationData.Entry mEntry; |
Adrian Roos | 5153d4a | 2016-03-22 10:01:56 -0700 | [diff] [blame] | 70 | |
| 71 | private ScrollContainer mScrollContainer; |
| 72 | private View mScrollContainerChild; |
Adrian Roos | 497ab02 | 2015-02-10 20:49:33 +0100 | [diff] [blame] | 73 | |
| 74 | public RemoteInputView(Context context, AttributeSet attrs) { |
| 75 | super(context, attrs); |
| 76 | } |
| 77 | |
| 78 | @Override |
| 79 | protected void onFinishInflate() { |
| 80 | super.onFinishInflate(); |
| 81 | |
| 82 | mProgressBar = (ProgressBar) findViewById(R.id.remote_input_progress); |
| 83 | |
Adrian Roos | fe84e1f | 2015-11-04 15:55:39 -0800 | [diff] [blame] | 84 | mSendButton = (ImageButton) findViewById(R.id.remote_input_send); |
| 85 | mSendButton.setOnClickListener(this); |
| 86 | |
Adrian Roos | 497ab02 | 2015-02-10 20:49:33 +0100 | [diff] [blame] | 87 | mEditText = (RemoteEditText) getChildAt(0); |
| 88 | mEditText.setOnEditorActionListener(new TextView.OnEditorActionListener() { |
| 89 | @Override |
| 90 | public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { |
| 91 | |
| 92 | // Check if this was the result of hitting the enter key |
| 93 | final boolean isSoftImeEvent = event == null |
| 94 | && (actionId == EditorInfo.IME_ACTION_DONE |
| 95 | || actionId == EditorInfo.IME_ACTION_NEXT |
| 96 | || actionId == EditorInfo.IME_ACTION_SEND); |
| 97 | final boolean isKeyboardEnterKey = event != null |
| 98 | && KeyEvent.isConfirmKey(event.getKeyCode()) |
| 99 | && event.getAction() == KeyEvent.ACTION_DOWN; |
| 100 | |
| 101 | if (isSoftImeEvent || isKeyboardEnterKey) { |
| 102 | sendRemoteInput(); |
| 103 | return true; |
| 104 | } |
| 105 | return false; |
| 106 | } |
| 107 | }); |
| 108 | mEditText.setOnClickListener(this); |
Adrian Roos | 245aa87 | 2015-12-07 14:53:53 -0800 | [diff] [blame] | 109 | mEditText.addTextChangedListener(this); |
Adrian Roos | 497ab02 | 2015-02-10 20:49:33 +0100 | [diff] [blame] | 110 | mEditText.setInnerFocusable(false); |
Adrian Roos | 5153d4a | 2016-03-22 10:01:56 -0700 | [diff] [blame] | 111 | mEditText.mRemoteInputView = this; |
Adrian Roos | 497ab02 | 2015-02-10 20:49:33 +0100 | [diff] [blame] | 112 | } |
| 113 | |
| 114 | private void sendRemoteInput() { |
| 115 | Bundle results = new Bundle(); |
| 116 | results.putString(mRemoteInput.getResultKey(), mEditText.getText().toString()); |
Adrian Roos | 1c0ca50 | 2015-10-07 12:20:42 -0700 | [diff] [blame] | 117 | Intent fillInIntent = new Intent().addFlags(Intent.FLAG_RECEIVER_FOREGROUND); |
Adrian Roos | fe84e1f | 2015-11-04 15:55:39 -0800 | [diff] [blame] | 118 | RemoteInput.addResultsToIntent(mRemoteInputs, fillInIntent, |
Adrian Roos | 497ab02 | 2015-02-10 20:49:33 +0100 | [diff] [blame] | 119 | results); |
| 120 | |
| 121 | mEditText.setEnabled(false); |
Adrian Roos | fe84e1f | 2015-11-04 15:55:39 -0800 | [diff] [blame] | 122 | mSendButton.setVisibility(INVISIBLE); |
Adrian Roos | 497ab02 | 2015-02-10 20:49:33 +0100 | [diff] [blame] | 123 | mProgressBar.setVisibility(VISIBLE); |
Adrian Roos | c0a579e | 2016-03-30 16:43:58 -0700 | [diff] [blame] | 124 | mEntry.remoteInputText = mEditText.getText(); |
| 125 | mController.addSpinning(mEntry.key); |
Adrian Roos | 245aa87 | 2015-12-07 14:53:53 -0800 | [diff] [blame] | 126 | mController.removeRemoteInput(mEntry); |
| 127 | mEditText.mShowImeOnInputConnection = false; |
Adrian Roos | c0a579e | 2016-03-30 16:43:58 -0700 | [diff] [blame] | 128 | mController.remoteInputSent(mEntry); |
Adrian Roos | 497ab02 | 2015-02-10 20:49:33 +0100 | [diff] [blame] | 129 | |
| 130 | try { |
| 131 | mPendingIntent.send(mContext, 0, fillInIntent); |
| 132 | } catch (PendingIntent.CanceledException e) { |
| 133 | Log.i(TAG, "Unable to send remote input result", e); |
| 134 | } |
| 135 | } |
| 136 | |
| 137 | public static RemoteInputView inflate(Context context, ViewGroup root, |
Adrian Roos | fe84e1f | 2015-11-04 15:55:39 -0800 | [diff] [blame] | 138 | NotificationData.Entry entry, |
Adrian Roos | 1c0ca50 | 2015-10-07 12:20:42 -0700 | [diff] [blame] | 139 | RemoteInputController controller) { |
Adrian Roos | 497ab02 | 2015-02-10 20:49:33 +0100 | [diff] [blame] | 140 | RemoteInputView v = (RemoteInputView) |
| 141 | LayoutInflater.from(context).inflate(R.layout.remote_input, root, false); |
Adrian Roos | 1c0ca50 | 2015-10-07 12:20:42 -0700 | [diff] [blame] | 142 | v.mController = controller; |
| 143 | v.mEntry = entry; |
Adrian Roos | fe84e1f | 2015-11-04 15:55:39 -0800 | [diff] [blame] | 144 | v.setTag(VIEW_TAG); |
Adrian Roos | 497ab02 | 2015-02-10 20:49:33 +0100 | [diff] [blame] | 145 | |
| 146 | return v; |
| 147 | } |
| 148 | |
| 149 | @Override |
| 150 | public void onClick(View v) { |
| 151 | if (v == mEditText) { |
| 152 | if (!mEditText.isFocusable()) { |
Adrian Roos | fe84e1f | 2015-11-04 15:55:39 -0800 | [diff] [blame] | 153 | focus(); |
Adrian Roos | 497ab02 | 2015-02-10 20:49:33 +0100 | [diff] [blame] | 154 | } |
Adrian Roos | fe84e1f | 2015-11-04 15:55:39 -0800 | [diff] [blame] | 155 | } else if (v == mSendButton) { |
| 156 | sendRemoteInput(); |
Adrian Roos | 497ab02 | 2015-02-10 20:49:33 +0100 | [diff] [blame] | 157 | } |
| 158 | } |
| 159 | |
Adrian Roos | 1c0ca50 | 2015-10-07 12:20:42 -0700 | [diff] [blame] | 160 | public void onDefocus() { |
| 161 | mController.removeRemoteInput(mEntry); |
Adrian Roos | 777ef56 | 2015-12-01 17:37:14 -0800 | [diff] [blame] | 162 | mEntry.remoteInputText = mEditText.getText(); |
Adrian Roos | fe84e1f | 2015-11-04 15:55:39 -0800 | [diff] [blame] | 163 | setVisibility(INVISIBLE); |
Adrian Roos | 1c0ca50 | 2015-10-07 12:20:42 -0700 | [diff] [blame] | 164 | } |
| 165 | |
| 166 | @Override |
Adrian Roos | 14503e2 | 2016-03-09 14:01:24 -0800 | [diff] [blame] | 167 | protected void onAttachedToWindow() { |
| 168 | super.onAttachedToWindow(); |
| 169 | if (mEntry.row.isChangingPosition()) { |
| 170 | if (getVisibility() == VISIBLE && mEditText.isFocusable()) { |
| 171 | mEditText.requestFocus(); |
| 172 | } |
| 173 | } |
| 174 | } |
| 175 | |
| 176 | @Override |
Adrian Roos | 1c0ca50 | 2015-10-07 12:20:42 -0700 | [diff] [blame] | 177 | protected void onDetachedFromWindow() { |
| 178 | super.onDetachedFromWindow(); |
Adrian Roos | 14503e2 | 2016-03-09 14:01:24 -0800 | [diff] [blame] | 179 | if (mEntry.row.isChangingPosition()) { |
| 180 | return; |
| 181 | } |
Adrian Roos | 1c0ca50 | 2015-10-07 12:20:42 -0700 | [diff] [blame] | 182 | mController.removeRemoteInput(mEntry); |
Adrian Roos | c0a579e | 2016-03-30 16:43:58 -0700 | [diff] [blame] | 183 | mController.removeSpinning(mEntry.key); |
Adrian Roos | 1c0ca50 | 2015-10-07 12:20:42 -0700 | [diff] [blame] | 184 | } |
| 185 | |
Adrian Roos | fe84e1f | 2015-11-04 15:55:39 -0800 | [diff] [blame] | 186 | public void setPendingIntent(PendingIntent pendingIntent) { |
| 187 | mPendingIntent = pendingIntent; |
| 188 | } |
| 189 | |
| 190 | public void setRemoteInput(RemoteInput[] remoteInputs, RemoteInput remoteInput) { |
| 191 | mRemoteInputs = remoteInputs; |
| 192 | mRemoteInput = remoteInput; |
| 193 | mEditText.setHint(mRemoteInput.getLabel()); |
| 194 | } |
| 195 | |
| 196 | public void focus() { |
Adrian Roos | fe84e1f | 2015-11-04 15:55:39 -0800 | [diff] [blame] | 197 | mController.addRemoteInput(mEntry); |
Adrian Roos | dc5b453 | 2016-01-06 20:49:41 +0100 | [diff] [blame] | 198 | mEditText.setInnerFocusable(true); |
Adrian Roos | fe84e1f | 2015-11-04 15:55:39 -0800 | [diff] [blame] | 199 | mEditText.mShowImeOnInputConnection = true; |
Adrian Roos | 777ef56 | 2015-12-01 17:37:14 -0800 | [diff] [blame] | 200 | mEditText.setText(mEntry.remoteInputText); |
| 201 | mEditText.setSelection(mEditText.getText().length()); |
Adrian Roos | fe84e1f | 2015-11-04 15:55:39 -0800 | [diff] [blame] | 202 | mEditText.requestFocus(); |
Adrian Roos | 245aa87 | 2015-12-07 14:53:53 -0800 | [diff] [blame] | 203 | updateSendButton(); |
| 204 | } |
| 205 | |
| 206 | public void onNotificationUpdate() { |
| 207 | boolean sending = mProgressBar.getVisibility() == VISIBLE; |
| 208 | |
| 209 | if (sending) { |
| 210 | // Update came in after we sent the reply, time to reset. |
| 211 | reset(); |
| 212 | } |
| 213 | } |
| 214 | |
| 215 | private void reset() { |
| 216 | mEditText.getText().clear(); |
| 217 | mEditText.setEnabled(true); |
| 218 | mSendButton.setVisibility(VISIBLE); |
| 219 | mProgressBar.setVisibility(INVISIBLE); |
Adrian Roos | c0a579e | 2016-03-30 16:43:58 -0700 | [diff] [blame] | 220 | mController.removeSpinning(mEntry.key); |
Adrian Roos | 245aa87 | 2015-12-07 14:53:53 -0800 | [diff] [blame] | 221 | updateSendButton(); |
| 222 | onDefocus(); |
| 223 | } |
| 224 | |
| 225 | private void updateSendButton() { |
| 226 | mSendButton.setEnabled(mEditText.getText().length() != 0); |
| 227 | } |
| 228 | |
| 229 | @Override |
| 230 | public void beforeTextChanged(CharSequence s, int start, int count, int after) {} |
| 231 | |
| 232 | @Override |
| 233 | public void onTextChanged(CharSequence s, int start, int before, int count) {} |
| 234 | |
| 235 | @Override |
| 236 | public void afterTextChanged(Editable s) { |
| 237 | updateSendButton(); |
Adrian Roos | fe84e1f | 2015-11-04 15:55:39 -0800 | [diff] [blame] | 238 | } |
| 239 | |
Adrian Roos | 0bd8a4b | 2016-03-14 16:21:44 -0700 | [diff] [blame] | 240 | public void close() { |
| 241 | mEditText.defocusIfNeeded(); |
| 242 | } |
| 243 | |
| 244 | @Override |
| 245 | public boolean onInterceptTouchEvent(MotionEvent ev) { |
| 246 | if (ev.getAction() == MotionEvent.ACTION_DOWN) { |
Adrian Roos | 5153d4a | 2016-03-22 10:01:56 -0700 | [diff] [blame] | 247 | findScrollContainer(); |
| 248 | if (mScrollContainer != null) { |
| 249 | mScrollContainer.requestDisallowLongPress(); |
Adrian Roos | 0bd8a4b | 2016-03-14 16:21:44 -0700 | [diff] [blame] | 250 | } |
| 251 | } |
| 252 | return super.onInterceptTouchEvent(ev); |
| 253 | } |
| 254 | |
Adrian Roos | 5153d4a | 2016-03-22 10:01:56 -0700 | [diff] [blame] | 255 | public boolean requestScrollTo() { |
| 256 | findScrollContainer(); |
| 257 | mScrollContainer.scrollTo(mScrollContainerChild); |
| 258 | return true; |
| 259 | } |
| 260 | |
| 261 | private void findScrollContainer() { |
| 262 | if (mScrollContainer == null) { |
| 263 | ViewParent p = this; |
| 264 | while (p != null) { |
| 265 | if (p.getParent() instanceof ScrollContainer) { |
| 266 | mScrollContainer = (ScrollContainer) p.getParent(); |
| 267 | mScrollContainerChild = (View) p; |
| 268 | break; |
| 269 | } |
| 270 | p = p.getParent(); |
| 271 | } |
| 272 | } |
| 273 | } |
| 274 | |
Adrian Roos | 497ab02 | 2015-02-10 20:49:33 +0100 | [diff] [blame] | 275 | /** |
| 276 | * An EditText that changes appearance based on whether it's focusable and becomes |
| 277 | * un-focusable whenever the user navigates away from it or it becomes invisible. |
| 278 | */ |
| 279 | public static class RemoteEditText extends EditText { |
| 280 | |
| 281 | private final Drawable mBackground; |
Adrian Roos | 5153d4a | 2016-03-22 10:01:56 -0700 | [diff] [blame] | 282 | private RemoteInputView mRemoteInputView; |
Adrian Roos | 1c0ca50 | 2015-10-07 12:20:42 -0700 | [diff] [blame] | 283 | boolean mShowImeOnInputConnection; |
Adrian Roos | 497ab02 | 2015-02-10 20:49:33 +0100 | [diff] [blame] | 284 | |
| 285 | public RemoteEditText(Context context, AttributeSet attrs) { |
| 286 | super(context, attrs); |
| 287 | mBackground = getBackground(); |
| 288 | } |
| 289 | |
| 290 | private void defocusIfNeeded() { |
Adrian Roos | 5153d4a | 2016-03-22 10:01:56 -0700 | [diff] [blame] | 291 | if (mRemoteInputView != null && mRemoteInputView.mEntry.row.isChangingPosition()) { |
Adrian Roos | 14503e2 | 2016-03-09 14:01:24 -0800 | [diff] [blame] | 292 | return; |
| 293 | } |
Adrian Roos | 497ab02 | 2015-02-10 20:49:33 +0100 | [diff] [blame] | 294 | if (isFocusable() && isEnabled()) { |
| 295 | setInnerFocusable(false); |
Adrian Roos | 5153d4a | 2016-03-22 10:01:56 -0700 | [diff] [blame] | 296 | if (mRemoteInputView != null) { |
| 297 | mRemoteInputView.onDefocus(); |
Adrian Roos | 1c0ca50 | 2015-10-07 12:20:42 -0700 | [diff] [blame] | 298 | } |
| 299 | mShowImeOnInputConnection = false; |
Adrian Roos | 497ab02 | 2015-02-10 20:49:33 +0100 | [diff] [blame] | 300 | } |
| 301 | } |
| 302 | |
| 303 | @Override |
| 304 | protected void onVisibilityChanged(View changedView, int visibility) { |
| 305 | super.onVisibilityChanged(changedView, visibility); |
| 306 | |
| 307 | if (!isShown()) { |
| 308 | defocusIfNeeded(); |
| 309 | } |
| 310 | } |
| 311 | |
| 312 | @Override |
Adrian Roos | 967f619 | 2016-03-09 12:47:26 -0800 | [diff] [blame] | 313 | protected void onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect) { |
| 314 | super.onFocusChanged(focused, direction, previouslyFocusedRect); |
| 315 | if (!focused) { |
| 316 | defocusIfNeeded(); |
| 317 | } |
Adrian Roos | 497ab02 | 2015-02-10 20:49:33 +0100 | [diff] [blame] | 318 | } |
| 319 | |
| 320 | @Override |
Adrian Roos | dc5b453 | 2016-01-06 20:49:41 +0100 | [diff] [blame] | 321 | public void getFocusedRect(Rect r) { |
| 322 | super.getFocusedRect(r); |
| 323 | r.top = mScrollY; |
| 324 | r.bottom = mScrollY + (mBottom - mTop); |
| 325 | } |
| 326 | |
| 327 | @Override |
Adrian Roos | 5153d4a | 2016-03-22 10:01:56 -0700 | [diff] [blame] | 328 | public boolean requestRectangleOnScreen(Rect rectangle) { |
| 329 | return mRemoteInputView.requestScrollTo(); |
| 330 | } |
| 331 | |
| 332 | @Override |
Adrian Roos | 497ab02 | 2015-02-10 20:49:33 +0100 | [diff] [blame] | 333 | public boolean onKeyPreIme(int keyCode, KeyEvent event) { |
Adrian Roos | 777ef56 | 2015-12-01 17:37:14 -0800 | [diff] [blame] | 334 | if (keyCode == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_UP) { |
Adrian Roos | 497ab02 | 2015-02-10 20:49:33 +0100 | [diff] [blame] | 335 | defocusIfNeeded(); |
Adrian Roos | 777ef56 | 2015-12-01 17:37:14 -0800 | [diff] [blame] | 336 | final InputMethodManager imm = InputMethodManager.getInstance(); |
| 337 | imm.hideSoftInputFromWindow(getWindowToken(), 0); |
| 338 | return true; |
Adrian Roos | 497ab02 | 2015-02-10 20:49:33 +0100 | [diff] [blame] | 339 | } |
| 340 | return super.onKeyPreIme(keyCode, event); |
| 341 | } |
| 342 | |
Adrian Roos | 1c0ca50 | 2015-10-07 12:20:42 -0700 | [diff] [blame] | 343 | @Override |
| 344 | public InputConnection onCreateInputConnection(EditorInfo outAttrs) { |
| 345 | final InputConnection inputConnection = super.onCreateInputConnection(outAttrs); |
| 346 | |
| 347 | if (mShowImeOnInputConnection && inputConnection != null) { |
| 348 | final InputMethodManager imm = InputMethodManager.getInstance(); |
| 349 | if (imm != null) { |
| 350 | // onCreateInputConnection is called by InputMethodManager in the middle of |
| 351 | // setting up the connection to the IME; wait with requesting the IME until that |
| 352 | // work has completed. |
| 353 | post(new Runnable() { |
| 354 | @Override |
| 355 | public void run() { |
| 356 | imm.viewClicked(RemoteEditText.this); |
| 357 | imm.showSoftInput(RemoteEditText.this, 0); |
| 358 | } |
| 359 | }); |
| 360 | } |
| 361 | } |
| 362 | |
| 363 | return inputConnection; |
| 364 | } |
Adrian Roos | 497ab02 | 2015-02-10 20:49:33 +0100 | [diff] [blame] | 365 | |
Adrian Roos | fe84e1f | 2015-11-04 15:55:39 -0800 | [diff] [blame] | 366 | @Override |
| 367 | public void onCommitCompletion(CompletionInfo text) { |
| 368 | clearComposingText(); |
| 369 | setText(text.getText()); |
| 370 | setSelection(getText().length()); |
| 371 | } |
| 372 | |
Adrian Roos | 497ab02 | 2015-02-10 20:49:33 +0100 | [diff] [blame] | 373 | void setInnerFocusable(boolean focusable) { |
| 374 | setFocusableInTouchMode(focusable); |
| 375 | setFocusable(focusable); |
| 376 | setCursorVisible(focusable); |
| 377 | |
| 378 | if (focusable) { |
| 379 | requestFocus(); |
| 380 | setBackground(mBackground); |
| 381 | } else { |
| 382 | setBackground(null); |
| 383 | } |
| 384 | |
| 385 | } |
| 386 | } |
| 387 | } |