0

I've been stuck in a situation and i need some help over here. There are many articles on this topic here but none of them answered my question. I want to implement onBackPressed() in fragments and show dialog box which shows to exit the application or not. Any help would be appreciated.

LoginFragment.java

    public class LoginFragment extends Fragment {
    public static final String TAG = LoginFragment.class.getSimpleName();

    private EditText mEtEmail;
    private EditText mEtPassword;
    private Button mBtLogin;
    private TextView mTvRegister;
    private TextView mTvForgotPassword;
    private TextInputLayout mTiEmail;
    private TextInputLayout mTiPassword;
    private ProgressBar mProgressBar;

    private CompositeSubscription mSubscriptions;
    private SharedPreferences mSharedPreferences;

    @NonNull
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_login,container,false);
        mSubscriptions = new CompositeSubscription();
        initViews(view);
        initSharedPreferences();
        return view;
    }
    private void initViews(View v) {

        mEtEmail = v.findViewById(R.id.et_email);
        mEtPassword = v.findViewById(R.id.et_password);
        mBtLogin = v.findViewById(R.id.btn_login);
        mTiEmail = v.findViewById(R.id.ti_email);
        mTiPassword = v.findViewById(R.id.ti_password);
        mProgressBar = v.findViewById(R.id.progress);
        mTvRegister = v.findViewById(R.id.tv_register);
        mTvForgotPassword = v.findViewById(R.id.tv_forgot_password);

        mBtLogin.setOnClickListener(view -> login());
        mTvRegister.setOnClickListener(view -> goToRegister());
        mTvForgotPassword.setOnClickListener(view -> showDialog());
    }

    private void initSharedPreferences() {

        mSharedPreferences = PreferenceManager.getDefaultSharedPreferences(getActivity());
    }

    private void login() {

        setError();

        String email = mEtEmail.getText().toString();
        String password = mEtPassword.getText().toString();

        int err = 0;

        if (!validateEmail(email)) {

            err++;
            mTiEmail.setError("Email should be valid !");
        }

        if (!validateFields(password)) {

            err++;
            mTiPassword.setError("Password should not be empty !");
        }

        if (err == 0) {

            loginProcess(email,password);
            mProgressBar.setVisibility(View.VISIBLE);

        } else {

            showSnackBarMessage("Enter Valid Details !");
        }
    }

    private void setError() {

        mTiEmail.setError(null);
        mTiPassword.setError(null);
    }

    private void loginProcess(String email, String password) {

        mSubscriptions.add(NetworkUtil.getRetrofit(email, password).login()
                .observeOn(AndroidSchedulers.mainThread())
                .subscribeOn(Schedulers.io())
                .subscribe(this::handleResponse,this::handleError));
    }

    private void handleResponse(Response response) {

        mProgressBar.setVisibility(View.GONE);

        SharedPreferences.Editor editor = mSharedPreferences.edit();
        editor.putString(Constants.TOKEN,response.getToken());
        editor.putString(Constants.EMAIL,response.getMessage());
        editor.apply();

        mEtEmail.setText(null);
        mEtPassword.setText(null);

        Intent intent = new Intent(getActivity(),  HomeActivity.class);
        startActivity(intent);

    }

    private void handleError(Throwable error) {

        mProgressBar.setVisibility(View.GONE);

        if (error instanceof HttpException) {

            Gson gson = new GsonBuilder().create();

            try {

                String errorBody = ((HttpException) error).response().errorBody().string();
                Response response = gson.fromJson(errorBody,Response.class);
                showSnackBarMessage(response.getMessage());

            } catch (IOException e) {
                e.printStackTrace();
            }
        } else {

            showSnackBarMessage("No Internet Connection!");
        }
    }

    private void showSnackBarMessage(String message) {

        if (getView() != null) {

            Snackbar.make(getView(),message,Snackbar.LENGTH_SHORT).show();
        }
    }

    private void goToRegister(){

        FragmentTransaction ft = getFragmentManager().beginTransaction();
        RegisterFragment fragment = new RegisterFragment();
        ft.replace(R.id.fragmentFrame,fragment,RegisterFragment.TAG);
        ft.addToBackStack(null).commit();
    }

    private void showDialog(){

        ResetPasswordDialog fragment = new ResetPasswordDialog();

        fragment.show(getFragmentManager(), ResetPasswordDialog.TAG);
    }
    @Override
    public void onDestroy() {
        super.onDestroy();
        mSubscriptions.unsubscribe();
    }
}

