问题
I have a simple login layout that contains two EditText fields and a Button to login. The problem is that the ActionBar disappears when the soft keyboard is open and I change the focus from an EditText to the Button, and the ActionBar comes back again when I press back. The problem does not occur when the soft keyboard is closed and I navigate through the EditTexts and Button with the DPAD.
I use ActionBarSherlock, and the problem occurs only on Android 2.x emulators, on the 4.x emulators everything is normal. I know ActionBarSherlock uses the native ActionBar implementations on Android versions where it is available, so it probably is a problem with the ActionBarSherlock code.
I also executed a test to check the value of ActionBar.isShowing()
, but this returned true even when the ActionBar was not visible on the screen.
I cannot figure out what is going on in this case, anybody has some ideas?
Layout XML
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:ignore="UselessParent" >
<LinearLayout
android:layout_width="250dp"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:orientation="vertical" >
<EditText
android:id="@+id/username"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:hint="@string/username"
android:inputType="textNoSuggestions"
android:nextFocusUp="@+id/loginButton"
android:imeOptions="actionNext" />
<EditText
android:id="@+id/password"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:hint="@string/password"
android:inputType="textPassword"
android:imeOptions="actionDone" />
<Button
android:id="@+id/loginButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right"
android:text="@string/login"
android:textSize="20sp"
android:nextFocusDown="@+id/username" />
</LinearLayout>
</RelativeLayout>
FRAGMENT CODE
public class LoginFragment extends BaseFragment {
@InjectView(R.id.loginButton) protected Button mLoginButton;
@InjectView(R.id.username) protected EditText mUsernameEditText;
@InjectView(R.id.password) protected EditText mPasswordEditText;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.login, container, false);
}
@Override
public void onStart() {
super.onStart();
mLoginButton.setEnabled(allFieldsValid());
mLoginButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
handleLogin();
}
});
mPasswordEditText.setOnEditorActionListener(new TextView.OnEditorActionListener() {
@Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
if (actionId == EditorInfo.IME_ACTION_DONE && allFieldsValid()) {
handleLogin();
}
return false;
}
});
TextWatcher fieldValidatorTextWatcher = new TextWatcher() {
@Override
public void afterTextChanged(Editable s) {
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
mLoginButton.setEnabled(allFieldsValid());
}
};
mUsernameEditText.addTextChangedListener(fieldValidatorTextWatcher);
mPasswordEditText.addTextChangedListener(fieldValidatorTextWatcher);
}
private void handleLogin() {
getSherlockActivity().setSupportProgressBarIndeterminateVisibility(true);
Intent intent = new Intent(getActivity(), LoginService.class);
intent.putExtra(BaseIntentService.EXTRA_STATUS_RECEIVER, mResultReceiver);
intent.putExtra(LoginService.PARAM_USERNAME, mUsernameEditText.getText().toString());
intent.putExtra(LoginService.PARAM_PASSWORD, mPasswordEditText.getText().toString());
getActivity().startService(intent);
}
private boolean allFieldsValid() {
return usernameFieldIsValid() && passwordFieldIsValid();
}
private boolean usernameFieldIsValid() {
return !TextUtils.isEmpty(mUsernameEditText.getText());
}
private boolean passwordFieldIsValid() {
return !TextUtils.isEmpty(mPasswordEditText.getText());
}
@Override
public void onReceiveResult(int resultCode, Bundle resultData) {
getSherlockActivity().setSupportProgressBarIndeterminateVisibility(false);
super.onReceiveResult(resultCode, resultData);
}
@Override
public void onReceiveResultSuccess(Bundle resultData) {
((LoginActivity) getActivity()).redirectToSelectTeamwebActivity(resultData.getInt(LoginService.RESULT_USER_ID));
}
@Override
public void onReceiveResultFailure(Bundle resultData) {
mPasswordEditText.setText("");
String errorMessage = getString(R.string.invalid_login_credentials);
Toast.makeText(getActivity(), errorMessage, Toast.LENGTH_LONG).show();
}
}
回答1:
ActionBarSherlock attaches a compatibility action bar on pre-ICS inside of the content view rather than in the Window's decor view. Because of this, it is susceptible to more inconveniences which may cause unexpected behavior like the one you are seeing.
If you have set the windowSoftInputMode
to pan the content view when the IME is open the action bar will disappear from the screen. The simple way around this would be to use a different mode (e.g., resize) which will re-layout the content view and keep the action bar on the screen.
来源:https://stackoverflow.com/questions/10258962/actionbarsherlock-actionbar-disappears-when-focus-changes-from-edittext-to-butto