private static View createSwitch(
     @NonNull LayoutInflater inflater,
     @NonNull ViewGroup parent,
     @NonNull FormField field,
     @NonNull String value,
     @NonNull String instructions,
     boolean readOnly,
     @NonNull final SwitchListener switchListener) {
   final View view = inflater.inflate(R.layout.edit_user_profile_switch, parent, false);
   ((TextView) view.findViewById(R.id.label)).setText(field.getLabel());
   ((TextView) view.findViewById(R.id.instructions)).setText(instructions);
   final RadioGroup group = ((RadioGroup) view.findViewById(R.id.options));
   {
     final RadioButton optionOne = ((RadioButton) view.findViewById(R.id.option_one));
     final RadioButton optionTwo = ((RadioButton) view.findViewById(R.id.option_two));
     optionOne.setText(field.getOptions().getValues().get(0).getName());
     optionOne.setTag(field.getOptions().getValues().get(0).getValue());
     optionTwo.setText(field.getOptions().getValues().get(1).getName());
     optionTwo.setTag(field.getOptions().getValues().get(1).getValue());
   }
   for (int i = 0; i < group.getChildCount(); i++) {
     final View child = group.getChildAt(i);
     child.setEnabled(!readOnly);
     if (child.getTag().equals(value)) {
       group.check(child.getId());
       break;
     }
   }
   if (readOnly) {
     group.setEnabled(false);
     view.setBackgroundColor(view.getResources().getColor(R.color.edx_grayscale_neutral_x_light));
   } else {
     group.setOnCheckedChangeListener(
         new RadioGroup.OnCheckedChangeListener() {
           @Override
           public void onCheckedChanged(RadioGroup group, int checkedId) {
             switchListener.onSwitch((String) group.findViewById(checkedId).getTag());
           }
         });
   }
   parent.addView(view);
   return view;
 }
  @Override
  public void onViewCreated(View view, Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
    getActivity().setTitle(formField.getLabel());
    final List<FormOption> options = new ArrayList<>();
    final FormOptions formOptions = formField.getOptions();
    final ArrayAdapter<FormOption> adapter =
        new ArrayAdapter<>(getActivity(), R.layout.edx_selectable_list_item, options);
    if (formOptions.getReference() != null) {
      new GetFormOptionsTask(getActivity(), formOptions.getReference()) {
        @Override
        protected void onSuccess(List<FormOption> formOptions) throws Exception {
          options.addAll(formOptions);
          adapter.notifyDataSetChanged();
          selectCurrentOption();
        }
      }.execute();

    } else if (formOptions.getRangeMin() != null && formOptions.getRangeMax() != null) {
      for (int i = formOptions.getRangeMax(); i >= formOptions.getRangeMin(); --i) {
        options.add(new FormOption(String.valueOf(i), String.valueOf(i)));
      }
    } else if (formOptions.getValues() != null && formOptions.getValues().size() > 0) {
      options.addAll(formOptions.getValues());
    }
    if (!TextUtils.isEmpty(formField.getInstructions())) {
      final View instructionsContainer =
          LayoutInflater.from(view.getContext())
              .inflate(R.layout.form_field_instructions_header, listView, false);
      final TextView instructions =
          (TextView) instructionsContainer.findViewById(R.id.instructions);
      final TextView subInstructions =
          (TextView) instructionsContainer.findViewById(R.id.sub_instructions);
      instructions.setText(formField.getInstructions());
      if (TextUtils.isEmpty(formField.getSubInstructions())) {
        subInstructions.setVisibility(View.GONE);
      } else {
        subInstructions.setText(formField.getSubInstructions());
      }
      listView.addHeaderView(instructionsContainer, null, false);
    }
    if (null != formField.getDataType()) {
      switch (formField.getDataType()) {
        case COUNTRY:
          {
            final Locale locale = Locale.getDefault();
            addDetectedValueHeader(
                listView,
                R.string.edit_user_profile_current_location,
                "current_location",
                locale.getDisplayCountry(),
                locale.getCountry(),
                FontAwesomeIcons.fa_map_marker);
            break;
          }
        case LANGUAGE:
          {
            final Locale locale = Locale.getDefault();
            addDetectedValueHeader(
                listView,
                R.string.edit_user_profile_current_language,
                "current_language",
                locale.getDisplayLanguage(),
                locale.getLanguage(),
                FontAwesomeIcons.fa_comment);
            break;
          }
      }
    }
    if (formField.getOptions().isAllowsNone()) {
      final TextView textView =
          (TextView)
              LayoutInflater.from(listView.getContext())
                  .inflate(R.layout.edx_selectable_list_item, listView, false);
      final String label = formField.getOptions().getNoneLabel();
      textView.setText(label);
      listView.addHeaderView(textView, new FormOption(label, null), true);
    }
    listView.setAdapter(adapter);
    listView.setOnItemClickListener(
        new AdapterView.OnItemClickListener() {
          @Override
          public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            final FormOption item = (FormOption) parent.getItemAtPosition(position);
            getActivity()
                .setResult(
                    Activity.RESULT_OK,
                    new Intent()
                        .putExtra(FormFieldActivity.EXTRA_FIELD, formField)
                        .putExtra(FormFieldActivity.EXTRA_VALUE, item.getValue()));
            getActivity().finish();
          }
        });
    selectCurrentOption();
  }
  public void setData(@Nullable final Account account, @Nullable FormDescription formDescription) {
    if (null == viewHolder) {
      return;
    }
    if (null == account || null == formDescription) {
      viewHolder.content.setVisibility(View.GONE);
      viewHolder.loadingIndicator.setVisibility(View.VISIBLE);

    } else {
      viewHolder.content.setVisibility(View.VISIBLE);
      viewHolder.loadingIndicator.setVisibility(View.GONE);
      viewHolder.changePhoto.setEnabled(!account.requiresParentalConsent());
      viewHolder.profileImage.setBorderColorResource(
          viewHolder.changePhoto.isEnabled()
              ? R.color.edx_brand_primary_base
              : R.color.edx_grayscale_neutral_base);

      if (account.getProfileImage().hasImage()) {
        Glide.with(viewHolder.profileImage.getContext())
            .load(account.getProfileImage().getImageUrlLarge())
            .into(viewHolder.profileImage);
      } else {
        Glide.with(EditUserProfileFragment.this)
            .load(R.drawable.xsie)
            .into(viewHolder.profileImage);
      }

      final Gson gson = new GsonBuilder().serializeNulls().create();
      final JsonObject obj = (JsonObject) gson.toJsonTree(account);

      final boolean isLimited =
          account.getAccountPrivacy() != Account.Privacy.ALL_USERS
              || account.requiresParentalConsent();

      final LayoutInflater layoutInflater = LayoutInflater.from(viewHolder.fields.getContext());
      viewHolder.fields.removeAllViews();
      for (final FormField field : formDescription.getFields()) {
        if (null == field.getFieldType()) {
          // Missing field type; ignore this field
          continue;
        }
        switch (field.getFieldType()) {
          case SWITCH:
            {
              if (field.getOptions().getValues().size() != 2) {
                // We expect to have exactly two options; ignore this field.
                continue;
              }
              final boolean isAccountPrivacyField =
                  field.getName().equals(Account.ACCOUNT_PRIVACY_SERIALIZED_NAME);
              String value = gson.fromJson(obj.get(field.getName()), String.class);
              if (isAccountPrivacyField && null == value || account.requiresParentalConsent()) {
                value = Account.PRIVATE_SERIALIZED_NAME;
              }

              createSwitch(
                  layoutInflater,
                  viewHolder.fields,
                  field,
                  value,
                  account.requiresParentalConsent()
                      ? getString(R.string.profile_consent_needed_explanation)
                      : field.getInstructions(),
                  isAccountPrivacyField ? account.requiresParentalConsent() : isLimited,
                  new SwitchListener() {
                    @Override
                    public void onSwitch(@NonNull String value) {
                      executeUpdate(field, value);
                    }
                  });
              break;
            }
          case SELECT:
          case TEXTAREA:
            {
              final String value;
              final String text;
              {
                final JsonElement accountField = obj.get(field.getName());
                if (null == accountField) {
                  value = null;
                  text = null;
                } else if (null == field.getDataType()) {
                  // No data type is specified, treat as generic string
                  value = gson.fromJson(accountField, String.class);
                  text = value;
                } else {
                  switch (field.getDataType()) {
                    case COUNTRY:
                      value = gson.fromJson(accountField, String.class);
                      try {
                        text =
                            TextUtils.isEmpty(value)
                                ? null
                                : LocaleUtils.getCountryNameFromCode(value);
                      } catch (InvalidLocaleException e) {
                        continue;
                      }
                      break;
                    case LANGUAGE:
                      final List<LanguageProficiency> languageProficiencies =
                          gson.fromJson(
                              accountField,
                              new TypeToken<List<LanguageProficiency>>() {}.getType());
                      value =
                          languageProficiencies.isEmpty()
                              ? null
                              : languageProficiencies.get(0).getCode();
                      try {
                        text = value == null ? null : LocaleUtils.getLanguageNameFromCode(value);
                      } catch (InvalidLocaleException e) {
                        continue;
                      }
                      break;
                    default:
                      // Unknown data type; ignore this field
                      continue;
                  }
                }
              }
              final String displayValue;
              if (TextUtils.isEmpty(text)) {
                final String placeholder = field.getPlaceholder();
                if (TextUtils.isEmpty(placeholder)) {
                  displayValue =
                      viewHolder
                          .fields
                          .getResources()
                          .getString(R.string.edit_user_profile_field_placeholder);
                } else {
                  displayValue = placeholder;
                }
              } else {
                displayValue = text;
              }
              createField(
                  layoutInflater,
                  viewHolder.fields,
                  field,
                  displayValue,
                  isLimited && !field.getName().equals(Account.YEAR_OF_BIRTH_SERIALIZED_NAME),
                  new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                      startActivityForResult(
                          FormFieldActivity.newIntent(getActivity(), field, value),
                          EDIT_FIELD_REQUEST);
                    }
                  });
              break;
            }
          default:
            {
              // Unknown field type; ignore this field
              break;
            }
        }
      }
    }
  }