WizarDroid icon indicating copy to clipboard operation
WizarDroid copied to clipboard

WizardStep.notifyCompleted() causing focus loss

Open nghamilton opened this issue 10 years ago • 14 comments
trafficstars

Hello,

I am not convinced this isn't my implementation, but it seems that the notifyCompleted() method is causing interference with EditText field focus.

I have a test on whether a field has text entered (also tried other methods, such as with a OnFocusChangeListener and a setOnEditorActionListener, with same result). After a call to notifyCompleted() focus in the textfield is lost (I can't work out what element it moves to). Does this sound like it is something that could be happening from inside notifyCompleted()?

Thank you for any thoughts.

    editText.addTextChangedListener(new TextWatcher() {

        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {
            //Save the wizard state so that the user can proceed, if a name has been entered
            if (s.toString().length() > 0)
                notifyCompleted();
            else
                notifyIncomplete();
        }

nghamilton avatar Apr 27 '15 06:04 nghamilton

Short answer: yes, it does. Unfortunately there doesn't seem to be anything that I currently can do about it. You should set the focus back to the UI element, which lost it. Long answer: when you call one of the notify methods, it posts a StepCompletedEvent event, which is then picked up by the Wizard's receive() and directly to onStepCompleted(), which has to call the ViewPager's adapter.notifyDataSetChanged() in order to rebuild the pages in the ViewPager and "open" the next step.

 @Override
    public void receive(Object event) {
        StepCompletedEvent stepCompletedEvent = (StepCompletedEvent) event;
        onStepCompleted(stepCompletedEvent.isStepCompleted(), stepCompletedEvent.getStep());
    }

    private void onStepCompleted(boolean isComplete, WizardStep step) {
        if (step != getCurrentStep()) return;
        int stepPosition = getCurrentStepPosition();


        // Check that the step is not already in this state to avoid spamming the viewpager
        if (wizardFlow.isStepCompleted(stepPosition) != isComplete) {
            wizardFlow.setStepCompleted(stepPosition, isComplete);
            mPager.getAdapter().notifyDataSetChanged();
            //Refresh the UI
            callbacks.onStepChanged();
        }
    }

It is mPager.getAdapter().notifyDataSetChanged(); which causes the loss of focus, since it's redrawing the UI.

Nimrodda avatar May 01 '15 14:05 Nimrodda

Thanks - I fixed it by extending your code and including a validation callback on the steps, made the user interaction a bit neater for me as well.

On Sat, May 2, 2015 at 12:43 AM, Nimrod Dayan [email protected] wrote:

Short answer: yes, it does. Unfortunately there doesn't seem to be anything that I currently can do about it. You should set the focus back to the UI element, which lost it. Long answer: when you call one of the notify methods, it posts a StepCompletedEvent event, which is then picked up by the Wizard's receive() and directly to onStepCompleted(), which has to call the ViewPager's adapter.notifyDataSetChanged() in order to rebuild the pages in the ViewPager and "open" the next step.

@Override public void receive(Object event) { StepCompletedEvent stepCompletedEvent = (StepCompletedEvent) event; onStepCompleted(stepCompletedEvent.isStepCompleted(), stepCompletedEvent.getStep()); }

private void onStepCompleted(boolean isComplete, WizardStep step) {
    if (step != getCurrentStep()) return;
    int stepPosition = getCurrentStepPosition();


    // Check that the step is not already in this state to avoid spamming the viewpager
    if (wizardFlow.isStepCompleted(stepPosition) != isComplete) {
        wizardFlow.setStepCompleted(stepPosition, isComplete);
        mPager.getAdapter().notifyDataSetChanged();
        //Refresh the UI
        callbacks.onStepChanged();
    }
}

— Reply to this email directly or view it on GitHub https://github.com/Nimrodda/WizarDroid/issues/61#issuecomment-98146768.

nghamilton avatar May 03 '15 22:05 nghamilton

care to share your solution? or perhaps make a pull request? thanks!

Nimrodda avatar May 08 '15 16:05 Nimrodda

i have the same problem. please fix it :D.

alexissilva avatar May 19 '15 13:05 alexissilva

I have the same problem too. @nghamilton if you share your solution it would help. Thanks!

locomundo avatar May 22 '15 07:05 locomundo

Sorry for the late response; I made quite a few changes to the code, some of it was through extensions and some through the modifications to the wizardroid code. I'll try to create a branch now that has just a fix for this issue, and set up a pull request.

nghamilton avatar May 27 '15 23:05 nghamilton

I've pushed my changes to the branch I am working on: https://github.com/nghamilton/WizarDroid. I didn't fix this above issue, just worked around it with the features I've put in (validation and a goNext() event).

My code also allows for running a wizard within another wizard.

Be warned: this was code I hacked to use for what I needed. This also included changing the way the back button worked, and what happened when the user swiped.

I'll try to be faster to respond next time, if you have any questions, shoot them through to me.

nghamilton avatar May 28 '15 00:05 nghamilton

Thanks! I'll take a look.

I managed to fix it by extending a few of the classes. If anyone is interested I can write a summary of my changes. I didn't modify the wizaedroid library code, so no pull request.

I do have suggestions to make some members of some classes protected, so it can be easily extended.

locomundo avatar May 29 '15 09:05 locomundo

@locomundo feel free to share what you've done. From WizarDroid perspective, notifyCompleted() should be called when the user is done interacting with the current step and ready to proceed to the next one. Whether the input from the user is valid or not is not the concern of the library. The user of the library should validate the input before calling notifyCompleted().

Nimrodda avatar May 29 '15 13:05 Nimrodda

thanks locomundo,

can you post your solution here how to extend these classes?

Marek

marekas avatar Aug 20 '15 10:08 marekas

the same problem with validation fields after calling notifyCompleted() i have onCreate, onCreateView - app go crazy after that

i think when next step unlock - wizard tell to adapter what we have +1 pages and re-create pages :(((

boomsya avatar Dec 16 '15 13:12 boomsya

@Nimrodda Why do you have to call notifyDataSetChanged() when a step is marked complete/incomplete? it sounds like enabling/disabling the Next button will be enough....

avrahamshukron avatar Dec 26 '15 11:12 avrahamshukron

@avrahamshukron calling notifyDataSetChanged() is necessary after adding/removing fragments from ViewPager.

Nimrodda avatar Dec 26 '15 15:12 Nimrodda

+1, will be great this feature.

bsysop avatar Jan 23 '16 04:01 bsysop