Merge pull request #177 from owncloud/login_view_layout_improvements

Login view layout improvements
This commit is contained in:
David A. Velasco 2013-06-12 02:16:08 -07:00
commit 9aa69ac474
7 changed files with 109 additions and 90 deletions

View file

@ -4,6 +4,6 @@
<classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.LIBRARIES"/>
<classpathentry kind="src" path="src"/>
<classpathentry kind="src" path="gen"/>
<classpathentry kind="con" path="com.android.ide.eclipse.adt.DEPENDENCIES"/>
<classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.DEPENDENCIES"/>
<classpathentry kind="output" path="bin/classes"/>
</classpath>

BIN
res/drawable/ic_hide.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

BIN
res/drawable/ic_view.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

View file

@ -122,28 +122,16 @@
android:hint="@string/auth_username"
android:inputType="textNoSuggestions" />
<FrameLayout
<EditText
android:id="@+id/account_password"
android:layout_width="match_parent"
android:layout_height="wrap_content"
>
<EditText
android:id="@+id/account_password"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ems="10"
android:hint="@string/auth_password"
android:inputType="textPassword"/>
<ImageView
android:id="@+id/viewPasswordButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right|center_vertical"
android:src="@android:drawable/ic_menu_view"
android:onClick="onViewPasswordClick"
android:visibility="invisible" />
</FrameLayout>
android:ems="10"
android:hint="@string/auth_password"
android:inputType="textPassword"
android:drawablePadding="5dp"
/>
<TextView
android:id="@+id/auth_status_text"
android:layout_width="match_parent"

View file

@ -101,28 +101,15 @@
android:hint="@string/auth_username"
android:inputType="textNoSuggestions" />
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<EditText
android:id="@+id/account_password"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ems="10"
android:hint="@string/auth_password"
android:inputType="textPassword" />
<ImageView
android:id="@+id/viewPasswordButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right|center_vertical"
android:onClick="onViewPasswordClick"
android:src="@android:drawable/ic_menu_view"
android:visibility="invisible" />
</FrameLayout>
<EditText
android:id="@+id/account_password"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:drawablePadding="5dp"
android:ems="10"
android:hint="@string/auth_password"
android:inputType="textPassword" />
<TextView
android:id="@+id/auth_status_text"
android:layout_width="match_parent"

View file

