2016-11-23 1 views
0

Aperçu rapide:Android: onPreferenceChange avec validation

J'ai construit la validation qui fonctionne avec onPreferenceChanged sur un exemple de projet conçu spécialement pour tester les paramètres et la façon dont ils sont sauvés et tel. La fonctionnalité est là et fonctionne comme je le souhaite. J'espérais pouvoir transférer cette fonctionnalité dans la classe SettingsActivity générée par défaut car elle semble fournir des fonctionnalités solides et des en-têtes indispensables pour l'extension du programme.

Le code que je voudrais implémenter est ce qui a été fourni ci-dessous. Très brièvement j'ai un contrôle qui décide si une vérification spécifique ou non doit être mise en œuvre et si oui, il attache le spécifique, sinon il en attache un générique. Je crois que c'est une méthode hacky et je voudrais une alternative si possible.

// 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; 
     } 
    }); 
} 

Ce que le SettingsActivity par défaut fournit est juste une commande prioritaire OnPreferenceChange simple et directe, ce qui signifie probablement vérification de validation doit être intégrée ici à moins qu'une méthode plus élégante existe, dans ce cas, je suis toutes les oreilles:

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 >= 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; 
    } 
}; 

apprécierais toute conseils sur la façon dont cela peut se faire sans que cela devienne ingérable

+0

Et notez également un peu de conflit dû au fait que sBindPreferenceSummaryToValueListener est statique, ce qui rend improbable toute alerte "Toasts", à moins que je ne puisse résoudre le contexte. Je ne sais toujours pas comment continuer à faire ça. – Ben

Répondre

0

La solution, pour les personnes intéressées, sans compléter et 100% est de placer le petit bloc de validation en haut, si la validation échoue est effectué une fausse déclaration sur:

private static Preference.OnPreferenceChangeListener sBindPreferenceSummaryToValueListener = new Preference.OnPreferenceChangeListener() { 
    @Override 
    public boolean onPreferenceChange(Preference preference, Object value) { 
     String stringValue = value.toString(); 

     /////////////////////////////////////////////////////////////////// 
     // Preference Validation Section 
     /////////////////////////////////////////////////////////////////// 

     // URL Check: http://whatev.er/targetstore 
     if (preference.getKey().equals("connect_url")) { 
      Pattern dsl_pattern = Pattern.compile(URL_REGEX,Pattern.CASE_INSENSITIVE); 
      Matcher dsl_matcher = dsl_pattern.matcher(stringValue); 

      if (dsl_matcher.matches() && // Match! 
        dsl_matcher.group(1).toLowerCase().endsWith("/targetstore")) { // Confirmed validity 
       Toast.makeText(dsl_context, "Preference Saved", Toast.LENGTH_LONG).show(); 
      } else { // No match - don't save data. 
       Toast.makeText(dsl_context, "Invalid URL. Example: http://example.com/targetstore", Toast.LENGTH_LONG).show(); 
       return false; // Stops result from saving 
      } 
     } 
     if (preference instanceof ListPreference) { 
      //List Pref setSummary 

     } else if (preference instanceof RingtonePreference) { 
      //Ringtone Pref setSummary 
     } else { 
      // For all other preferences, set the summary to the value's 
      // simple string representation. 
      preference.setSummary(stringValue); 
     } 
     return true; 
    } 
}; 

Il y a toujours un problème chaque fois que les paramètres sont chargés, une invite "Preference Saved" sera affichée. Certains vérifient si les données sont lues ou non, ce qui peut aider à résoudre ce problème, mais je n'ai pas connaissance d'un tel contrôle.