stepstone-tech / android-material-stepper

This library allows to use Material steppers inside Android applications.
Apache License 2.0
1.78k stars 263 forks source link

Using a Singleton to keep data #282

Closed Tarcisiofl closed 5 years ago

Tarcisiofl commented 5 years ago

Make sure these boxes are checked before submitting your issue - thank you!

As the StepperLayout uses a Viewpager internally, when it loads, it also created the nearest left and right steps. Therefore, I'm using a Singleton to keep the data selected by each user. However, when I select one item on the first step, and put it on my Singleton, it was not displayed on my next step.

Is it possible to notify that the data has changed?

zawadz88 commented 5 years ago

Hi, could you place a code snippet of how it works? In general, if you're sharing data between steps and would like to refresh it you should do it when the step changes.

Tarcisiofl commented 5 years ago

I have the below fragment where the user put vehicle plates.

public class PlateFragment extends Fragment implements BlockingStep {
    private ActivityPlatesBinding mDataBinding;
    private DataManager dataManager;
    private HashMap<String, String> hashMap = new HashMap<>();

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        mDataBinding = DataBindingUtil.inflate(inflater, R.layout.activity_plates, container, false);

        View rootView;
        rootView = mDataBinding.getRoot();
        return rootView;
    }

    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        if (context instanceof DataManager) {
            dataManager = (DataManager) context;
        } else {
            throw new IllegalStateException("Activity must implement DataManager interface!");
        }
    }

    private void setLayoutByVehicleType(Vehicle vehicle) {
        if(vehicle.getCart()) {
            setLayoutComplete();
        } else {
            setLayotPartial();
        }
    }

    private void setLayoutComplete() {
        mDataBinding.textCarrierName.setText(SingletonStepSaver.getInstance().getCarrier().getName());
        if (mDataBinding.grp2.getVisibility() == View.GONE)
            mDataBinding.grp2.setVisibility(View.VISIBLE);

        mDataBinding.lbl1.setText(R.string.plate);
        mDataBinding.lbl2.setText(R.string.cart);
    }

    private void setLayotPartial() {
        mDataBinding.textCarrierName.setText(SingletonStepSaver.getInstance().getCarrier().getName());
        mDataBinding.lbl1.setText(R.string.plate);
        mDataBinding.grp2.setVisibility(View.GONE);
    }

    private void setInputByVehicleType(Vehicle vehicle) {
        if(vehicle.getCart()) {
            hashMap.put(mDataBinding.lbl1.getText().toString(), mDataBinding.edt1.getText().toString());
            hashMap.put(mDataBinding.lbl2.getText().toString(), mDataBinding.edt2.getText().toString());

            SingletonStepSaver.getInstance().setPlates(hashMap);
        } else {
            hashMap.put(mDataBinding.lbl1.getText().toString(), mDataBinding.edt1.getText().toString());

            SingletonStepSaver.getInstance().setPlates(hashMap);
        }
    }

    @Override
    public void onNextClicked(final StepperLayout.OnNextClickedCallback callback) {
        callback.goToNextStep();
    }

    @Override
    public void onCompleteClicked(StepperLayout.OnCompleteClickedCallback callback) {

    }

    @Override
    public void onBackClicked(StepperLayout.OnBackClickedCallback callback) {
        callback.goToPrevStep();
    }

    @Override
    public VerificationError verifyStep() {
        setInputByVehicleType(dataManager.getVehicle());
        return isNull(hashMap) ? null : new VerificationError("Nenhum dado informado!");
    }

    public static boolean isNull(Map<String, String> aMap){
        for(Map.Entry<String, String> entry : aMap.entrySet()){
            if(!(entry.getValue().isEmpty() && entry.getValue() != null)) {
                return true;
            }
        }
        return false;
    }

    @Override
    public void onSelected() {
        setLayoutByVehicleType(dataManager.getVehicle());
        mDataBinding.textVehicleName.setText(dataManager.getVehicle().getName());
    }

    @Override
    public void onError(@NonNull VerificationError error) {
        Toast.makeText(getContext(), "Erro: " + error.getErrorMessage(), Toast.LENGTH_SHORT).show();
    }
}

Therefore, in the function setInputByVehicleType(Vehicle vehicle) I put the information on a hashMap and added it to the Singleton SingletonStepSaver.getInstance().setPlates(hashMap);. However, when I tried to get the information on next step at first it is null, if I went back and further, now it gets populated.

Any idea?

zawadz88 commented 5 years ago

So that's the first step, right? In the next step, are you getting that data in onSelected() or in some Fragment lifecycle method?

Tarcisiofl commented 5 years ago

Yes, it is! I'm getting it on onCreateView

zawadz88 commented 5 years ago

onCreateView get called when the Fragment gets first created. Since a ViewPager is used under the hood this will be called right at the beginning since both the current Fragment and side Fragments get created. I suggest using onSelected() in the next step to refresh that data.

Tarcisiofl commented 5 years ago

It works put it on onSelected()