ui: Custom password field
Add the ability to reveal text dynamically on password fields during account
creation and credentials screen
diff --git a/res/drawable-hdpi/ic_action_reveal.png b/res/drawable-hdpi/ic_action_reveal.png
new file mode 100755
index 0000000..2fd88e0
--- /dev/null
+++ b/res/drawable-hdpi/ic_action_reveal.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_action_reveal.png b/res/drawable-mdpi/ic_action_reveal.png
new file mode 100755
index 0000000..6f4cc5b
--- /dev/null
+++ b/res/drawable-mdpi/ic_action_reveal.png
Binary files differ
diff --git a/res/drawable-xhdpi/ic_action_reveal.png b/res/drawable-xhdpi/ic_action_reveal.png
new file mode 100755
index 0000000..4e83be4
--- /dev/null
+++ b/res/drawable-xhdpi/ic_action_reveal.png
Binary files differ
diff --git a/res/drawable-xxhdpi/ic_action_reveal.png b/res/drawable-xxhdpi/ic_action_reveal.png
new file mode 100755
index 0000000..02a3d6f
--- /dev/null
+++ b/res/drawable-xxhdpi/ic_action_reveal.png
Binary files differ
diff --git a/res/layout/credentials_pref.xml b/res/layout/credentials_pref.xml
index 883399e..ff7c008 100644
--- a/res/layout/credentials_pref.xml
+++ b/res/layout/credentials_pref.xml
@@ -46,13 +46,11 @@
<requestFocus />
</EditText>
- <EditText
+ <org.sflphone.views.PasswordEditText
android:id="@+id/credentials_password"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:imeOptions="actionNext"
- android:hint="Password..."
- android:inputType="textVisiblePassword" />
+ android:imeOptions="actionNext" />
<EditText
android:id="@+id/credentials_realm"
diff --git a/res/layout/frag_account_creation.xml b/res/layout/frag_account_creation.xml
index 2315280..830dd63 100644
--- a/res/layout/frag_account_creation.xml
+++ b/res/layout/frag_account_creation.xml
@@ -37,7 +37,7 @@
android:singleLine="true"
android:typeface="monospace" />
- <EditText
+ <org.sflphone.views.PasswordEditText
android:id="@+id/password"
android:layout_width="match_parent"
android:layout_height="wrap_content"
diff --git a/res/layout/password_edittext.xml b/res/layout/password_edittext.xml
new file mode 100644
index 0000000..edd4f12
--- /dev/null
+++ b/res/layout/password_edittext.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" >
+
+ <EditText
+ android:id="@+id/password_edittext"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:singleLine="true"
+ android:typeface="sans"
+ android:hint="@string/prompt_password" />
+
+ <Button
+ android:id="@+id/password_visibility"
+ android:layout_width="30dip"
+ android:layout_height="30dip"
+ android:layout_alignBaseline="@+id/password_edittext"
+ android:layout_alignParentRight="true"
+ android:layout_marginRight="5dip"
+ android:background="@drawable/ic_action_reveal" />
+
+</RelativeLayout>
\ No newline at end of file
diff --git a/src/org/sflphone/fragments/AccountCreationFragment.java b/src/org/sflphone/fragments/AccountCreationFragment.java
index 7aed9da..f96a82e 100644
--- a/src/org/sflphone/fragments/AccountCreationFragment.java
+++ b/src/org/sflphone/fragments/AccountCreationFragment.java
@@ -21,6 +21,7 @@
import android.widget.TextView;
import android.widget.TextView.OnEditorActionListener;
import android.widget.Toast;
+import org.sflphone.views.PasswordEditText;
public class AccountCreationFragment extends Fragment {
@@ -34,7 +35,7 @@
private EditText mAliasView;
private EditText mHostnameView;
private EditText mUsernameView;
- private EditText mPasswordView;
+ private PasswordEditText mPasswordView;
private Callbacks mCallbacks = sDummyCallbacks;
private static Callbacks sDummyCallbacks = new Callbacks() {
@@ -63,9 +64,9 @@
mAliasView = (EditText) inflatedView.findViewById(R.id.alias);
mHostnameView = (EditText) inflatedView.findViewById(R.id.hostname);
mUsernameView = (EditText) inflatedView.findViewById(R.id.username);
- mPasswordView = (EditText) inflatedView.findViewById(R.id.password);
+ mPasswordView = (PasswordEditText) inflatedView.findViewById(R.id.password);
- mPasswordView.setOnEditorActionListener(new OnEditorActionListener() {
+ mPasswordView.getEdit_text().setOnEditorActionListener(new OnEditorActionListener() {
@Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
diff --git a/src/org/sflphone/views/CredentialsPreference.java b/src/org/sflphone/views/CredentialsPreference.java
index 93d0df8..5b18f1d 100644
--- a/src/org/sflphone/views/CredentialsPreference.java
+++ b/src/org/sflphone/views/CredentialsPreference.java
@@ -56,7 +56,9 @@
public class CredentialsPreference extends DialogPreference {
- EditText mUsernameField, mPasswordField, mRealmField;
+ EditText mUsernameField;
+ PasswordEditText mPasswordField;
+ EditText mRealmField;
public CredentialsPreference(Context context, AttributeSet attrs) {
super(context, attrs);
@@ -70,13 +72,13 @@
View view = inflater.inflate(R.layout.credentials_pref, null);
mUsernameField = (EditText) view.findViewById(R.id.credentials_username);
- mPasswordField = (EditText) view.findViewById(R.id.credentials_password);
+ mPasswordField = (PasswordEditText) view.findViewById(R.id.credentials_password);
mRealmField = (EditText) view.findViewById(R.id.credentials_realm);
if (getExtras().getSerializable(CredentialsManager.CURRENT_CRED) != null) {
HashMap<String, String> details = (HashMap<String, String>) getExtras().getSerializable(CredentialsManager.CURRENT_CRED);
mUsernameField.setText(details.get(AccountCredentials.CONFIG_ACCOUNT_USERNAME));
- mPasswordField.setText(details.get(AccountCredentials.CONFIG_ACCOUNT_PASSWORD));
+ mPasswordField.getEdit_text().setText(details.get(AccountCredentials.CONFIG_ACCOUNT_PASSWORD));
mRealmField.setText(details.get(AccountCredentials.CONFIG_ACCOUNT_REALM));
}
diff --git a/src/org/sflphone/views/PasswordEditText.java b/src/org/sflphone/views/PasswordEditText.java
new file mode 100644
index 0000000..e15ce65
--- /dev/null
+++ b/src/org/sflphone/views/PasswordEditText.java
@@ -0,0 +1,115 @@
+package org.sflphone.views;
+
+import android.content.Context;
+import android.text.Editable;
+import android.text.TextWatcher;
+import android.text.method.HideReturnsTransformationMethod;
+import android.text.method.PasswordTransformationMethod;
+import android.util.AttributeSet;
+import android.view.LayoutInflater;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.inputmethod.EditorInfo;
+import android.widget.Button;
+import android.widget.EditText;
+import android.widget.RelativeLayout;
+import org.sflphone.R;
+
+/**
+ * Created by lisional on 06/04/14.
+ */
+public class PasswordEditText extends RelativeLayout {
+ LayoutInflater inflater = null;
+ EditText edit_text;
+ Button btn_clear;
+
+ public PasswordEditText(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ initViews();
+ }
+
+ public PasswordEditText(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ initViews();
+ }
+
+ public PasswordEditText(Context context) {
+ super(context);
+ // TODO Auto-generated constructor stub
+ initViews();
+ }
+
+ void initViews() {
+ inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+ inflater.inflate(R.layout.password_edittext, this, true);
+ edit_text = (EditText) findViewById(R.id.password_edittext);
+ edit_text.setSingleLine();
+ edit_text.setImeOptions(EditorInfo.IME_ACTION_DONE);
+ btn_clear = (Button) findViewById(R.id.password_visibility);
+ btn_clear.setVisibility(RelativeLayout.INVISIBLE);
+ revealText();
+ edit_text.setTransformationMethod(PasswordTransformationMethod.getInstance());
+ showHideClearButton();
+ }
+
+ void revealText() {
+ btn_clear.setOnTouchListener(new View.OnTouchListener() {
+ @Override
+ public boolean onTouch(View v, MotionEvent event) {
+ switch(event.getAction()) {
+ case MotionEvent.ACTION_DOWN:
+ edit_text.setTransformationMethod(HideReturnsTransformationMethod.getInstance());
+ edit_text.setSelection(edit_text.getText().length());
+ return true; // if you want to handle the touch event
+ case MotionEvent.ACTION_UP:
+ // RELEASED
+ edit_text.setTransformationMethod(PasswordTransformationMethod.getInstance());
+ edit_text.setSelection(edit_text.getText().length());
+ return true; // if you want to handle the touch event
+ }
+ return false;
+ }
+ });
+ }
+
+ void showHideClearButton() {
+ edit_text.addTextChangedListener(new TextWatcher() {
+
+ @Override
+ public void onTextChanged(CharSequence s, int start, int before, int count) {
+ if (s.length() > 0)
+ btn_clear.setVisibility(RelativeLayout.VISIBLE);
+ else
+ btn_clear.setVisibility(RelativeLayout.INVISIBLE);
+ }
+
+ @Override
+ public void beforeTextChanged(CharSequence s, int start, int count, int after) {
+ }
+
+ @Override
+ public void afterTextChanged(Editable s) {
+ }
+ });
+ }
+
+ public Editable getText() {
+ Editable text = edit_text.getText();
+ return text;
+ }
+
+ public void setInputType(int typeClassNumber) {
+ edit_text.setFocusableInTouchMode(true);
+ edit_text.requestFocus();
+ edit_text.setInputType(typeClassNumber);
+ }
+
+ public EditText getEdit_text() {
+ return edit_text;
+ }
+
+ public void setError(String string) {
+ edit_text.setError(string);
+ edit_text.requestFocus();
+ }
+}
\ No newline at end of file