Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Autocomplete FloatingEditText for Google emails. #9

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,315 @@
package com.marvinlabs.widget.floatinglabel.edittext;

import android.accounts.Account;
import android.accounts.AccountManager;
import android.content.Context;
import android.content.res.ColorStateList;
import android.content.res.TypedArray;
import android.graphics.Typeface;
import android.os.AsyncTask;
import android.os.Parcelable;
import android.text.Editable;
import android.text.InputType;
import android.text.TextWatcher;
import android.text.method.KeyListener;
import android.util.AttributeSet;
import android.util.Log;
import android.widget.ArrayAdapter;
import android.widget.AutoCompleteTextView;
import android.widget.TextView;

import com.marvinlabs.widget.floatinglabel.FloatingLabelTextViewBase;
import com.marvinlabs.widget.floatinglabel.LabelAnimator;
import com.marvinlabs.widget.floatinglabel.R;
import com.marvinlabs.widget.floatinglabel.anim.TextViewLabelAnimator;

import java.util.ArrayList;
import java.util.List;

/**
* <p>
* An implementation of the floating label input widget for Android's AutoCompleteTextView
*
* Looks for Google Email accounts on the device to use for auto-completion.
*
* --REQUIRES GET_ACCOUNTS PERMISSION--
*
* Based on FloatingLabelEditText implementation by Vincent Mimoun-Prat @ MarvinLabs
* <p/>
* Created by Joe Rider 14/10/2014
*/
public class FloatingLabelGoogleAutoCompleteEditText extends FloatingLabelTextViewBase<AutoCompleteTextView> {

private static final String GOOGLE_ACCOUNT_TYPE = "com.google";

public interface EditTextListener {
public void onTextChanged(FloatingLabelGoogleAutoCompleteEditText source, String text);
}

/**
* The listener to notify when the selection changes
*/
protected EditTextListener editTextListener;

// =============================================================================================
// Lifecycle
// ==

public FloatingLabelGoogleAutoCompleteEditText(Context context) {
super(context);
init();
}

public FloatingLabelGoogleAutoCompleteEditText(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}

public FloatingLabelGoogleAutoCompleteEditText(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}

// =============================================================================================
// Overridden methods
// ==

@Override
protected void afterLayoutInflated(Context context, AttributeSet attrs, int defStyle) {
super.afterLayoutInflated(context, attrs, defStyle);

final int inputType;

if (attrs == null) {
inputType = InputType.TYPE_CLASS_TEXT;
} else {
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.FloatingLabelEditText, defStyle, 0);
inputType = a.getInt(R.styleable.FloatingLabelEditText_android_inputType, InputType.TYPE_CLASS_TEXT);
a.recycle();
}

final AutoCompleteTextView inputWidget = getInputWidget();

inputWidget.setInputType(inputType);
inputWidget.addTextChangedListener(new EditTextWatcher());
}

@Override
protected int getDefaultLayoutId() {
return R.layout.flw_widget_floating_label_googleautocomplete_edittext;
}

@Override
protected void restoreInputWidgetState(Parcelable inputWidgetState) {
getInputWidget().onRestoreInstanceState(inputWidgetState);
// setLabelAnchored(isEditTextEmpty());
}

@Override
protected Parcelable saveInputWidgetInstanceState() {
return getInputWidget().onSaveInstanceState();
}

@Override
protected void setInitialWidgetState() {
setLabelAnchored(isEditTextEmpty());
}

@Override
protected LabelAnimator<AutoCompleteTextView> getDefaultLabelAnimator() {
return new TextViewLabelAnimator<AutoCompleteTextView>();
}

// =============================================================================================
// Delegate methods for the input widget
// ==

/**
* Delegate method for the input widget
*/
public Editable getInputWidgetText() {
return getInputWidget().getText();
}

/**
* Delegate method for the input widget
*/
public void setInputWidgetText(CharSequence text, TextView.BufferType type) {
getInputWidget().setText(text, type);
}

/**
* Delegate method for the input widget
*/
public void setInputWidgetTextSize(float size) {
getInputWidget().setTextSize(size);
}

