Skip to content

Instantly share code, notes, and snippets.

@niftynei
Last active August 31, 2015 18:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save niftynei/dd4ec30fb25a1ec9fb82 to your computer and use it in GitHub Desktop.
Save niftynei/dd4ec30fb25a1ec9fb82 to your computer and use it in GitHub Desktop.
LoginView.java
package com.electricobjects.client.login;
import android.annotation.TargetApi;
import android.app.Activity;
import android.content.Context;
import android.os.Build;
import android.os.SystemClock;
import android.text.Html;
import android.text.InputType;
import android.text.Spannable;
import android.text.TextPaint;
import android.text.method.LinkMovementMethod;
import android.text.style.URLSpan;
import android.util.AttributeSet;
import android.util.Patterns;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.inputmethod.EditorInfo;
import android.widget.EditText;
import android.widget.FrameLayout;
import android.widget.TextView;
import com.electricobjects.client.configs.EoConfig;
import com.electricobjects.client.configs.EoConstants;
import com.electricobjects.client.util.NavigationUtil;
import com.electricobjects.client.util.views.ErrorView;
import com.electricobjects.commons.util.EoLog;
/**
* Created by lisa on 1/29/15.
*
*/
public class LoginView extends FrameLayout implements TextView.OnEditorActionListener, View.OnKeyListener, View.OnClickListener, View.OnFocusChangeListener {
private static final String TAG = EoLog.makeTag(LoginView.class);
private LoginCallback mCallback;
private ErrorView mErrorView;
private View mUsernameBorder;
public interface LoginCallback {
void onEnterPressed();
void onLearnMorePressed();
void onForgotPasswordPressed();
}
EditText mEmail;
EditText mPassword;
EditText mUsername;
View mForgotPassword;
TextView mTermsAndCondis;
TextView mFlavorText;
View mLearnMoreLink;
public LoginView(Context context, LoginCallback callback) {
super(context);
init(callback);
}
public LoginView(Context context, AttributeSet attrs) {
super(context, attrs);
init(null);
}
public LoginView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(null);
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public LoginView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
init(null);
}
private void init(LoginCallback callback) {
LayoutInflater.from(getContext()).inflate(R.layout.view_login, this, true);
mEmail = (EditText) findViewById(R.id.text_email);
mPassword = (EditText) findViewById(R.id.text_password);
mUsername = (EditText) findViewById(R.id.text_username);
mUsernameBorder = findViewById(R.id.border_bottom);
mForgotPassword = findViewById(R.id.text_forgot_password);
mTermsAndCondis = (TextView) findViewById(R.id.text_terms_and_condis);
mLearnMoreLink = findViewById(R.id.text_learn_more);
mFlavorText = (TextView) findViewById(R.id.text_login_flavor);
mErrorView = (ErrorView) findViewById(R.id.view_error);
mEmail.setOnFocusChangeListener(this);
// i should probably add a setter for the callback
mCallback = callback;
}
public void hideKeyboard() {
mForgotPassword.requestFocus();
}
public void setType(String action) {
// set in the activity; whether to show the Login or Sign up fields
if (EoConstants.ACTION_LOGIN.equals(action) || EoConstants.ACTION_LOGIN_SHOW_MESSAGE.equals(action)) {
setupLoginView();
} else if (EoConstants.ACTION_SIGN_UP.equals(action)) {
setupCreateAccountView();
}
}
public void focusOnEmail() {
// some hacky StackOverflow fix for getting the keyboard to pop up
mEmail.dispatchTouchEvent(MotionEvent.obtain(SystemClock.uptimeMillis(), SystemClock.uptimeMillis(), MotionEvent.ACTION_DOWN, 0, 0, 0));
mEmail.dispatchTouchEvent(MotionEvent.obtain(SystemClock.uptimeMillis(), SystemClock.uptimeMillis(), MotionEvent.ACTION_UP, 0, 0, 0));
}
public boolean isCreateAccount() {
return mUsername.getVisibility() == View.VISIBLE;
}
public String getPassword() {
return mPassword.getText().toString();
}
public String getUsername() {
return mUsername.getText().toString();
}
public String getEmail() {
return mEmail.getText().toString();
}
public void setEmailError(String string) {
hideErrorMessage();
mEmail.setError(string);
}
public void setPasswordError(String string) {
hideErrorMessage();
mPassword.setError(string);
}
public void setUsernameError(String string) {
hideErrorMessage();
mUsername.setError(string);
}
public void showErrorMessage(String string) {
mEmail.setError(null);
mPassword.setError(null);
mUsername.setError(null);
mErrorView.showError(string);
}
public void hideErrorMessage() {
mErrorView.hideError();
}
public boolean hasUsername() {
boolean isValid = mUsername.length() > 0;
if (!isValid) {
mUsername.setError(getContext().getString(R.string.error_enter_username));
}
return isValid;
}
public boolean hasEmail() {
boolean isValid = mEmail.length() > 0;
if (!isValid) {
mEmail.setError(getContext().getString(R.string.error_enter_email));
}
return isValid;
}
public boolean hasPassword() {
boolean isValid = mPassword.length() > 0;
if (!isValid) {
mPassword.setError(getContext().getString(R.string.error_enter_password));
}
return isValid;
}
public boolean validateUsername() {
boolean isValid = hasUsername();
return isValid;
}
public boolean validateEmail() {
boolean isValid = hasEmail();
if (isValid) {
isValid = Patterns.EMAIL_ADDRESS.matcher(getEmail()).matches();
if (!isValid) {
mEmail.setError(getContext().getString(R.string.error_invalid_email));
}
}
return isValid;
}
public boolean validatePassword() {
boolean isValid = hasPassword();
if (isValid) {
isValid = mPassword.length() >= EoConstants.VALIDATE_PASSWORD_LENGTH;
if (!isValid) {
mPassword.setError(getContext().getString(R.string.error_password_too_short));
}
}
return isValid;
}
public boolean validateCreateAccount() {
return validateUsername() & validatePassword() & validateEmail();
}
public boolean validateLogin() {
return validateEmail() & validatePassword();
}
private void setupLoginView() {
mFlavorText.setText(R.string.login_to_display);
mEmail.setHint(R.string.email);
mPassword.setHint(R.string.password);
mPassword.setImeOptions(EditorInfo.IME_ACTION_GO);
mPassword.setInputType(InputType.TYPE_CLASS_TEXT|InputType.TYPE_TEXT_VARIATION_PASSWORD);
mPassword.setOnEditorActionListener(this);
mPassword.setOnKeyListener(this);
mForgotPassword.setVisibility(View.VISIBLE);
mForgotPassword.setOnClickListener(this);
mLearnMoreLink.setVisibility(View.VISIBLE);
mLearnMoreLink.setOnClickListener(this);
mUsernameBorder.setVisibility(View.GONE);
mUsername.setVisibility(View.GONE);
mTermsAndCondis.setVisibility(View.INVISIBLE);
}
private void setupCreateAccountView() {
mFlavorText.setText(R.string.sign_up_to_display);
mEmail.setHint(R.string.enter_your_email);
mPassword.setHint(R.string.create_a_password);
mPassword.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD);
mUsername.setImeOptions(EditorInfo.IME_ACTION_GO);
mUsername.setHint(R.string.create_a_username);
mUsername.setOnEditorActionListener(this);
mUsername.setOnKeyListener(this);
setupLinksForTermsAndCondis();
mUsernameBorder.setVisibility(View.VISIBLE);
mTermsAndCondis.setVisibility(View.VISIBLE);
mForgotPassword.setVisibility(View.GONE);
mLearnMoreLink.setVisibility(View.GONE);
}
private void setupLinksForTermsAndCondis() {
String termsLink = EoConfig.getEnv().getTermsUrl();
String privacyPolicyLink = EoConfig.getEnv().getPrivacyUrl();
Spannable span = (Spannable) Html.fromHtml(getContext().getString(R.string.terms_and_conditions, privacyPolicyLink, termsLink));
for (URLSpan urlSpan : span.getSpans(0, span.length(), URLSpan.class)) {
span.setSpan(new URLSpan(urlSpan.getURL()) {
@Override
public void updateDrawState(TextPaint tp) {
tp.setUnderlineText(false);
}
@Override
public void onClick(View widget) {
if (getContext() instanceof Activity) {
// this cast may break if you do any cool/weird inflation via ContextWrappers, etc.
NavigationUtil.goToWebpage((Activity) getContext(), getURL());
} else {
super.onClick(widget);
}
}
}, span.getSpanStart(urlSpan), span.getSpanEnd(urlSpan), 0);
span.removeSpan(urlSpan);
}
mTermsAndCondis.setText(span);
mTermsAndCondis.setMovementMethod(LinkMovementMethod.getInstance());
}
@Override
public void onClick(View v) {
if (mCallback == null) return;
switch (v.getId()) {
case R.id.text_forgot_password:
mCallback.onForgotPasswordPressed();
break;
case R.id.text_learn_more:
mCallback.onLearnMorePressed();
break;
default:
// do nothing;
}
}
@Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
if (mCallback == null) return false;
if (actionId == EditorInfo.IME_ACTION_GO) {
validateAndGo();
return true;
}
return false;
}
@Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
if (mCallback == null) return false;
if (keyCode == KeyEvent.KEYCODE_ENTER) {
validateAndGo();
return true;
}
return false;
}
@Override
public void onFocusChange(View v, boolean hasFocus) {
}
private void validateAndGo() {
boolean isValid = isCreateAccount() ? validateCreateAccount() : validateLogin();
if (isValid) {
mCallback.onEnterPressed();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment