2016-07-28 43 views
-1

我已经编写了一个应用程序来获取来自USGS的地震数据,我想为想要使用不同mag等级检查的用户添加首选项更改。但是,如果首选项发生更改,onStart不会触发。请建议我如何修改代码SharedPreferences在更改时不启动onStart

public class EarthquakeFragment extends Fragment{ 
public EarthquakeFragment(){ 
} 

ListView listView; 
private EarthquakeAdapter eAdapter; 

@Override 
public View onCreateView (LayoutInflater inflater, ViewGroup container, Bundle saveInstanceState) 
{ 
    View rootView = inflater.inflate(R.layout.earthquake_fragment, container, false); 

    eAdapter = new EarthquakeAdapter(getActivity(), new ArrayList<EarthquakeInfo>()); 
    listView = (ListView) rootView.findViewById(R.id.list); 
    listView.setAdapter(eAdapter); 

    listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { 
     @Override 
     public void onItemClick(AdapterView<?> parent, View view, int position, long id) { 
      EarthquakeInfo currentEarthquake = eAdapter.getItem(position); 
      String url = currentEarthquake.getUrl(); 

      Intent intent = new Intent(Intent.ACTION_VIEW); 
      intent.setData(Uri.parse(url)); 
      startActivity(intent); 
     } 
    }); 
    setHasOptionsMenu(true); 
    // Start the AsyncTask to fetch the earthquake data 
    EarthquakeAsyncTask task = new EarthquakeAsyncTask(); 
    task.execute(); 
    return rootView; 
} 


/** 
* {@link AsyncTask} to perform the network request on a background thread, and then 
* update the UI with the list of earthquakes in the response. 
* 
* AsyncTask has three generic parameters: the input type, a type used for progress updates, and 
* an output type. Our task will take a String URL, and return an Earthquake. We won't do 
* progress updates, so the second generic is just Void. 
* 
* We'll only override two of the methods of AsyncTask: doInBackground() and onPostExecute(). 
* The doInBackground() method runs on a background thread, so it can run long-running code 
* (like network activity), without interfering with the responsiveness of the app. 
* Then onPostExecute() is passed the result of doInBackground() method, but runs on the 
* UI thread, so it can use the produced data to update the UI. 
*/ 
private class EarthquakeAsyncTask extends AsyncTask<String, Void, List<EarthquakeInfo>> { 

    /** 
    * This method runs on a background thread and performs the network request. 
    * We should not update the UI from a background thread, so we return a list of 
    * {@link EarthquakeInfo}s as the result. 
    */ 
    @Override 
    protected List<EarthquakeInfo> doInBackground(String... urls) { 


     SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(getActivity()); 
     String maglevel = preferences.getString(getString(R.string.pref_mag_key), ""); 

      final String BASE_URL= "http://earthquake.usgs.gov/fdsnws/event/1/query?"; 
      final String FORMAT_PARAM = "format"; 
      final String ORDER_PARAM = "orderby"; 
      final String START_PARAM = "starttime"; 
      final String END_PARAM = "endtime"; 
      final String MINMAG_PARAM = "minmag"; 
      String format = "geojson"; 
      String order = "time"; 
      String start = "2016-01-01"; 
      String end = "2016-07-28"; 
      String minmag = maglevel; 

      Uri buildUri = Uri.parse(BASE_URL).buildUpon() 
        .appendQueryParameter(FORMAT_PARAM, format) 
        .appendQueryParameter(ORDER_PARAM, order) 
        .appendQueryParameter(START_PARAM, start) 
        .appendQueryParameter(END_PARAM, end) 
        .appendQueryParameter(MINMAG_PARAM, minmag) 
        .build(); 
      String url = buildUri.toString(); 


     // Don't perform the request if there are no URLs, or the first URL is null. 
     if (url == null) { 
      return null; 
     } 

     List<EarthquakeInfo> result = QueryUtils.fetchEarthquakeData(url); 
     return result; 
    } 

    /** 
    * This method runs on the main UI thread after the background work has been 
    * completed. This method receives as input, the return value from the doInBackground() 
    * method. First we clear out the adapter, to get rid of earthquake data from a previous 
    * query to USGS. Then we update the adapter with the new list of earthquakes, 
    * which will trigger the ListView to re-populate its list items. 
    */ 
    @Override 
    protected void onPostExecute(List<EarthquakeInfo> data) { 
     // Clear the adapter of previous earthquake data 
     onStart(); 
     eAdapter.clear(); 

     // If there is a valid list of {@link Earthquake}s, then add them to the adapter's 
     // data set. This will trigger the ListView to update. 
     if (data != null && !data.isEmpty()) { 
      eAdapter.addAll(data); 
     } 
    } 
} 
} 

非常感谢!!!!!

+0

当共享首选项的值更改时,是否希望执行活动的onStart()事件? –

+0

是的。这是我想要做的 –

+0

不知道为什么有人会在没有评论他们的问题是什么问题的情况下倒下了。这应该停止。 – Talha

回答

0

聆听SharedPreferences上的更改不会如此。

对于您需要实现SharedPreferences.OnSharedPreferenceChangeListener

SharedPreferences.OnSharedPreferenceChangeListener spChanged = new 
          SharedPreferences.OnSharedPreferenceChangeListener() { 
      @Override 
    public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, 
      String key) { 
     // your stuff here 
    } 
}; 

在你PreferenceActivity,即让你的PreferenceActivity类的成员,然后做registerOnSharedPreferenceChangeListener(spChanged)PreferenceActivity.onCreate()方法。

+0

谢谢lalongooo;)我会明天尝试 –

0

我终于解决了这个问题。

我在onResume上调用fetch数据方法。由于我无法在AsyncTask上使用空数据获取数据,因此会导致NullPointExection。所以我让我执行AsyncTask的默认网址。之后,我在onResume上添加SharePreference。之后,问题就解决了。

这是我的代码。

public class EarthquakeFragment extends Fragment{ 

public EarthquakeFragment(){ 
} 

ListView listView; 
EarthquakeAdapter eAdapter; 

@Override 
public View onCreateView (LayoutInflater inflater, ViewGroup container, Bundle saveInstanceState) 
{ 
    String defaultUrl = getActivity().getString(R.string.default_link); 

    View rootView = inflater.inflate(R.layout.earthquake_fragment, container, false); 

    eAdapter = new EarthquakeAdapter(getActivity(), new ArrayList<EarthquakeInfo>()); 
    listView = (ListView) rootView.findViewById(R.id.list); 
    listView.setAdapter(eAdapter); 

    listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { 
     @Override 
     public void onItemClick(AdapterView<?> parent, View view, int position, long id) { 
      EarthquakeInfo currentEarthquake = eAdapter.getItem(position); 
      String url = currentEarthquake.getUrl(); 

      Intent intent = new Intent(Intent.ACTION_VIEW); 
      intent.setData(Uri.parse(url)); 
      startActivity(intent); 
     } 
    }); 
    setHasOptionsMenu(true); 
    // Start the AsyncTask to fetch the earthquake data 
    EarthquakeAsyncTask task = new EarthquakeAsyncTask(); 
    task.execute(defaultUrl); 
    return rootView; 
} 

private void updateEarthquake() { 
    EarthquakeAsyncTask earthquakeTask = new EarthquakeAsyncTask(); 
    SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(getActivity()); 
    String maglevel = preferences.getString(getString(R.string.pref_mag_key), getString(R.string.pref_mag_6)); 
    String startTime = preferences.getString(getString(R.string.start_key), getString(R.string.pref_time_2016)); 
    String sortby= preferences.getString(getString(R.string.sort_key), getString(R.string.pref_sortby_time)); 

    final String BASE_URL= "http://earthquake.usgs.gov/fdsnws/event/1/query?"; 
    final String FORMAT_PARAM = "format"; 
    final String ORDER_PARAM = "orderby"; 
    final String START_PARAM = "starttime"; 
    final String END_PARAM = "endtime"; 
    final String MINMAG_PARAM = "minmag"; 
    final String LIMIT_PARAM = "limit"; 
    final String format = "geojson"; 
    final String order = sortby; 
    String start = startTime+"-01-01"; 
    String end = startTime+"-12-31"; 
    String minmag = maglevel; 
    final String limit = "10"; 

    Uri buildUri = Uri.parse(BASE_URL).buildUpon() 
      .appendQueryParameter(FORMAT_PARAM, format) 
      .appendQueryParameter(ORDER_PARAM, order) 
      .appendQueryParameter(START_PARAM, start) 
      .appendQueryParameter(END_PARAM, end) 
      .appendQueryParameter(MINMAG_PARAM, minmag) 
      .appendQueryParameter(LIMIT_PARAM, limit) 
      .build(); 
    String url = buildUri.toString(); 

    // Don't perform the request if there are no URLs, or the first URL is null. 
    if (url == null) { 
    } 
    earthquakeTask.execute(url); 
} 

