Gaurav Arora
Gaurav Arora

Reputation: 8362

Handling backpressed on each fragment

I have browsed a lot on stackoverflow and have made a best set of transactions for my project but have issue while handling backpressed.

This is my baseactivity class:

public class BaseAppCompatActivity extends LifecycleActivity {
    protected IBackPressedListener onBackPressedListener;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }


    protected FragmentTransaction getFragmentTransaction() {
        return getSupportFragmentManager().beginTransaction();
    }

    protected void addFragment(int fragmentContainer, Fragment fragment, String fragName, boolean addToBackStack) {
        FragmentTransaction ft = getFragmentTransaction();
        ft.add(fragmentContainer, fragment);
        if (addToBackStack)
            ft.addToBackStack(fragName);
        // Complete the changes added above
        ft.commitAllowingStateLoss();
    }

    public void setOnBackPressedListener(IBackPressedListener onBackPressedListener) {
        this.onBackPressedListener = onBackPressedListener;
    }

    @Override
    public void onBackPressed() {

    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        onBackPressedListener = null;
    }
}

This is my activity clas where I am adding the fragments and handling the backpressed events:

public class RechargeFragmentActivity extends BaseAppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_recharge_fragment);

        /*Replace fragment*/
        addFragment(R.id.fragmentFrame, new SelectRechargeOperatorFragment(), AppFragments.FRAG_SELECT_RECHARGE_OPERATORS, true);
    }

    @Override
    public void onBackPressed() {
        if (getSupportFragmentManager().getBackStackEntryCount() > 1 && onBackPressedListener != null) {
            onBackPressedListener.onBackPressed();
        } else
            finish();
    }

}

Now I implement Onbackpressed listener in fragment and it works fine for one backpressed, after that it picks up the instance of last fragment only which is popped off.

public class SelectRechargeOperatorFragment extends BaseFragment {
    @Inject
    public SelectRechargeOperatorLiveDataModel operatorLiveDataModel;
    @BindView(R.id.rv_select_operator)
    RecyclerView rvSelectOperators;
    @BindView(R.id.proceedLayout)
    RelativeLayout btnProceed;
    private RechargeOperatorsAdapter adapter;


    public SelectRechargeOperatorFragment() {
        //empty constructor required
    }

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ((BaseAppCompatActivity) fragmentContext).setOnBackPressedListener(this);
    }

    @Override
    protected void onInject(GraphComponent applicationComponent) {
        super.onInject(applicationComponent);
        applicationComponent.inject(this);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View convertView = inflater.inflate(R.layout.fragment_select_recharge_operator, container, false);
        ButterKnife.bind(this, convertView);

        /*fetch-views*/
        setUpOperatorRecyclerView();
        proceedToRecharge();

        return convertView;
    }

    @Override
    public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
    }

    @Override
    public void onResume() {
        super.onResume();
    }

    private void proceedToRecharge() {
        btnProceed.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                addFragment(R.id.fragmentFrame, new RechargeAirtimeFargment(), AppFragments.FRAG_RECHARGE_AIRTIME_PLANS, true);
            }
        });
    }
 @Override
    public void onBackPressed() {
        super.onBackPressed();
        getActivity().getSupportFragmentManager().popBackStack();
    }


}

This works well when I add only one fragment. When I add multiple fragments it works well only for first popping of fragment after that it returns me the old fragment onBackpressed listener. Why ?

Upvotes: 0

Views: 204

Answers (1)

VishnuSP
VishnuSP

Reputation: 589

The problem is, each time you add a fragment the onBackPressedListener in your activity is being overriden by the new object. So after popping the last fragment the logic fails. Try the following.

  1. Remove the setOnBackPressedListener and onBackPressedListener from your Activity
  2. Implement IBackPressedListener in your fragments. May be you can use a basefragment to avoid code duplication. Choose based on your need.
  3. Change the onBackPressed in your activity as,

     @Override
     public void onBackPressed() {
            if (getSupportFragmentManager().getBackStackEntryCount() > 1) {
                Fragment currentFragment = getSupportFragmentManager().findFragmentById(R.id.fragmentFrame);
               if(null != currentFragment && currentFragment instance of IBackPressedListener) {
                   ((IBackPressedListener)currentFragment).onBackPressed();
               }
            } else
                finish();
        }
    

Upvotes: 2

Related Questions