重置片段中的所有视图

Reset all Views in fragment

所以我目前在FragmentA.java,一个class,由不同的EditTextCheckbox组成,供用户按下和输入。

我的问题是,我有这个重置按钮,如何重置整个片段视图? (例如,EditText 将被设置为空字符串,或者值为 0,就像创建时一样)。

P.S。当然我可以通过程序一个一个地设置editText/Checkboxes,但是有很多它们和其他视图,所以我想知道是否有一个好的方法来重置它们。

让我们把它分解成几个步骤:

1。获取参考资料

如何做到这一点取决于您已经拥有的东西。如果创建字段 in-code,这很简单:只需将引用存储在 List<CommonBaseType>.

如果它们是从 XML 布局加载的,则有多个选项。如果您只想重置某些类型的所有视图,则可以通过获取对视图层次结构的引用来遍历视图层次结构 ViewGroup (布局)并遍历 children 与getChildCount() and getChildAt(int)。然后,检查 child 的类型。如果是 ViewGroup,检查 children。如果是 EditTextCheckBox,请将它们添加到列表中。

如果您需要更多控制并且不希望重置 所有 视图,您可以标记您想要的视图。您可以使用 android:tag-attribute and find them after inflation using the View.findViewWithTag(Object)-method.

在 XML 中标记视图

2。重置

现在您有了引用,您可以通过简单地遍历您在步骤 1 中创建的集合并根据它们的类型处理它们来重置它们。一些伪代码:

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...
}

类似这样的操作会将您表单中的所有字段重置为 default-value,具体取决于它们的类型。

3。重置回原始值

如果您想将视图重置为其原始值,您应该在设置初始值时“索引”它们(如果您通过 [=74] 设置值,则可能直接在 inflation 之后=]).

要做到这一点,只需 运行 遍历第 1 步中的列表,然后将其 ID 映射到此时的值:

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...
}

稍后当您想要重置 form-elements 时,您可以再次迭代列表并从地图中获取默认值。根据字段类型 (EditText -> String, CheckBox -> Boolean, etz) 转换它们并设置值。

奖金:讨厌的无线电组

重置 RadioGroup 只需调用 clearCheck() 即可,它具有令人讨厌的 side-effect 触发关联的 OnCheckedChangeListener(您可能不想要,具体取决于您在监听器中做的)。

解决此问题的最简单方法是在调用 clearCheck() 之前 un-register 侦听器,然后 re-registering 调用它。这可以通过覆盖 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);
    }
}