重新加载片段后触发LiveData观察器

问题描述 投票:0回答:1

我的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;
    }
}
android android-fragments mvvm android-livedata
1个回答
0
投票

您的问题是,您使UserRepository是Singleton实例,并始终保持userModelLiveData的值是解决此更改方法的简便方法

public LiveData<UserModelJSONPlaceholder> getUserModelLiveData() {
        userModelLiveData = new MutableLiveData<>();
        return userModelLiveData;
}
© www.soinside.com 2019 - 2024. All rights reserved.