@Override 
public void onResume(){ 
    super.onResume(); 
    updateEarthquake(); 
} 

/** 
* {@link AsyncTask} to perform the network request on a background thread, and then 
* update the UI with the list of earthquakes in the response. 
* 
* AsyncTask has three generic parameters: the input type, a type used for progress updates, and 
* an output type. Our task will take a String URL, and return an Earthquake. We won't do 
* progress updates, so the second generic is just Void. 
* 
* We'll only override two of the methods of AsyncTask: doInBackground() and onPostExecute(). 
* The doInBackground() method runs on a background thread, so it can run long-running code 
* (like network activity), without interfering with the responsiveness of the app. 
* Then onPostExecute() is passed the result of doInBackground() method, but runs on the 
* UI thread, so it can use the produced data to update the UI. 
*/ 
private class EarthquakeAsyncTask extends AsyncTask<String, Void, List<EarthquakeInfo>> { 

    /** 
    * This method runs on a background thread and performs the network request. 
    * We should not update the UI from a background thread, so we return a list of 
    * {@link EarthquakeInfo}s as the result. 
    */ 
    @Override 
    protected List<EarthquakeInfo> doInBackground(String... urls) { 

     List<EarthquakeInfo> result = QueryUtils.fetchEarthquakeData(urls[0]); 
     return result; 
    } 

    /** 
    * This method runs on the main UI thread after the background work has been 
    * completed. This method receives as input, the return value from the doInBackground() 
    * method. First we clear out the adapter, to get rid of earthquake data from a previous 
    * query to USGS. Then we update the adapter with the new list of earthquakes, 
    * which will trigger the ListView to re-populate its list items. 
    */ 
    @Override 
    protected void onPostExecute(List<EarthquakeInfo> data) { 
     // Clear the adapter of previous earthquake data 
     eAdapter.clear(); 
     // If there is a valid list of {@link Earthquake}s, then add them to the adapter's 
     // data set. This will trigger the ListView to update. 
     if (data != null && !data.isEmpty()) { 
      eAdapter.addAll(data); 
     } 
    } 
} 
} 

这是我的设置活动代码

public class SettingActivity extends PreferenceActivity 
    implements Preference.OnPreferenceChangeListener{ 

@Override 
public void onCreate (Bundle savedInstanceState){ 
    super.onCreate(savedInstanceState); 
    addPreferencesFromResource(R.xml.pref_general); 

    bindPreferenceSummaryToValue(findPreference(getString(R.string.pref_mag_key))); 
    bindPreferenceSummaryToValue(findPreference(getString(R.string.start_key))); 
    bindPreferenceSummaryToValue(findPreference(getString(R.string.sort_key))); 

} 

private void bindPreferenceSummaryToValue(Preference preference) { 
    preference.setOnPreferenceChangeListener(this); 
    onPreferenceChange(preference, 
      PreferenceManager 
        .getDefaultSharedPreferences(preference.getContext()) 
        .getString(preference.getKey(), "")); 

} 

@Override 
public boolean onPreferenceChange(Preference preference, Object newValue) { 
    String stringValue = newValue.toString(); 
    if (preference instanceof ListPreference) { 
     ListPreference preferences = (ListPreference) preference; 
     int prefIndex = preferences.findIndexOfValue(stringValue); 
     if (prefIndex >= 0) { 
      preference.setSummary(preferences.getEntries()[prefIndex]); 
     }else { 
      preference.setSummary(stringValue); 
     } 
    } 
    return true; 
} 
} 

希望它可以帮助谁也面临同样问题的任何人。请同时告知是否有任何“错误理由”在onResume中获取数据。

谢谢你的回复!!!!!!