Change ShowHidePasswordEditText to TextInputEditText.

change the input fields in the AccountActivity to use the TextInputLayout.

Rollback format and change toggle tint
This commit is contained in:
SoyaLeaf 2018-02-17 14:09:21 +08:00 committed by Daniel Gultsch
parent 63c4fe6f02
commit 63fb5d98cc
10 changed files with 194 additions and 165 deletions

1
.gitignore vendored
View file

@ -7,6 +7,7 @@ src/playstore/res/values/gcm.xml
# https://github.com/github/gitignore/blob/master/Gradle.gitignore # https://github.com/github/gitignore/blob/master/Gradle.gitignore
.gradle/ .gradle/
build/ build/
gradle.properties
captures/ captures/
signing.properties signing.properties
# Ignore Gradle GUI config # Ignore Gradle GUI config

View file

@ -41,6 +41,7 @@ dependencies {
implementation "com.android.support:appcompat-v7:$supportLibVersion" implementation "com.android.support:appcompat-v7:$supportLibVersion"
implementation "com.android.support:support-emoji-appcompat:$supportLibVersion" implementation "com.android.support:support-emoji-appcompat:$supportLibVersion"
implementation "com.android.support:support-emoji:$supportLibVersion" implementation "com.android.support:support-emoji:$supportLibVersion"
implementation "com.android.support:design:$supportLibVersion"
freeImplementation "com.android.support:support-emoji-bundled:$supportLibVersion" freeImplementation "com.android.support:support-emoji-bundled:$supportLibVersion"
implementation 'org.bouncycastle:bcmail-jdk15on:1.58' implementation 'org.bouncycastle:bcmail-jdk15on:1.58'
implementation 'org.jitsi:org.otr4j:0.22' implementation 'org.jitsi:org.otr4j:0.22'
@ -53,7 +54,6 @@ dependencies {
implementation 'com.makeramen:roundedimageview:2.3.0' implementation 'com.makeramen:roundedimageview:2.3.0'
implementation "com.wefika:flowlayout:0.4.1" implementation "com.wefika:flowlayout:0.4.1"
implementation 'net.ypresto.androidtranscoder:android-transcoder:0.2.0' implementation 'net.ypresto.androidtranscoder:android-transcoder:0.2.0'
implementation 'com.github.scottyab:showhidepasswordedittext:0.8'
} }
ext { ext {

View file

@ -1 +1,18 @@
## Project-wide Gradle settings.
#
# For more details on how to configure your build environment visit
# http://www.gradle.org/docs/current/userguide/build_environment.html
#
# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
# Default value: -Xmx1024m -XX:MaxPermSize=256m
# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
#
# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
# org.gradle.parallel=true
#Sat Feb 17 18:50:27 CST 2018
systemProp.http.proxyHost=127.0.0.1
org.gradle.jvmargs=-Xmx2048M org.gradle.jvmargs=-Xmx2048M
systemProp.http.proxyPort=1080

View file

@ -5,7 +5,6 @@ import android.os.Bundle;
import android.view.View; import android.view.View;
import android.widget.Button; import android.widget.Button;
import android.widget.EditText; import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast; import android.widget.Toast;
import eu.siacs.conversations.R; import eu.siacs.conversations.R;
@ -39,7 +38,6 @@ public class ChangePasswordActivity extends XmppActivity implements XmppConnecti
} }
} }
}; };
private TextView mCurrentPasswordLabel;
private EditText mCurrentPassword; private EditText mCurrentPassword;
private EditText mNewPassword; private EditText mNewPassword;
private Account mAccount; private Account mAccount;
@ -48,10 +46,8 @@ public class ChangePasswordActivity extends XmppActivity implements XmppConnecti
void onBackendConnected() { void onBackendConnected() {
this.mAccount = extractAccount(getIntent()); this.mAccount = extractAccount(getIntent());
if (this.mAccount != null && this.mAccount.isOptionSet(Account.OPTION_MAGIC_CREATE)) { if (this.mAccount != null && this.mAccount.isOptionSet(Account.OPTION_MAGIC_CREATE)) {
this.mCurrentPasswordLabel.setVisibility(View.GONE);
this.mCurrentPassword.setVisibility(View.GONE); this.mCurrentPassword.setVisibility(View.GONE);
} else { } else {
this.mCurrentPasswordLabel.setVisibility(View.VISIBLE);
this.mCurrentPassword.setVisibility(View.VISIBLE); this.mCurrentPassword.setVisibility(View.VISIBLE);
} }
} }
@ -64,7 +60,6 @@ public class ChangePasswordActivity extends XmppActivity implements XmppConnecti
mCancelButton.setOnClickListener(view -> finish()); mCancelButton.setOnClickListener(view -> finish());
this.mChangePasswordButton = findViewById(R.id.right_button); this.mChangePasswordButton = findViewById(R.id.right_button);
this.mChangePasswordButton.setOnClickListener(this.mOnChangePasswordButtonClicked); this.mChangePasswordButton.setOnClickListener(this.mOnChangePasswordButtonClicked);
this.mCurrentPasswordLabel = findViewById(R.id.current_password_label);
this.mCurrentPassword = findViewById(R.id.current_password); this.mCurrentPassword = findViewById(R.id.current_password);
this.mCurrentPassword.setCustomSelectionActionModeCallback(new DisabledActionModeCallback()); this.mCurrentPassword.setCustomSelectionActionModeCallback(new DisabledActionModeCallback());
this.mNewPassword = findViewById(R.id.new_password); this.mNewPassword = findViewById(R.id.new_password);