@ -61,7 +61,6 @@ import android.view.inputmethod.EditorInfo;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.TextView.OnEditorActionListener;
@ -95,8 +94,10 @@ implements OnRemoteOperationListener, OnSslValidatorListener, OnFocusChangeList
private static final String KEY_SERVER_STATUS_TEXT = "SERVER_STATUS_TEXT";
private static final String KEY_SERVER_STATUS_ICON = "SERVER_STATUS_ICON";
private static final String KEY_IS_SSL_CONN = "IS_SSL_CONN";
private static final String KEY_PASSWORD_VISIBLE = "PASSWORD_VISIBLE";
private static final String KEY_AUTH_STATUS_TEXT = "AUTH_STATUS_TEXT";
private static final String KEY_AUTH_STATUS_ICON = "AUTH_STATUS_ICON";
private static final String KEY_REFRESH_BUTTON_ENABLED = "KEY_REFRESH_BUTTON_ENABLED";
private static final String OAUTH_MODE_ON = "on";
private static final String OAUTH_MODE_OFF = "off";
@ -131,7 +132,6 @@ implements OnRemoteOperationListener, OnSslValidatorListener, OnFocusChangeList
private byte mAction;
private Account mAccount;
private ImageView mViewPasswordButton;
private EditText mHostUrlInput;
private EditText mUsernameInput;
private EditText mPasswordInput;
@ -142,6 +142,8 @@ implements OnRemoteOperationListener, OnSslValidatorListener, OnFocusChangeList
private TextView mOAuthAuthEndpointText;
private TextView mOAuthTokenEndpointText;
private boolean mRefreshButtonEnabled;
/**
@ -156,7 +158,6 @@ implements OnRemoteOperationListener, OnSslValidatorListener, OnFocusChangeList
/// set view and get references to view elements
setContentView(R.layout.account_setup);
mViewPasswordButton = (ImageView) findViewById(R.id.viewPasswordButton);
mHostUrlInput = (EditText) findViewById(R.id.hostUrlInput);
mUsernameInput = (EditText) findViewById(R.id.account_username);
mPasswordInput = (EditText) findViewById(R.id.account_password);
@ -216,7 +217,10 @@ implements OnRemoteOperationListener, OnSslValidatorListener, OnFocusChangeList
mIsSslConn = savedInstanceState.getBoolean(KEY_IS_SSL_CONN);
mAuthStatusText = savedInstanceState.getInt(KEY_AUTH_STATUS_TEXT);
mAuthStatusIcon = savedInstanceState.getInt(KEY_AUTH_STATUS_ICON);
if (savedInstanceState.getBoolean(KEY_PASSWORD_VISIBLE, false)) {
showPassword();
}
/// server data
String ocVersion = savedInstanceState.getString(KEY_OC_VERSION);
if (ocVersion != null) {
@ -230,13 +234,16 @@ implements OnRemoteOperationListener, OnSslValidatorListener, OnFocusChangeList
// check if server check was interrupted by a configuration change
if (savedInstanceState.getBoolean(KEY_SERVER_CHECK_IN_PROGRESS, false)) {
checkOcServer();
}
}
// refresh button enabled
mRefreshButtonEnabled = savedInstanceState.getBoolean(KEY_REFRESH_BUTTON_ENABLED);
}
showServerStatus();
showAuthStatus();
if (mServerIsChecked && !mServerIsValid) showRefreshButton();
if (mServerIsChecked && !mServerIsValid && mRefreshButtonEnabled) showRefreshButton();
mOkButton.setEnabled(mServerIsValid); // state not automatically recovered in configuration changes
if (!OAUTH_MODE_OPTIONAL.equals(getString(R.string.oauth2_mode))) {
@ -261,7 +268,9 @@ implements OnRemoteOperationListener, OnSslValidatorListener, OnFocusChangeList
mHostUrlInput.setOnTouchListener(new RightDrawableOnTouchListener() {
@Override
public boolean onDrawableTouch(final MotionEvent event) {
AuthenticatorActivity.this.onRefreshClick(mHostUrlInput);
if (event.getAction() == MotionEvent.ACTION_UP) {
AuthenticatorActivity.this.onRefreshClick();
}
return true;
}
});
@ -283,7 +292,16 @@ implements OnRemoteOperationListener, OnSslValidatorListener, OnFocusChangeList
});
mPasswordInput.setOnFocusChangeListener(this);
mPasswordInput.setImeOptions(EditorInfo.IME_ACTION_DONE);
mPasswordInput.setOnEditorActionListener(this);
mPasswordInput.setOnEditorActionListener(this);
mPasswordInput.setOnTouchListener(new RightDrawableOnTouchListener() {
@Override
public boolean onDrawableTouch(final MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_UP) {
AuthenticatorActivity.this.onViewPasswordClick();
}
return true;
}
});
}
/**
@ -305,6 +323,7 @@ implements OnRemoteOperationListener, OnSslValidatorListener, OnFocusChangeList
outState.putBoolean(KEY_SERVER_CHECKED, mServerIsChecked);
outState.putBoolean(KEY_SERVER_CHECK_IN_PROGRESS, (!mServerIsValid && mOcServerChkOperation != null));
outState.putBoolean(KEY_IS_SSL_CONN, mIsSslConn);
outState.putBoolean(KEY_PASSWORD_VISIBLE, isPasswordVisible());
outState.putInt(KEY_AUTH_STATUS_ICON, mAuthStatusIcon);
outState.putInt(KEY_AUTH_STATUS_TEXT, mAuthStatusText);
@ -318,6 +337,9 @@ implements OnRemoteOperationListener, OnSslValidatorListener, OnFocusChangeList
if (mAccount != null) {
outState.putParcelable(KEY_ACCOUNT, mAccount);
}
// refresh button enabled
outState.putBoolean(KEY_REFRESH_BUTTON_ENABLED, mRefreshButtonEnabled);
}
@ -394,6 +416,9 @@ implements OnRemoteOperationListener, OnSslValidatorListener, OnFocusChangeList
if (view.getId() == R.id.hostUrlInput) {
if (!hasFocus) {
onUrlInputFocusLost((TextView) view);
if (!mServerIsValid) {
showRefreshButton();
}
}
else {
hideRefreshButton();
@ -459,16 +484,43 @@ implements OnRemoteOperationListener, OnSslValidatorListener, OnFocusChangeList
*/
private void onPasswordFocusChanged(TextView passwordInput, boolean hasFocus) {
if (hasFocus) {
mViewPasswordButton.setVisibility(View.VISIBLE);
showViewPasswordButton();
} else {
int input_type = InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD;
passwordInput.setInputType(input_type);
mViewPasswordButton.setVisibility(View.INVISIBLE);
hidePassword();
hidePasswordButton();
}
}
private void showViewPasswordButton() {
//int drawable = android.R.drawable.ic_menu_view;
int drawable = R.drawable.ic_view;
if (isPasswordVisible()) {
//drawable = android.R.drawable.ic_secure;
drawable = R.drawable.ic_hide;
}
mPasswordInput.setCompoundDrawablesWithIntrinsicBounds(0, 0, drawable, 0);
}
private boolean isPasswordVisible() {
return ((mPasswordInput.getInputType() & InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD) == InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD);
}
private void hidePasswordButton() {
mPasswordInput.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0);
}
private void showPassword() {
mPasswordInput.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD);
showViewPasswordButton();
}
private void hidePassword() {
mPasswordInput.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD);
showViewPasswordButton();
}
/**
* Cancels the authenticator activity
*
@ -1100,10 +1152,12 @@ implements OnRemoteOperationListener, OnSslValidatorListener, OnFocusChangeList
private void showRefreshButton() {
mHostUrlInput.setCompoundDrawablesWithIntrinsicBounds(0, 0, R.drawable.ic_action_refresh_black, 0);
mRefreshButtonEnabled = true;
}
private void hideRefreshButton() {
mHostUrlInput.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0);
mRefreshButtonEnabled = false;
}
/**
@ -1113,30 +1167,24 @@ implements OnRemoteOperationListener, OnSslValidatorListener, OnFocusChangeList
*
* @param view Refresh 'button'
*/
public void onRefreshClick(View view) {
public void onRefreshClick() {
checkOcServer();
}
/**
* Called when the eye icon in the password field is clicked.
*
* Toggles the visibility of the password in the field.
*
* @param view 'View password' 'button'
*/
public void onViewPasswordClick(View view) {
public void onViewPasswordClick() {
int selectionStart = mPasswordInput.getSelectionStart();
int selectionEnd = mPasswordInput.getSelectionEnd();
int input_type = mPasswordInput.getInputType();
if ((input_type & InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD) == InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD) {
input_type = InputType.TYPE_CLASS_TEXT
| InputType.TYPE_TEXT_VARIATION_PASSWORD;
if (isPasswordVisible()) {
hidePassword();
} else {
input_type = InputType.TYPE_CLASS_TEXT
| InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD;
showPassword();
}
mPasswordInput.setInputType(input_type);
mPasswordInput.setSelection(selectionStart, selectionEnd);
}
@ -1167,13 +1215,11 @@ implements OnRemoteOperationListener, OnSslValidatorListener, OnFocusChangeList
mOAuthTokenEndpointText.setVisibility(View.VISIBLE);
mUsernameInput.setVisibility(View.GONE);
mPasswordInput.setVisibility(View.GONE);
mViewPasswordButton.setVisibility(View.GONE);
} else {
mOAuthAuthEndpointText.setVisibility(View.GONE);
mOAuthTokenEndpointText.setVisibility(View.GONE);
mUsernameInput.setVisibility(View.VISIBLE);
mPasswordInput.setVisibility(View.VISIBLE);
mViewPasswordButton.setVisibility(View.INVISIBLE);
}
}
@ -1214,30 +1260,28 @@ implements OnRemoteOperationListener, OnSslValidatorListener, OnFocusChangeList
private abstract static class RightDrawableOnTouchListener implements OnTouchListener {
private int fuzz = 10;
private int fuzz = 75;
/**
* {@inheritDoc}
*/
@Override
public boolean onTouch(View view, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
Drawable rightDrawable = null;
if (view instanceof TextView) {
Drawable[] drawables = ((TextView)view).getCompoundDrawables();
if (drawables.length > 2) {
rightDrawable = drawables[2];
}
Drawable rightDrawable = null;
if (view instanceof TextView) {
Drawable[] drawables = ((TextView)view).getCompoundDrawables();
if (drawables.length > 2) {
rightDrawable = drawables[2];
}
if (rightDrawable != null) {
final int x = (int) event.getX();
final int y = (int) event.getY();
final Rect bounds = rightDrawable.getBounds();
if (x >= (view.getRight() - bounds.width() - fuzz) && x <= (view.getRight() - view.getPaddingRight() + fuzz)
&& y >= (view.getPaddingTop() - fuzz) && y <= (view.getHeight() - view.getPaddingBottom()) + fuzz) {
return onDrawableTouch(event);
}
}
if (rightDrawable != null) {
final int x = (int) event.getX();
final int y = (int) event.getY();
final Rect bounds = rightDrawable.getBounds();
if (x >= (view.getRight() - bounds.width() - fuzz) && x <= (view.getRight() - view.getPaddingRight() + fuzz)
&& y >= (view.getPaddingTop() - fuzz) && y <= (view.getHeight() - view.getPaddingBottom()) + fuzz) {
return onDrawableTouch(event);
}
}
return false;

View file

@ -2,8 +2,8 @@
<classpath>
<classpathentry combineaccessrules="false" kind="src" path="/owncloud-android"/>
<classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
<classpathentry kind="con" path="com.android.ide.eclipse.adt.LIBRARIES"/>
<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/4"/>
<classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.LIBRARIES"/>
<classpathentry exported="true" kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/4"/>
<classpathentry kind="src" path="src"/>
<classpathentry kind="src" path="gen"/>
<classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.DEPENDENCIES"/>