【发布时间】:2018-08-17 14:19:54
【问题描述】:
问题:用户应该能够通过他们的电话号码或用户名(他们在注册时设置的)登录。这两个值都允许用户登录。Edittext 字段需要足够聪明才能确定输入的内容。所以当用户输入数字作为第一个字符时,它应该自动添加国家代码电话号码前缀并插入前缀后键入的字符。
这是我的布局:
<LinearLayout
android:id="@+id/login"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:orientation="vertical">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.design.widget.TextInputLayout
android:id="@+id/emaillayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:animateLayoutChanges="true"
android:background="@drawable/login_field"
android:padding="2dp"
android:paddingStart="5dp"
android:visibility="visible">
<AutoCompleteTextView
android:id="@+id/email"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@android:color/transparent"
android:hint="@string/prompt_email"
android:inputType="textEmailAddress"
android:maxLines="1"
android:padding="2dp"
android:singleLine="true" />
</android.support.design.widget.TextInputLayout>
<android.support.design.widget.TextInputLayout
android:id="@+id/phlayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:animateLayoutChanges="true"
android:background="@drawable/login_field"
android:orientation="horizontal"
android:padding="2dp"
android:paddingStart="5dp"
android:visibility="gone">
<EditText
android:id="@+id/et_ph"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="@android:color/transparent"
android:ems="10"
android:hint="Phone number"
android:inputType="phone" />
</android.support.design.widget.TextInputLayout>
</FrameLayout>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.design.widget.TextInputLayout
android:id="@+id/pwdlayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:background="@drawable/login_field"
android:orientation="horizontal"
android:padding="2dp"
android:paddingStart="5dp">
<EditText
android:id="@+id/password"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@android:color/transparent"
android:hint="@string/prompt_password"
android:imeActionId="6"
android:imeActionLabel="@string/action_sign_in_short"
android:imeOptions="actionUnspecified"
android:inputType="textPassword"
android:maxLines="1"
android:padding="2dp"
android:singleLine="true" />
</android.support.design.widget.TextInputLayout>
<TextView
android:id="@+id/pwdtoggle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end|center_vertical"
android:text="SHOW"
android:layout_marginRight="16dp"
android:paddingTop="10dp"
/>
</FrameLayout>
<Button
android:id="@+id/email_sign_in_button"
style="?android:textAppearanceSmall"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginEnd="5dp"
android:layout_marginStart="5dp"
android:layout_marginTop="16dp"
android:background="@drawable/sausage_button"
android:text="@string/action_sign_in"
android:textStyle="bold" />
</LinearLayout>
这是我在活动中的代码:
emailView.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
public void afterTextChanged(Editable s)
{
if(isNumberOnly(s.toString()))
{
ChangeToPhoneNumber(s.toString());
}
}
});
numberView.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
public void afterTextChanged(Editable s)
{
if(s.length()==0)
{
ChangeToUsername();
}
}
});
}
private void ChangeToPhoneNumber(String s)
{
emaillayout.setVisibility(View.GONE);
phlayout.setVisibility(View.VISIBLE);
numberView.setText("+61" + s);
numberView.setSelection(mPhonenumberView.getText().length());
mPhonenumberView.requestFocus();
}
private void ChangeToUsername()
{
emaillayout.setVisibility(View.VISIBLE);
phlayout.setVisibility(View.GONE);
emailView.setText("");
emailView.requestFocus();
}
public boolean isNumberOnly(String s)
{
return s.matches("-?\\d+(.\\d+)?");
}
所以通过这个实现,我能够实现我想要的。以下是截图:
虽然我可以实现结果,但我觉得一直调用文本观察器可能有点开销,因为我使用了两个单独的视图并添加了两个 Textwatcher 实例。以什么方式可以使这更清洁和高效?此外,我想了解如何确保在按键盘上的退格键时不会删除前缀,而是将视图更改为用户名字段?
【问题讨论】:
-
如果我的用户名是
99redballons怎么办?我认为你的逻辑必须更强大一点,而不仅仅是测试输入的第一个字符。也许只考虑数字 + 输入的总数的长度 + 格式验证器 + 有效区号表。 -
如果手机和用户名都允许登录,那么它在您的数据源/数据库中必须是唯一的。参考@TooManyEduardos 的问题,如果您不允许在用户名的开头使用数字文字,那么您已经找到了正确的方法。删除第二个
TextInputLayout并使用一个。TextWatcher的替代方案也只是将其删除。当您以任何方法(例如发送到服务器或其他方式)使用View的文本时,您只需检查第一个条目是数字还是字符并确定给定输入的类型。
标签: android android-edittext phone-number android-textinputlayout android-textwatcher