View file

@ -1,7 +1,5 @@
package eu.siacs.conversations.ui; package eu.siacs.conversations.ui;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AlertDialog.Builder;
import android.app.PendingIntent; import android.app.PendingIntent;
import android.content.ActivityNotFoundException; import android.content.ActivityNotFoundException;
import android.content.DialogInterface; import android.content.DialogInterface;
@ -10,11 +8,14 @@ import android.content.SharedPreferences;
import android.graphics.Bitmap; import android.graphics.Bitmap;
import android.net.Uri; import android.net.Uri;
import android.os.Bundle; import android.os.Bundle;
import android.os.Handler;
import android.provider.Settings; import android.provider.Settings;
import android.security.KeyChain; import android.security.KeyChain;
import android.security.KeyChainAliasCallback; import android.security.KeyChainAliasCallback;
import android.support.v4.content.ContextCompat; import android.support.v4.content.ContextCompat;
import android.support.v7.app.ActionBar; import android.support.v7.app.ActionBar;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AlertDialog.Builder;
import android.text.Editable; import android.text.Editable;
import android.text.TextWatcher; import android.text.TextWatcher;
import android.view.Menu; import android.view.Menu;
@ -50,9 +51,9 @@ import eu.siacs.conversations.crypto.axolotl.AxolotlService;
import eu.siacs.conversations.crypto.axolotl.XmppAxolotlSession; import eu.siacs.conversations.crypto.axolotl.XmppAxolotlSession;
import eu.siacs.conversations.entities.Account; import eu.siacs.conversations.entities.Account;
import eu.siacs.conversations.services.BarcodeProvider; import eu.siacs.conversations.services.BarcodeProvider;
import eu.siacs.conversations.services.XmppConnectionService.OnCaptchaRequested;
import eu.siacs.conversations.services.XmppConnectionService; import eu.siacs.conversations.services.XmppConnectionService;
import eu.siacs.conversations.services.XmppConnectionService.OnAccountUpdate; import eu.siacs.conversations.services.XmppConnectionService.OnAccountUpdate;
import eu.siacs.conversations.services.XmppConnectionService.OnCaptchaRequested;
import eu.siacs.conversations.ui.adapter.KnownHostsAdapter; import eu.siacs.conversations.ui.adapter.KnownHostsAdapter;
import eu.siacs.conversations.ui.widget.DisabledActionModeCallback; import eu.siacs.conversations.ui.widget.DisabledActionModeCallback;
import eu.siacs.conversations.utils.CryptoHelper; import eu.siacs.conversations.utils.CryptoHelper;
@ -272,6 +273,7 @@ public class EditAccountActivity extends OmemoActivity implements OnAccountUpdat
private boolean mSavedInstanceInit = false; private boolean mSavedInstanceInit = false;
private Button mClearDevicesButton; private Button mClearDevicesButton;
private XmppUri pendingUri = null; private XmppUri pendingUri = null;
private boolean mUseTor;
public void refreshUiReal() { public void refreshUiReal() {
invalidateOptionsMenu(); invalidateOptionsMenu();
@ -356,6 +358,24 @@ public class EditAccountActivity extends OmemoActivity implements OnAccountUpdat
} }
}; };
private View.OnFocusChangeListener mEditTextFocusListener = new View.OnFocusChangeListener() {
@Override
public void onFocusChange(View view, boolean b) {
EditText et = (EditText) view;
if (b) {
int resId = mUsernameMode ? R.string.username : R.string.account_settings_example_jabber_id;
if (view.getId() == R.id.hostname) {
resId = mUseTor ? R.string.hostname_or_onion : R.string.hostname_example;
}
final int res = resId;
new Handler().postDelayed(() -> et.setHint(res),200);
} else {
et.setHint(null);
}
}
};
private final OnClickListener mAvatarClickListener = new OnClickListener() { private final OnClickListener mAvatarClickListener = new OnClickListener() {
@Override @Override
public void onClick(final View view) { public void onClick(final View view) {
@ -514,7 +534,7 @@ public class EditAccountActivity extends OmemoActivity implements OnAccountUpdat
setContentView(R.layout.activity_edit_account); setContentView(R.layout.activity_edit_account);
this.mAccountJid = (AutoCompleteTextView) findViewById(R.id.account_jid); this.mAccountJid = (AutoCompleteTextView) findViewById(R.id.account_jid);
this.mAccountJid.addTextChangedListener(this.mTextWatcher); this.mAccountJid.addTextChangedListener(this.mTextWatcher);
this.mAccountJidLabel = (TextView) findViewById(R.id.account_jid_label); this.mAccountJid.setOnFocusChangeListener(this.mEditTextFocusListener);
this.mPassword = (EditText) findViewById(R.id.account_password); this.mPassword = (EditText) findViewById(R.id.account_password);
this.mPassword.addTextChangedListener(this.mTextWatcher); this.mPassword.addTextChangedListener(this.mTextWatcher);
this.mAvatar = (ImageView) findViewById(R.id.avater); this.mAvatar = (ImageView) findViewById(R.id.avater);
@ -553,6 +573,7 @@ public class EditAccountActivity extends OmemoActivity implements OnAccountUpdat
this.mNamePort = (LinearLayout) findViewById(R.id.name_port); this.mNamePort = (LinearLayout) findViewById(R.id.name_port);
this.mHostname = (EditText) findViewById(R.id.hostname); this.mHostname = (EditText) findViewById(R.id.hostname);
this.mHostname.addTextChangedListener(mTextWatcher); this.mHostname.addTextChangedListener(mTextWatcher);
this.mHostname.setOnFocusChangeListener(mEditTextFocusListener);
this.mClearDevicesButton = (Button) findViewById(R.id.clear_devices); this.mClearDevicesButton = (Button) findViewById(R.id.clear_devices);
this.mClearDevicesButton.setOnClickListener(new OnClickListener() { this.mClearDevicesButton.setOnClickListener(new OnClickListener() {
@Override @Override
@ -668,9 +689,8 @@ public class EditAccountActivity extends OmemoActivity implements OnAccountUpdat
} }
} }
SharedPreferences preferences = getPreferences(); SharedPreferences preferences = getPreferences();
boolean useTor = Config.FORCE_ORBOT || preferences.getBoolean("use_tor", false); mUseTor = Config.FORCE_ORBOT || preferences.getBoolean("use_tor", false);
this.mShowOptions = useTor || preferences.getBoolean("show_connection_options", false); this.mShowOptions = mUseTor || preferences.getBoolean("show_connection_options", false);
mHostname.setHint(useTor ? R.string.hostname_or_onion : R.string.hostname_example);
this.mNamePort.setVisibility(mShowOptions ? View.VISIBLE : View.GONE); this.mNamePort.setVisibility(mShowOptions ? View.VISIBLE : View.GONE);
} }

View file

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M12,4.5C7,4.5 2.73,7.61 1,12c1.73,4.39 6,7.5 11,7.5s9.27,-3.11 11,-7.5c-1.73,-4.39 -6,-7.5 -11,-7.5zM12,17c-2.76,0 -5,-2.24 -5,-5s2.24,-5 5,-5 5,2.24 5,5 -2.24,5 -5,5zM12,9c-1.66,0 -3,1.34 -3,3s1.34,3 3,3 3,-1.34 3,-3 -1.34,-3 -3,-3z"/>
</vector>

View file

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M12,7c2.76,0 5,2.24 5,5 0,0.65 -0.13,1.26 -0.36,1.83l2.92,2.92c1.51,-1.26 2.7,-2.89 3.43,-4.75 -1.73,-4.39 -6,-7.5 -11,-7.5 -1.4,0 -2.74,0.25 -3.98,0.7l2.16,2.16C10.74,7.13 11.35,7 12,7zM2,4.27l2.28,2.28 0.46,0.46C3.08,8.3 1.78,10.02 1,12c1.73,4.39 6,7.5 11,7.5 1.55,0 3.03,-0.3 4.38,-0.84l0.42,0.42L19.73,22 21,20.73 3.27,3 2,4.27zM7.53,9.8l1.55,1.55c-0.05,0.21 -0.08,0.43 -0.08,0.65 0,1.66 1.34,3 3,3 0.22,0 0.44,-0.03 0.65,-0.08l1.55,1.55c-0.67,0.33 -1.41,0.53 -2.2,0.53 -2.76,0 -5,-2.24 -5,-5 0,-0.79 0.2,-1.53 0.53,-2.2zM11.84,9.02l3.15,3.15 0.02,-0.16c0,-1.66 -1.34,-3 -3,-3l-0.17,0.01z"/>
</vector>

View file

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/ic_visibility" android:state_checked="true" />
<item android:drawable="@drawable/ic_visibility_off" android:state_checked="false" />
</selector>

View file

@ -21,56 +21,44 @@
android:orientation="vertical" android:orientation="vertical"
android:padding="@dimen/infocard_padding"> android:padding="@dimen/infocard_padding">
<TextView
android:id="@+id/current_password_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/current_password"
android:textColor="?attr/color_text_primary"
android:textSize="?attr/TextSizeBody"/>
<RelativeLayout <android.support.design.widget.TextInputLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="wrap_content"
android:minHeight="64sp"> app:passwordToggleDrawable="@drawable/visibility_toggle_drawable"
app:passwordToggleEnabled="true"
app:passwordToggleTint="?attr/color_text_secondary">
<com.scottyab.showhidepasswordedittext.ShowHidePasswordEditText <android.support.design.widget.TextInputEditText
android:id="@+id/current_password" android:id="@+id/current_password"
android:layout_alignParentTop="true"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:hint="@string/password" android:layout_alignParentTop="true"
android:hint="@string/current_password"
android:inputType="textPassword" android:inputType="textPassword"
android:textColor="?attr/color_text_primary" android:textColor="?attr/color_text_primary"
android:textColorHint="?attr/color_text_secondary" android:textColorHint="?attr/color_text_secondary"
android:textSize="?attr/TextSizeBody"
app:tint_color="?attr/color_text_secondary"/>
</RelativeLayout>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/new_password"
android:textColor="?attr/color_text_primary"
android:textSize="?attr/TextSizeBody" /> android:textSize="?attr/TextSizeBody" />
</android.support.design.widget.TextInputLayout>
<RelativeLayout <android.support.design.widget.TextInputLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="wrap_content"
android:minHeight="56sp"> app:passwordToggleDrawable="@drawable/visibility_toggle_drawable"
app:passwordToggleEnabled="true"
app:passwordToggleTint="?attr/color_text_secondary">
<com.scottyab.showhidepasswordedittext.ShowHidePasswordEditText <android.support.design.widget.TextInputEditText
android:id="@+id/new_password" android:id="@+id/new_password"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_alignParentTop="true" android:layout_alignParentTop="true"
android:hint="@string/password" android:hint="@string/new_password"
android:inputType="textPassword" android:inputType="textPassword"
android:textColor="?attr/color_text_primary" android:textColor="?attr/color_text_primary"
android:textColorHint="?attr/color_text_secondary" android:textColorHint="?attr/color_text_secondary"
android:textSize="?attr/TextSizeBody" android:textSize="?attr/TextSizeBody" />
app:tint_color="?attr/color_text_secondary"/> </android.support.design.widget.TextInputLayout>
</RelativeLayout>
</LinearLayout> </LinearLayout>
</ScrollView> </ScrollView>

View file

@ -45,39 +45,31 @@
android:layout_toRightOf="@+id/avater" android:layout_toRightOf="@+id/avater"
android:orientation="vertical"> android:orientation="vertical">
<TextView <android.support.design.widget.TextInputLayout
android:id="@+id/account_jid_label" android:layout_width="match_parent"
android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/account_settings_jabber_id" android:hint="@string/account_settings_jabber_id">
android:textColor="?attr/color_text_primary"
android:textSize="?attr/TextSizeBody"/>
<AutoCompleteTextView <AutoCompleteTextView
android:id="@+id/account_jid" android:id="@+id/account_jid"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:hint="@string/account_settings_example_jabber_id"
android:inputType="textEmailAddress"
android:imeOptions="actionNext" android:imeOptions="actionNext"
android:inputType="textEmailAddress"
android:textColor="?attr/color_text_primary" android:textColor="?attr/color_text_primary"
android:textColorHint="?attr/color_text_secondary" android:textColorHint="?attr/color_text_secondary"
android:textSize="?attr/TextSizeBody" /> android:textSize="?attr/TextSizeBody" />
</android.support.design.widget.TextInputLayout>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="@string/account_settings_password"
android:textColor="?attr/color_text_primary"
android:textSize="?attr/TextSizeBody"/>
<RelativeLayout <android.support.design.widget.TextInputLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="wrap_content"
android:minHeight="56sp"> app:passwordToggleDrawable="@drawable/visibility_toggle_drawable"
app:passwordToggleEnabled="true"
app:passwordToggleTint="?attr/color_text_secondary">
<com.scottyab.showhidepasswordedittext.ShowHidePasswordEditText <android.support.design.widget.TextInputEditText
android:id="@+id/account_password" android:id="@+id/account_password"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
@ -86,10 +78,8 @@
android:inputType="textPassword" android:inputType="textPassword"
android:textColor="?attr/color_text_primary" android:textColor="?attr/color_text_primary"
android:textColorHint="?attr/color_text_secondary" android:textColorHint="?attr/color_text_secondary"
android:textSize="?attr/TextSizeBody" android:textSize="?attr/TextSizeBody" />
app:tint_color="?attr/color_text_secondary"/> </android.support.design.widget.TextInputLayout>
</RelativeLayout>
<LinearLayout <LinearLayout
android:id="@+id/name_port" android:id="@+id/name_port"
@ -105,38 +95,32 @@
android:layout_weight="0.8" android:layout_weight="0.8"
android:orientation="vertical"> android:orientation="vertical">
<TextView <android.support.design.widget.TextInputLayout
android:id="@+id/textView" android:layout_width="match_parent"
android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/account_settings_hostname" android:hint="@string/account_settings_hostname">
android:textColor="?attr/color_text_primary"
android:textSize="?attr/TextSizeBody"/>
<EditText <EditText
android:id="@+id/hostname" android:id="@+id/hostname"
android:layout_width="fill_parent" android:layout_width="fill_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:hint="@string/hostname_or_onion"
android:inputType="textNoSuggestions" android:inputType="textNoSuggestions"
android:textColor="?attr/color_text_primary" android:textColor="?attr/color_text_primary"
android:textColorHint="?attr/color_text_secondary" android:textColorHint="?attr/color_text_secondary"
android:textSize="?attr/TextSizeBody" /> android:textSize="?attr/TextSizeBody" />
</android.support.design.widget.TextInputLayout>
</LinearLayout> </LinearLayout>
<LinearLayout <LinearLayout
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_weight="0.2" android:layout_weight="0.2"
android:orientation="vertical" android:orientation="vertical">
>
<TextView <android.support.design.widget.TextInputLayout
android:layout_width="wrap_content" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/account_settings_port" android:hint="@string/account_settings_port">
android:textColor="?attr/color_text_primary"
android:textSize="?attr/TextSizeBody"/>
<EditText <EditText
android:id="@+id/port" android:id="@+id/port"
@ -147,6 +131,7 @@
android:textColor="?attr/color_text_primary" android:textColor="?attr/color_text_primary"
android:textColorHint="?attr/color_text_secondary" android:textColorHint="?attr/color_text_secondary"
android:textSize="?attr/TextSizeBody" /> android:textSize="?attr/TextSizeBody" />
</android.support.design.widget.TextInputLayout>
</LinearLayout> </LinearLayout>
</LinearLayout> </LinearLayout>
@ -562,13 +547,14 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_alignParentRight="true" android:layout_alignParentRight="true"
android:layout_centerVertical="true" android:layout_centerVertical="true"
android:alpha="?attr/icon_alpha"
android:background="?android:selectableItemBackground" android:background="?android:selectableItemBackground"
android:contentDescription="@string/copy_otr_clipboard_description" android:contentDescription="@string/copy_otr_clipboard_description"
android:padding="@dimen/image_button_padding" android:padding="@dimen/image_button_padding"
android:src="?attr/icon_copy" android:src="?attr/icon_copy"
android:alpha="?attr/icon_alpha"
android:visibility="visible" /> android:visibility="visible" />
</RelativeLayout> </RelativeLayout>
<RelativeLayout <RelativeLayout
android:id="@+id/axolotl_fingerprint_box" android:id="@+id/axolotl_fingerprint_box"
android:layout_width="wrap_content" android:layout_width="wrap_content"
@ -663,8 +649,7 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:divider="?android:dividerHorizontal" android:divider="?android:dividerHorizontal"
android:orientation="vertical" android:orientation="vertical"
android:showDividers="middle"> android:showDividers="middle"></LinearLayout>
</LinearLayout>
<Button <Button
android:id="@+id/clear_devices" android:id="@+id/clear_devices"