/**
* Delegate method for the input widget
*/
public void setInputWidgetTextSize(int unit, float size) {
getInputWidget().setTextSize(unit, size);
}

/**
* Delegate method for the input widget
*/
public void setInputWidgetKeyListener(KeyListener input) {
getInputWidget().setKeyListener(input);
}

/**
* Delegate method for the input widget
*/
public void setInputWidgetTypeface(Typeface tf, int style) {
getInputWidget().setTypeface(tf, style);
}

/**
* Delegate method for the input widget
*/
public void setInputWidgetTextColor(int color) {
getInputWidget().setTextColor(color);
}

/**
* Delegate method for the input widget
*/
public void setInputWidgetTextColor(ColorStateList colors) {
getInputWidget().setTextColor(colors);
}

/**
* Delegate method for the input widget
*/
public void setInputWidgetText(CharSequence text) {
getInputWidget().setText(text);
}

/**
* Delegate method for the input widget
*/
public void setInputWidgetText(int resid) {
getInputWidget().setText(resid);
}

/**
* Delegate method for the input widget
*/
public void setInputWidgetInputType(int type) {
getInputWidget().setInputType(type);
}

/**
* Delegate method for the input widget
*/
public void addInputWidgetTextChangedListener(TextWatcher watcher) {
getInputWidget().addTextChangedListener(watcher);
}

/**
* Delegate method for the input widget
*/
public void removeInputWidgetTextChangedListener(TextWatcher watcher) {
getInputWidget().removeTextChangedListener(watcher);
}

// =============================================================================================
// Other methods
// ==

public EditTextListener getEditTextListener() {
return editTextListener;
}

public void setEditTextListener(EditTextListener editTextListener) {
this.editTextListener = editTextListener;
}

/**
* Called when the text within the input widget is updated
*
* @param s The new text
*/
protected void onTextChanged(String s) {
if (s.length() == 0) {
anchorLabel();
} else {
floatLabel();
}

if (editTextListener != null) editTextListener.onTextChanged(this, s);
}

/**
* @return true if the input widget is empty
*/
private boolean isEditTextEmpty() {
return getInputWidget().getText().toString().isEmpty();
}

/**
* TextWatcher that changes the floating label state when the EditText content changes between
* empty and not empty.
*/
private class EditTextWatcher implements TextWatcher {
@Override
public void afterTextChanged(Editable s) {
FloatingLabelGoogleAutoCompleteEditText.this.onTextChanged(s.toString());
}

@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
// Ignored
}

@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
}

private void init() {
getInputWidget().setThreshold(1);

new AsyncTask<Void, Void, List<String>>() {
@Override
protected List<String> doInBackground(Void... params) {
return findEmailAccounts();
}

@Override
protected void onPostExecute(List<String> o) {
ArrayAdapter<String> adapter = new ArrayAdapter<String>(getContext(), android.R.layout.simple_dropdown_item_1line, o);
getInputWidget().setAdapter(adapter);

if (o.size() == 1) {
setInputWidgetText(o.get(0));
}
}
}.execute();
}

private List<String> findEmailAccounts() {
List<String> emails = new ArrayList<String>();

try {
AccountManager accountManager = AccountManager.get(getContext());
Account[] accounts = accountManager.getAccountsByType(GOOGLE_ACCOUNT_TYPE);
for (Account account : accounts) {
if (isValidEmail(account.name))
emails.add(account.name);
}
}
//Catch exception if GET_ACCOUNTS permission is not present.
catch(SecurityException sec){
Log.e(FloatingLabelGoogleAutoCompleteEditText.class.getSimpleName(), sec.getMessage());
}

return emails;
}

private static boolean isValidEmail(CharSequence target) {
return target != null && android.util.Patterns.EMAIL_ADDRESS.matcher(target).matches();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">

<TextView
android:id="@id/flw_floating_label"
style="@style/FloatingLabelWidget.Label.EditText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:text="This is the label"/>

<AutoCompleteTextView
android:id="@id/flw_input_widget"
style="@style/FloatingLabelWidget.InputWidget.EditText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:text="Your input value here"/>

</merge>