aboutsummaryrefslogtreecommitdiff
path: root/WordPress/src/main/java/org/wordpress/android/widgets/SuggestionAutoCompleteText.java
diff options
context:
space:
mode:
Diffstat (limited to 'WordPress/src/main/java/org/wordpress/android/widgets/SuggestionAutoCompleteText.java')
-rw-r--r--WordPress/src/main/java/org/wordpress/android/widgets/SuggestionAutoCompleteText.java202
1 files changed, 202 insertions, 0 deletions
diff --git a/WordPress/src/main/java/org/wordpress/android/widgets/SuggestionAutoCompleteText.java b/WordPress/src/main/java/org/wordpress/android/widgets/SuggestionAutoCompleteText.java
new file mode 100644
index 000000000..afc2e0479
--- /dev/null
+++ b/WordPress/src/main/java/org/wordpress/android/widgets/SuggestionAutoCompleteText.java
@@ -0,0 +1,202 @@
+package org.wordpress.android.widgets;
+
+import android.content.Context;
+import android.content.res.Configuration;
+import android.graphics.Rect;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.util.AttributeSet;
+import android.view.KeyEvent;
+import android.view.View;
+import android.view.inputmethod.EditorInfo;
+import android.view.inputmethod.InputMethodManager;
+import android.widget.MultiAutoCompleteTextView;
+
+import org.wordpress.android.ui.suggestion.util.SuggestionTokenizer;
+import org.wordpress.persistentedittext.PersistentEditTextHelper;
+
+public class SuggestionAutoCompleteText extends MultiAutoCompleteTextView {
+ PersistentEditTextHelper mPersistentEditTextHelper;
+ private OnEditTextBackListener mBackListener;
+
+ public interface OnEditTextBackListener {
+ void onEditTextBack();
+ }
+
+ public SuggestionAutoCompleteText(Context context) {
+ super(context, null);
+ init(context, null);
+ }
+
+ public SuggestionAutoCompleteText(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ init(context, attrs);
+ }
+
+ public SuggestionAutoCompleteText(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ init(context, attrs);
+ }
+
+ private void init(Context context, AttributeSet attrs) {
+ TypefaceCache.setCustomTypeface(context, this, attrs);
+ setTokenizer(new SuggestionTokenizer());
+ setThreshold(1);
+ mPersistentEditTextHelper = new PersistentEditTextHelper(context);
+ // When TYPE_TEXT_FLAG_AUTO_COMPLETE is set, autocorrection is disabled.
+ setRawInputType(getInputType() & ~EditorInfo.TYPE_TEXT_FLAG_AUTO_COMPLETE);
+ }
+
+ public PersistentEditTextHelper getAutoSaveTextHelper() {
+ return mPersistentEditTextHelper;
+ }
+
+ @Override
+ protected void onAttachedToWindow() {
+ super.onAttachedToWindow();
+ if (getAutoSaveTextHelper().getUniqueId() == null) {
+ return;
+ }
+ getAutoSaveTextHelper().loadString(this);
+ }
+
+ @Override
+ protected void onDetachedFromWindow() {
+ super.onDetachedFromWindow();
+ if (getAutoSaveTextHelper().getUniqueId() == null) {
+ return;
+ }
+ getAutoSaveTextHelper().saveString(this);
+ }
+
+ public void setOnBackListener(OnEditTextBackListener listener) {
+ mBackListener = listener;
+ }
+
+ @Override
+ public Parcelable onSaveInstanceState() {
+ SavedState savedState = new SavedState(super.onSaveInstanceState());
+
+ // store the current Focused state
+ savedState.isFocused = isFocused();
+
+ return savedState;
+ }
+
+ @Override
+ public void onRestoreInstanceState(Parcelable state) {
+ if(!(state instanceof SavedState)) {
+ super.onRestoreInstanceState(state);
+ return;
+ }
+
+ SavedState savedState = (SavedState)state;
+ super.onRestoreInstanceState(savedState.getSuperState());
+
+ // if we were focused, setup a properly timed future request for focus
+ if (savedState.isFocused) {
+ // this OnLayoutChangeListener will self unregister upon running and it's there so we can properly time the
+ // on-screen IME opening
+ addOnLayoutChangeListener(mOneoffFocusRequest);
+ }
+ }
+
+ private final OnLayoutChangeListener mOneoffFocusRequest = new OnLayoutChangeListener() {
+ @Override
+ public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop,
+ int oldRight, int oldBottom) {
+ // we're now at a good point in time to launch a focus request
+ post(new Runnable() {
+ @Override
+ public void run() {
+ // self unregister so we won't auto-request focus again
+ removeOnLayoutChangeListener(mOneoffFocusRequest);
+
+ // request focus
+ setFocusableInTouchMode(true);
+ requestFocus();
+ }
+ });
+ }
+ };
+
+ @Override
+ public boolean performClick() {
+ // make sure we are focusable otherwise we will not get focused
+ setFocusableInTouchMode(true);
+ requestFocus();
+
+ return super.performClick();
+ }
+
+ /*
+ * detect when user hits the back button while soft keyboard is showing (hiding the keyboard)
+ */
+ @Override
+ public boolean onKeyPreIme(int keyCode, KeyEvent event) {
+ if (event.getKeyCode() == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_UP) {
+ // clear focus but stop being focusable first. This way we won't receive focus if we're the only focusable
+ // widget on the page
+ setFocusableInTouchMode(false);
+ clearFocus();
+
+ if (mBackListener != null) {
+ mBackListener.onEditTextBack();
+ }
+ }
+
+ return super.dispatchKeyEvent(event);
+ }
+
+ @Override
+ protected void onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect) {
+ super.onFocusChanged(focused, direction, previouslyFocusedRect);
+
+ // if no hardware keys are present, associate being focused to having the on-screen keyboard visible
+ if (getResources().getConfiguration().keyboard == Configuration.KEYBOARD_NOKEYS) {
+ InputMethodManager inputMethodManager = (InputMethodManager) getContext()
+ .getSystemService(Context.INPUT_METHOD_SERVICE);
+
+ if (focused) {
+ // show the on-screen keybpoard if we got focused
+ inputMethodManager.showSoftInput(this, 0);
+ } else {
+ // stop being focusable so closing the keyboard won't focus us
+ setFocusableInTouchMode(false);
+ inputMethodManager.hideSoftInputFromWindow(getWindowToken(), 0);
+ }
+ }
+ }
+
+ /**
+ * Local class for holding the EditBox's focused or not state
+ */
+ static class SavedState extends BaseSavedState {
+ boolean isFocused;
+
+ SavedState(Parcelable superState) {
+ super(superState);
+ }
+
+ private SavedState(Parcel in) {
+ super(in);
+ this.isFocused = (in.readInt() == 1);
+ }
+
+ @Override
+ public void writeToParcel(Parcel out, int flags) {
+ super.writeToParcel(out, flags);
+ out.writeInt(this.isFocused ? 1 : 0);
+ }
+
+ public static final Parcelable.Creator<SavedState> CREATOR = new Parcelable.Creator<SavedState>() {
+ public SavedState createFromParcel(Parcel in) {
+ return new SavedState(in);
+ }
+
+ public SavedState[] newArray(int size) {
+ return new SavedState[size];
+ }
+ };
+ }
+}