Reset all Views in fragment

3.9k views Asked by At

So I am currently in FragmentA.java, a class which consists of different EditTexts and Checkboxes for users to press and input.

My question is, I have this reset button, how can I reset the entire fragment view? (e.g. an EditText will be set to empty string, or with the value 0, as it is when created).

P.S. of course I can set the editText/Checkboxes one by one programically, however there are quite a lot of them and other views, so I would like to know if there is a good way to reset all of them.

1

There are 1 answers

4
Lukas Knuth On BEST ANSWER

Let's break it down into steps:

1. Getting the references

How this is done depends on what you already have. If the fields are created in-code, it's easy: Just store the references in a List<CommonBaseType>.

If they are loaded from an XML Layout, there are multiple options. If you just want all views of certain type(s) to be reset, you can iterate through the view hierarchy by getting a reference to their holding ViewGroup (the layout) and iterate over the children with getChildCount() and getChildAt(int). Then, check the type of the child. If it's a ViewGroup, check it's children. If it's an EditText or CheckBox, add them to the list.

If you need more control and don't want all views to be reset, you can tag the ones you want with something. You can tag a view in XML by using the android:tag-attribute and find them after inflation using the View.findViewWithTag(Object)-method.

2. Resetting

Now that you have the references, you can reset them by simply iterating over the collection you made in step 1 and handle them depending on their type. Some pseudo code with that:

List<View> form_elements = findViewsToReset();
for (View element : form_elements){
    if (element instanceof EditText){
        ((EditText) element).setText("");
    } else if (element instanceof CheckBox){
        ((CheckBox) element).setChecked(false);
    }
    // and so forth...
}

Something like this will reset all fields in your form to a default-value, depending on their type.

3. Resetting back to their original values

If you want to reset the views to their original values, you should "index" those when the initial values are set (which might be directly after inflation, if you set the values via XML).

To do this, simply run through your list from step 1 and make a mapping from their ID to their value at that point:

List<View> form_elements = findViewsToReset();
Map<Integer, Object> default_values = new HashMap<>(form_elements.size());
for (View element : form_elements){
    if (element.getId() == View.NO_ID){
        // We have nothing to identify this view by...
        continue;
    }
    // Store the default values away:
    if (element instanceof EditText){
        default_values.put(
            element.getId(), 
            ((EditText) element).getText()
        );
    } else if (element instanceof CheckBox){
        default_values.put(
            element.getId(),
            ((CheckBox) element).isChecked()
        );
    }
    // and so forth...
}

Later when you want to reset the form-elements, you can just iterate the list again and get the default values from the map. Cast them depending on the type of field (EditText -> String, CheckBox -> Boolean, etz) and set the values.

Bonus: Nasty RadioGroup

Resetting a RadioGroup is simply archived by calling clearCheck() on it, which has the nasty side-effect of triggering the associated OnCheckedChangeListener (which you might not want, depending on what you're doing in the listener).

The simplest way around this is to un-register the listener before calling clearCheck() and re-registering it afterwards. This can be archived by overriding RadioGroup.clearCheck():

/**
 * When {@link #clearCheck()} is called, the registered (if any) {@link android.widget.RadioGroup.OnCheckedChangeListener} will <b>not</b> be called.
 * @author Lukas Knuth
 * @version 1.0
 */
public class CustomRadioGroup extends RadioGroup {

    private OnCheckedChangeListener checked_change_listener;

    public CustomRadioGroup(Context context) {
        super(context);
    }

    public CustomRadioGroup(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    public void setOnCheckedChangeListener(OnCheckedChangeListener listener) {
        // We need to store this ourselves, since there is no getter-method for the listener -.-
        this.checked_change_listener = listener;
        super.setOnCheckedChangeListener(listener);
    }

    @Override
    public void clearCheck() {
        // 1. unregister the listener:
        super.setOnCheckedChangeListener(null);
        // 2. Clear
        super.clearCheck();
        // 3. restore the listener like it was before:
        super.setOnCheckedChangeListener(this.checked_change_listener);
    }
}