>问题:用户应该能够通过他们的电话号码或用户名(他们在注册时设置的内容)登录。这两个值都允许用户登录。编辑文本字段需要足够智能,以确定正在输入的内容。因此,当用户输入数字作为第一个字符时,它应该自动添加国家/地区代码电话号码前缀,并在前缀后插入键入的字符。
这是我的布局:
<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 实例。如何才能使它更加清洁和高效?此外,我想了解如何确保前缀未被删除,但在按键盘上的退格键时将视图更改为用户名字段?
您可以EditText
实现以下功能:
mPhoneAndEmailView.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()) && !mPhoneAndEmailView.contains("+61")){
mPhoneAndEmailView.setText("+61" + s);
}//utlimately when you clear number and start typing text it will ignore if and takes alpha or if it has only numbers first time it will append +61
}
});
尝试用这种方式为我工作。我只使用一个EditText
并以编程方式更改所有属性
主活动.java
public class MainActivity extends AppCompatActivity {
TextInputLayout textInputLayout;
AppCompatEditText edtPhnUsername;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textInputLayout = findViewById(R.id.textInputLayout);
edtPhnUsername = findViewById(R.id.edtPhnUsername);
edtPhnUsername.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) {
new Thread(new Runnable() {
@Override
public void run() {
changeEditTextState();
}
}).start();
}
@Override
public void afterTextChanged(Editable s) {
}
});
}
private void changeEditTextState() {
String uname = edtPhnUsername.getText().toString().trim();
if (!TextUtils.isEmpty(uname)) {
String desiredString = "";
if (uname.length() >= 3) {
desiredString = uname.substring(0, 3);
}
if (uname.contains("+61") && desiredString.equalsIgnoreCase("+61")) {
changeToPhoneNumber();
} else {
changeToUsername();
}
} else {
//default
changeToUsername();
}
}
private void changeToPhoneNumber() {
textInputLayout.setHint("Phone number");
edtPhnUsername.setInputType(InputType.TYPE_CLASS_PHONE);
setEditTextMaxLength(10);
}
private void changeToUsername() {
textInputLayout.setHint("Username");
edtPhnUsername.setInputType(InputType.TYPE_CLASS_TEXT);
setEditTextMaxLength(50);
}
public void setEditTextMaxLength(int length) {
InputFilter[] filterArray = new InputFilter[1];
filterArray[0] = new InputFilter.LengthFilter(length);
edtPhnUsername.setFilters(filterArray);
}
}
activity_main.xml
<android.support.design.widget.TextInputLayout
android:id="@+id/textInputLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:animateLayoutChanges="true"
android:orientation="horizontal"
android:paddingStart="5dp"
android:hint="Username"
android:paddingLeft="5dp">
<android.support.v7.widget.AppCompatEditText
android:id="@+id/edtPhnUsername"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="text"
android:maxLines="1"
android:layout_weight="1" />
</android.support.design.widget.TextInputLayout>