title: Android: onPreferenceChange with validation
body: <p><strong>Quick overview:</strong></p>
  
  <p>I have built validation that works with onPreferenceChanged on a sample project designed just to test settings and how they're saved and such.  The functionality is all there and works as I desire it to.  I was hoping to be able to move this functionality over into the default generated SettingsActivity class since it appears to provide solid functionality and much needed headers for the expansion of the program.</p>
  
  <p>The code itself I would like to implement is what's been provided below.  Very briefly I have a check which decides if a specific verification or not needs to be implemented and if so it attaches the specific one, otherwise it attaches a generic one.  <strong>I believe this to be a hacky method and would like an alternative if possible.</strong></p>
  
  <pre><code>// Type of verification checking to attach
  public void attachOnPreferenceChangedListener(Preference dsp_pref) {
      if (dsp_pref.getKey().equals("et_targetPref")) {
          attachTargetVerifier(dsp_pref);
      } else { // Any non verifier specific is given a generic listen with summary updater
          attachGenericVerifier(dsp_pref);
      }
  }
  
  private void attachGenericVerifier(Preference dsp_pref) {
      dsp_pref.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
          @Override
          public boolean onPreferenceChange(Preference preference, Object newValue) {
              updatePrefSummary(preference);
              return true;
          }
      });
  }
  
  private void attachTargetVerifier(Preference dsp_pref) {
      dsp_pref.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
          @Override
          public boolean onPreferenceChange(Preference preference, Object newValue) {
              Pattern dsl_pattern = Pattern.compile(URL_REGEX,Pattern.CASE_INSENSITIVE);
              Matcher dsl_matcher = dsl_pattern.matcher(newValue.toString());
  
              if (!dsl_matcher.matches()) {
                  Toast.makeText(getActivity(), "Invalid URL.  Example: http://example.com/target", Toast.LENGTH_LONG).show();
              } else if (dsl_matcher.group(1).toLowerCase().endsWith("/target")) {
                  Toast.makeText(getActivity(), "Preference Saved", Toast.LENGTH_LONG).show();
                  updatePrefSummary(preference);
                  return true;
              } else if(dsl_matcher.group(2) == null) {
                  Toast.makeText(getActivity(), "URL must start with 'http://'", Toast.LENGTH_LONG).show();
              } else {
  
              }
              return false;
          }
      });
  }
  </code></pre>
  
  <p>What the default SettingsActivity provides is just a simple and straightforward OnPreferenceChange override, which probably means <strong>validation checking needs to be integrated here</strong> unless a more elegant method exists, in which case I'm all ears:</p>
  
  <pre><code>private static Preference.OnPreferenceChangeListener sBindPreferenceSummaryToValueListener = new Preference.OnPreferenceChangeListener() {
      @Override
      public boolean onPreferenceChange(Preference preference, Object value) {
          String stringValue = value.toString();
  
          if (preference instanceof ListPreference) {
              // For list preferences, look up the correct display value in
              // the preference's 'entries' list.
              ListPreference listPreference = (ListPreference) preference;
              int index = listPreference.findIndexOfValue(stringValue);
  
              // Set the summary to reflect the new value.
              preference.setSummary(
                      index &gt;= 0
                              ? listPreference.getEntries()[index]
                              : null);
  
          } else if (preference instanceof RingtonePreference) {
              // For ringtone preferences, look up the correct display value
              // using RingtoneManager.
              if (TextUtils.isEmpty(stringValue)) {
                  // Empty values correspond to 'silent' (no ringtone).
                  preference.setSummary(R.string.pref_ringtone_silent);
  
              } else {
                  Ringtone ringtone = RingtoneManager.getRingtone(
                          preference.getContext(), Uri.parse(stringValue));
  
                  if (ringtone == null) {
                      // Clear the summary if there was a lookup error.
                      preference.setSummary(null);
                  } else {
                      // Set the summary to reflect the new ringtone display
                      // name.
                      String name = ringtone.getTitle(preference.getContext());
                      preference.setSummary(name);
                  }
              }
  
          } else {
              // For all other preferences, set the summary to the value's
              // simple string representation.
              preference.setSummary(stringValue);
          }
          return true;
      }
  };
  </code></pre>
  
  <p><strong>Appreciate any advice on how this can be done without it becoming unmanageable</strong></p>