diff options
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.java | 202 |
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]; + } + }; + } +} |