我已经编写了一个用于从USGS获取地震数据的应用程序,我想为想要检查不同mag级别的用户添加首选项更改。但是,当首选项发生更改时,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 :(得分: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()
。
答案 1 :(得分:0)
我终于解决了这个问题。
我在onResume上调用fetch数据方法。由于我无法在AsyncTask上获取空数据,因此会导致NullPointExection。所以我使用默认URL来执行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;
}
}
希望它可以帮助任何面临同样问题的人。还请告知是否有任何&#34;不良原因&#34;获取onResume中的数据。
感谢您的回复!!!!!!