MainActivity.java

public class MainActivity extends AppCompatActivity implements ResetPasswordDialog.Listener {

    public static final String TAG = MainActivity.class.getSimpleName();
    private LoginFragment mLoginFragment;
    private ResetPasswordDialog mResetPasswordDialog;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        if (savedInstanceState == null) {
            loadFragment();
        }
    }
    private void loadFragment() {

        if (mLoginFragment == null) {

            mLoginFragment = new LoginFragment();
        }
        getFragmentManager().beginTransaction().replace(R.id.fragmentFrame, mLoginFragment, LoginFragment.TAG).commit();
    }
    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);

        String data = intent.getData().getLastPathSegment();
        Log.d(TAG, "onNewIntent: " + data);

        mResetPasswordDialog = (ResetPasswordDialog) getFragmentManager().findFragmentByTag(ResetPasswordDialog.TAG);

        if (mResetPasswordDialog != null)
            mResetPasswordDialog.setToken(data);
    }

    @Override
    public void onPasswordReset(String message) {

        showSnackBarMessage(message);
    }

    private void showSnackBarMessage(String message) {

        Snackbar.make(findViewById(R.id.activity_main), message, Snackbar.LENGTH_SHORT).show();

    }
}

In My Login Fragment, I want to show a dialog box "Do you want to exit the application or not". On Yes it dismiss the current fragment and end the activity otherwise it'll remain active. Help please!

Devil10
  • 1,853
  • 1
  • 18
  • 22
Syed Bilal
  • 13
  • 7

2 Answers2

0

You can even try this way

MainActivity.java

  @Override
public void onBackPressed() {

    if (getFragmentManager() != null && getFragmentManager().getBackStackEntryCount() >= 1) {

   String fragmentTag = getFragmentManager().findFragmentById(R.id.frame_container).getTag();

   if(fragmentTag.equals(LoginFragment.getTag())){
    // show Dialog code
      }else{
            super.onBackPressed();
      }

    } else {
         super.onBackPressed();
    }
}

Add this code in your main activity so that when login fragment is added and you click backpress, then on first if the fragment is added to fragment transaction, then first it finds the fragment and check if its tag is equals to the login fragment tag. Then if both tag matches, then you can show your exit alert dialog.

Devil10
  • 1,853
  • 1
  • 18
  • 22
  • i tried this but if(fragmentTag.equals(LoginFragment.getTag())) this shows : getTag() cannot be referenced from a static context. I tried using TAG directly. I have TAG string in LoginFragment. None of it works. Can you help ? – Syed Bilal Nov 26 '19 at 07:38
  • 1
    i have edited your code and fixed the issue. Thanks for the help buddy.! :) Cheers! – Syed Bilal Nov 26 '19 at 07:59
  • Even you can add custom tag in place of Loginfragment.getTag() when you add fragment in transaction and can compare with that string tag. – Devil10 Nov 26 '19 at 18:13
0

Android team has prepared a new way of handling the back button pressed on Fragments for us, so you should check this out. It's called OnBackPressedDispatcher.

You need to register OnBackPressedCallback to the fragment where do you want to intercept back button pressed. You can do it like this inside of the Fragment:

     @Override
     public void onAttach(@NonNull Context context) {
         super.onAttach(context);
         OnBackPressedCallback callback = new OnBackPressedCallback(true) {
             @Override
             public void handleOnBackPressed() {
                //show exit dialog
             }
         };
         requireActivity().getOnBackPressedDispatcher().addCallback(this, callback);
     }
BVantur
  • 1,182
  • 16
  • 11