我的MainAcivity托管2个片段,登录并注册。我在LoginFragment上有一个LiveData观察器,用于观察用户登录实时数据,此后如果用户通过了身份验证,MainMenuActivity意图将启动。在主菜单上,有一个注销按钮,它将启动MainActivity并加载LoginFragment。
但是这是问题,LoginFragment上的观察者在加载片段后立即触发,该片段再次直接启动MainMenuActivity意图。
我的登录片段:
public class LoginFragment extends Fragment {
public static LoginFragment newInstance(){
return new LoginFragment();
}
private LoginViewModel mLoginViewModel;
private LiveData<UserModelJSONPlaceholder> mUserModelLiveData;
private static final String TAG = "FragLogin";
private Button mBtnLogin;
private EditText mTxtUsername, mTxtPass;
private TextView mTxtRegister;
private CheckBox mCheckBoxRemember;
private TextView mTxtInvalid;
private Callbacks mCallbacks = null;
private ProgressBar mProgressBar;
private UserApiInterface mAPIInterface;
private SharedPreferences mSharedPreferences;
private SharedPreferences.Editor mPreferencesEditor;
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_login,container,false);
mBtnLogin = view.findViewById(R.id.btnLogin_login);
mTxtUsername = view.findViewById(R.id.txtUsername);
mTxtPass = view.findViewById(R.id.txtPass);
mCheckBoxRemember = view.findViewById(R.id.checkBoxRememberMe);
mTxtRegister = view.findViewById(R.id.txtRegister_login);
mProgressBar = view.findViewById(R.id.progressBar);
mTxtInvalid = view.findViewById(R.id.txtInvalid);
mProgressBar.setVisibility(View.GONE);
mTxtInvalid.setVisibility(View.GONE);
mAPIInterface = APIClient.getClient().create(UserApiInterface.class);
mSharedPreferences = getContext().getSharedPreferences("login",Context.MODE_PRIVATE);
mPreferencesEditor = mSharedPreferences.edit();
setListener();
return view;
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mLoginViewModel = new ViewModelProvider(this).get(LoginViewModel.class);
mUserModelLiveData = mLoginViewModel.getUserModelLiveData();
//observer would be triggered right after loading fragment after logout
mUserModelLiveData.observe(this, new Observer<UserModelJSONPlaceholder>() {
@Override
public void onChanged(UserModelJSONPlaceholder userModel) {
Log.d(TAG, "onChanged: Observer: "+userModel.getResponse());
mProgressBar.setVisibility(View.GONE);
String loginAuth = userModel.getResponse();
if(loginAuth.equals("OK")){
mPreferencesEditor.putString("name",userModel.getUserModel().getName());
mCallbacks.login_goMainMenu(userModel.getUserModel().getName());
}else{
mTxtInvalid.setVisibility(View.VISIBLE);
}
}
});
}
private void doLogin(){
mProgressBar.setVisibility(View.VISIBLE);
final String username = mTxtUsername.getText().toString().trim();
final String password = mTxtPass.getText().toString().trim();
mLoginViewModel.authLogin(username,password);
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
mCallbacks = (Callbacks) context;
}
private void setListener(){
mBtnLogin.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v) {
doLogin();
}
});
mTxtRegister.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mCallbacks.login_goRegister();
}
});
mCheckBoxRemember.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if(buttonView.isChecked()){
mPreferencesEditor.putBoolean("rememberMe", true).apply();
Log.d(TAG, "onCheckedChanged: Checked");
}else{
mPreferencesEditor.putBoolean("rememberMe", false).apply();
Log.d(TAG, "onCheckedChanged: Unchecked");
}
}
});
}
public interface Callbacks{
void login_goMainMenu(String name);
void login_goRegister();
}
}
我的MainMenuActivity:
public class MainMenuActivity extends AppCompatActivity {
private static final String ARG_NAME = "arg_name";
private Button mBtnEnterQ,mBtnCreateQ;
private TextView mTxtName;
private Toolbar mToolbar;
private SharedPreferences mSharedPreferences;
private SharedPreferences.Editor mEditor;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main_menu);
mBtnEnterQ = findViewById(R.id.btnEnterQ);
mBtnCreateQ = findViewById(R.id.btnCreateQ);
mTxtName = findViewById(R.id.txtUsername);
mToolbar = findViewById(R.id.toolbar);
mSharedPreferences = getSharedPreferences("login",MODE_PRIVATE);
mEditor = mSharedPreferences.edit();
setSupportActionBar(mToolbar);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.toolbar_menu,menu);
return true;
}
@Override
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
switch (item.getItemId()){
case R.id.itemLogout:
doLogout();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
private void doLogout(){
mEditor.remove("rememberMe");
mEditor.apply();
Intent i = new Intent(this, MainActivity.class);
startActivity(i);
finish();
}
}
这是我的ViewModel和LoginFragment的仓库:
public class LoginViewModel extends ViewModel {
private static final String TAG = "LoginVM";
private UserRepository mUserRepository;
LiveData<UserModelJSONPlaceholder> mUserModelLiveData;
public LoginViewModel() {
mUserRepository = UserRepository.getInstance();
}
public void authLogin(String username, String password){
mUserRepository.authLogin(username,password);
}
public LiveData<UserModelJSONPlaceholder> getUserModelLiveData() {
return mUserRepository.getUserModelLiveData();
}
}
public class UserRepository {
private static UserRepository instance;
private static final String TAG = "RepoUser";
private UserApiInterface mUserApiInterface;
MutableLiveData<UserModelJSONPlaceholder> userModelLiveData;
public static UserRepository getInstance(){
if(instance==null){
instance=new UserRepository();
}
return instance;
}
private UserRepository(){
mUserApiInterface = APIClient.getClient().create(UserApiInterface.class);
Log.d(TAG, "UserRepository: repoInit");
}
public void authLogin(String username, String password){
Log.d(TAG, "authLogin: REQUEST INIT");
Log.d(TAG, "authLogin: SERVER: "+ CONFIG.SERVER);
mUserApiInterface.getUser(username,password).enqueue(new Callback<UserModelJSONPlaceholder>() {
@Override
public void onResponse(Call<UserModelJSONPlaceholder> call, Response<UserModelJSONPlaceholder> response) {
if(response.isSuccessful()){
UserModelJSONPlaceholder r = response.body();
userModelLiveData.postValue(response.body());
}else{
Log.d(TAG, "onResponse: FAILED. "+response.errorBody());
}
}
@Override
public void onFailure(Call<UserModelJSONPlaceholder> call, Throwable t) {
Log.d(TAG, "onFailure: "+t.getMessage());
}
});
}
public LiveData<UserModelJSONPlaceholder> getUserModelLiveData() {
if(userModelLiveData == null)
userModelLiveData = new MutableLiveData<>();
return userModelLiveData;
}
}
您的问题是,您使UserRepository
是Singleton实例,并始终保持userModelLiveData
的值是解决此更改方法的简便方法
public LiveData<UserModelJSONPlaceholder> getUserModelLiveData() {
userModelLiveData = new MutableLiveData<>();
return userModelLiveData;
}