在我的程序中,我試圖將List的天氣狀況更新爲ListView。我下載並將JSON存儲在asyncTask中,然後在onPostExecute和notifyDataSetChanged期間將數據解析到我的List中。我在這裏查看了幾個相關的問題,但我不確定我錯過了什麼。這裏是我的MainActivity.javaListView在customAdapter.notifyDataSetChanged後沒有更新
public class MainActivity extends AppCompatActivity {
private List<Weather> weatherList = new ArrayList<>();
private WeatherArrayAdapter weatherArrayAdapter;
private ListView weatherListView;
private TextView locationEditText;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
weatherListView = (ListView)findViewById(R.id.weatherListView);
weatherArrayAdapter = new WeatherArrayAdapter(this, weatherList);
weatherListView.setAdapter(weatherArrayAdapter);
locationEditText = (TextView)findViewById(R.id.locationEditText);
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//Create a URL using the specific city entered by the user
URL url = createURL(locationEditText.getText().toString());
//As long as there is not a null url we get the weather
if(url!=null){
Log.e("URL", url.toString());
dismissKeyboard(locationEditText);
GetWeatherTask getLocalWeatherTask = new GetWeatherTask();
getLocalWeatherTask.execute(url);
}
else{
Snackbar.make(findViewById(R.id.coordinatorLayout),R.string.invalid_url, Snackbar.LENGTH_LONG).show();
}
}
});
}
private void dismissKeyboard(View v){
InputMethodManager inputMethodManager = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
inputMethodManager.hideSoftInputFromWindow(v.getWindowToken(), 0);
}
private URL createURL(String city){
String apiKey = getString(R.string.api_key);
String baseURL = getString(R.string.web_service_url);
try{
String urlString = baseURL + URLEncoder.encode(city, "UTF-8") + "&units=imperial&cnt=16&APPID=" + apiKey;
return new URL(urlString);
}
catch (Exception e){
e.printStackTrace();
}
//Returns null only if the URL data was malformed
return null;
}
private class GetWeatherTask extends AsyncTask<URL, Void, JSONObject>{
@Override
protected JSONObject doInBackground(URL... params) {
HttpURLConnection connection = null;
try{
URL url = params[0];
Log.e("URL", url.toString());
connection = (HttpURLConnection)url.openConnection();
int responseCode = connection.getResponseCode();
if(responseCode == 200){
StringBuilder stringBuilder = new StringBuilder();
try(BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(connection.getInputStream(), "UTF-8"))){
String line;
while((line = bufferedReader.readLine()) != null){
stringBuilder.append(line);
}
connection.disconnect();
return new JSONObject(stringBuilder.toString());
}
catch (Exception e){
e.printStackTrace();
}
}
else {
Snackbar.make(findViewById(R.id.coordinatorLayout), R.string.connect_fail, Snackbar.LENGTH_LONG).show();
}
}
catch (Exception e){
e.printStackTrace();
}
finally {
if (connection != null) {
connection.disconnect();
}
}
return null;
}
@Override
protected void onPostExecute(JSONObject weather){
convertJSONtoArrayList(weather);
weatherArrayAdapter.updateData(weatherList);
weatherArrayAdapter.notifyDataSetChanged();
weatherListView.smoothScrollToPosition(0);
}
private void convertJSONtoArrayList(JSONObject forecast){
weatherList.clear();
try{
JSONArray list = forecast.getJSONArray("list");
for(int i = 0; i < list.length(); i++){
JSONObject day = list.getJSONObject(i);
JSONObject temperatures = day.getJSONObject("main");
JSONObject weather = day.getJSONArray("weather").getJSONObject(0);
Calendar hour = Calendar.getInstance();
hour.setTime(new SimpleDateFormat("yyyy-MM-dd' 'HH:mm:ss", Locale.US).parse(day.getString("dt_txt")));
weatherList.add(new Weather(
day.getLong("dt")*1000,
hour.getTimeInMillis(),
temperatures.getDouble("temp_min"),
temperatures.getDouble("temp_max"),
temperatures.getDouble("humidity"),
weather.getString("icon"),
weather.getString("description")));
}
}
catch (Exception e){
e.printStackTrace();
}
}
}
}
這裏是我的WeatherArrayAdapter.java
class WeatherArrayAdapter extends ArrayAdapter<Weather> {
private static class ViewHolder{
ImageView conditionImageView;
TextView dayTextView;
TextView lowTextView;
TextView highTextView;
TextView humidityTextView;
TextView timeOfDayTextView;
TextView descriptionTextView;
}
//Create a map of used bitmaps to prevent re-downloading previously used bitmaps
private Map<String, Bitmap> bitmaps = new HashMap<>();
private List<Weather> weatherList;
WeatherArrayAdapter(Context context, List<Weather> forecast){
super(context, R.layout.item_list, forecast);
this.weatherList = forecast;
}
@NonNull
@Override
public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
Log.e("ADAPTER", "getView()");
Weather day = weatherList.get(position);
ViewHolder viewHolder;
if(convertView == null){
viewHolder = new ViewHolder();
LayoutInflater inflater = LayoutInflater.from(getContext());
convertView = inflater.inflate(R.layout.list_item, parent, false);
viewHolder.conditionImageView = convertView.findViewById(R.id.conditionImageView);
viewHolder.dayTextView = convertView.findViewById(R.id.dayTextView);
viewHolder.highTextView = convertView.findViewById(R.id.highTextView);
viewHolder.lowTextView = convertView.findViewById(R.id.lowTextView);
viewHolder.humidityTextView = convertView.findViewById(R.id.humidityTextView);
viewHolder.timeOfDayTextView = convertView.findViewById(R.id.timeOfDayTextView);
viewHolder.descriptionTextView = convertView.findViewById(R.id.descriptionTextView);
}
else{
viewHolder = (ViewHolder) convertView.getTag();
}
if (bitmaps.containsKey(day.iconURL)) {
viewHolder.conditionImageView.setImageBitmap(bitmaps.get(day.iconURL));
} else {
new LoadImageTask(viewHolder.conditionImageView).execute(day.iconURL);
}
viewHolder.dayTextView.setText(day.dayOfWeek);
viewHolder.highTextView.setText(day.maxTemp);
viewHolder.lowTextView.setText(day.minTemp);
viewHolder.humidityTextView.setText(day.humidity);
viewHolder.timeOfDayTextView.setText(day.timeOfDay);
viewHolder.descriptionTextView.setText(day.description);
return convertView;
}
private class LoadImageTask extends AsyncTask<String, Void, Bitmap>{
ImageView imageView;
LoadImageTask(ImageView view){
this.imageView = view;
}
@Override
protected Bitmap doInBackground(String... strings) {
Bitmap bmp = null;
HttpURLConnection connection = null;
try{
URL url = new URL(strings[0]);
connection = (HttpURLConnection)url.openConnection();
try(InputStream inputStream = connection.getInputStream()){
bmp = BitmapFactory.decodeStream(inputStream);
bitmaps.put(strings[0], bmp);
}
catch (Exception e){
e.printStackTrace();
}
}
catch (Exception e){
e.printStackTrace();
}
finally {
if (connection != null) {
connection.disconnect();
}
}
return bmp;
}
@Override
protected void onPostExecute(Bitmap bitmap){
imageView.setImageBitmap(bitmap);
}
}
public void updateData(List<Weather> weatherList){
this.weatherList = weatherList;
}
}
的Weather.java類
class Weather {
final String dayOfWeek, minTemp, maxTemp, humidity, iconURL, timeOfDay, description;
Weather(long timestamp, long timeOfDayMS, double minTemp, double maxTemp, double humidity, String iconName, String description){
NumberFormat numberFormat = NumberFormat.getNumberInstance();
numberFormat.setParseIntegerOnly(true);
this.dayOfWeek = convertTimestampToDay(timestamp);
this.timeOfDay = convertTimeOfDayToHM(timeOfDayMS);
this.minTemp = numberFormat.format(minTemp) + "\u00B0F";
this.maxTemp = numberFormat.format(maxTemp) + "\u00B0F";
this.humidity = numberFormat.format(humidity) + "%";
this.iconURL = "http://openweathermap.org/img/w/" + iconName + ".png";
this.description = description;
}
//Given a timestamp of milliseconds since epoch, we create a calendar and derive a day of the week name
private String convertTimestampToDay(long timestamp){
return new SimpleDateFormat("EEEE", Locale.US).format(getCalendar(timestamp).getTimeInMillis());
}
//Given a timestamp of milliseconds since epoch, we create a calendar and derive a time of day in hour:minute
private String convertTimeOfDayToHM(long timeOfDay){
return new SimpleDateFormat("h:mm a", Locale.US).format(getCalendar(timeOfDay).getTimeInMillis());
}
private Calendar getCalendar(long timestamp){
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(timestamp);
calendar.setTimeZone(TimeZone.getTimeZone(Calendar.getInstance().getTimeZone().getDisplayName()));
return calendar;
}
}
而且最後我list_item.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="horizontal" android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="@+id/conditionImageView"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_weight="1"
android:contentDescription="@string/weather_image"
android:scaleType="fitCenter"
app:srcCompat="@mipmap/ic_launcher_round" />
<GridLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:columnCount="3"
android:rowCount="2"
android:useDefaultMargins="true"
android:visibility="visible">
<TextView
android:id="@+id/dayTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_column="0"
android:layout_columnWeight="1"
android:layout_row="0"
android:text="@string/day"
android:textAppearance="@android:style/TextAppearance.Material.Large" />
<TextView
android:id="@+id/lowTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_column="0"
android:layout_columnWeight="1"
android:layout_row="1"
android:text="@string/low" />
<TextView
android:id="@+id/highTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_column="2"
android:layout_columnWeight="1"
android:layout_row="1"
android:text="@string/high" />
<TextView
android:id="@+id/humidityTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_column="1"
android:layout_columnWeight="1"
android:layout_row="1"
android:text="@string/humidity" />
<TextView
android:id="@+id/timeOfDayTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_column="1"
android:layout_columnWeight="1"
android:layout_row="0"
android:text="@string/time" />
<TextView
android:id="@+id/descriptionTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_column="2"
android:layout_columnWeight="1"
android:layout_row="0"
android:text="@string/desc" />
</GridLayout>
</LinearLayout>
任何幫助都非常讚賞編輯。
編輯我已經解決了超級構造函數,我從服務器獲取 數據不幸的是,我的列表視圖中仍是空白。 以下是我從API獲取的JSON日誌。
D/JSON: {"cod":"200","message":0.1604,"cnt":16,"list":[{"dt":1507280400,"main":{"temp":52,"temp_min":50.88,"temp_max":52,"pressure":1031.72,"sea_level":1039.36,"grnd_level":1031.72,"humidity":70,"temp_kf":0.62},"weather":[{"id":800,"main":"Clear","description":"clear sky","icon":"01d"}],"clouds":{"all":0},"wind":{"speed":8.84,"deg":325.503},"sys":{"pod":"d"},"dt_txt":"2017-10-06 09:00:00"},{"dt":1507291200,"main":{"temp":56.17,"temp_min":55.34,"temp_max":56.17,"pressure":1032,"sea_level":1039.58,"grnd_level":1032,"humidity":65,"temp_kf":0.46},"weather":[{"id":800,"main":"Clear","description":"clear sky","icon":"01d"}],"clouds":{"all":0},"wind":{"speed":8.95,"deg":326.001},"sys":{"pod":"d"},"dt_txt":"2017-10-06 12:00:00"},{"dt":1507302000,"main":{"temp":57.13,"temp_min":56.58,"temp_max":57.13,"pressure":1031.96,"sea_level":1039.61,"grnd_level":1031.96,"humidity":57,"temp_kf":0.31},"weather":[{"id":800,"main":"Clear","description":"clear sky","icon":"01d"}],"clouds":{"all":0},"wind":{"speed":8.08,"deg":321.001},"sys":{"pod":"d"},"dt_txt":"2017-10-06 15:00:00"},{"dt":1507312800,"main":{"temp":51.49,"temp_min":51.22,"temp_max":51.49,"pressure":1031.85,"sea_level":1039.49,"grnd_level":1031.85,"humidity":63,"temp_kf":0.15},"weather":[{"id":803,"main":"Clouds","description":"broken clouds","icon":"04n"}],"clouds":{"all":64},"wind":{"speed":3.71,"deg":290.502},"sys":{"pod":"n"},"dt_txt":"2017-10-06 18:00:00"},{"dt":1507323600,"main":{"temp":46.91,"temp_min":46.91,"temp_max":46.91,"pressure":1031.69,"sea_level":1039.4,"grnd_level":1031.69,"humidity":81,"temp_kf":0},"weather":[{"id":801,"main":"Clouds","description":"few clouds","icon":"02n"}],"clouds":{"all":20},"wind":{"speed":4.85,"deg":223.502},"sys":{"pod":"n"},"dt_txt":"2017-10-06 21:00:00"},{"dt":1507334400,"main":{"temp":47.11,"temp_min":47.11,"temp_max":47.11,"pressure":1030.48,"sea_level":1038.22,"grnd_level":1030.48,"humidity":85,"temp_kf":0},"weather":[{"id":802,"main":"Clouds","description":"scattered clouds","icon":"03n"}],"clouds":{"all":32},"wind":{"speed":7.74,"deg":249.001},"sys":{"pod":"n"},"dt_txt":"2017-10-07 00:00:00"},{"dt":1507345200,"main":{"temp":48.53,"temp_min":48.53,"temp_max":48.53,"pressure":1028.24,"sea_level":1035.82,"grnd_level":1028.24,"humidity":78,"temp_kf":0},"weather":[{"id":802,"main":"Clouds","description":"scattered clouds","icon":"03n"}],"clouds":{"all":44},"wind":{"speed":9.42,"deg":237.503},"sys":{"pod":"n"},"dt_txt":"2017-10-07 03:00:00"},{"dt":1507356000,"main":{"temp":49.38,"temp_min":49.38,"temp_max":49.38,"pressure":1025.51,"sea_level":1033.19,"grnd_level":1025.51,"humidity":90,"temp_kf":0},"weather":[{"id":500,"main":"Rain","description":"light rain","icon":"10n"}],"clouds":{"all":88},"wind":{"speed":13.04,"deg":237.506},"rain":{"3h":0.715},"sys":{"pod":"n"},"dt_txt":"2017-10-07 06:00:00"},{"dt":1507366800,"main":{"temp":55.61,"temp_min":55.61,"temp_max":55.61,"pressure":1023.56,"sea_level":1031.15,"grnd_level":1023.56,"humidity":89,"temp_kf":0},"weather":[{"id":500,"main":"Rain","description":"light rain","icon":"10d"}],"clouds":{"all":80},"wind":{"speed":14.45,"deg":250.003},"rain":{"3h":0.21},"sys":{"pod":"d"},"dt_txt":"2017-10-07 09:00:00"},{"dt":1507377600,"main":{"temp":61.41,"temp_min":61.41,"temp_max":61.41,"pressure":1021.72,"sea_level":1029.22,"grnd_level":1021.72,"humidity":78,"temp_kf":0},"weather":[{"id":500,"main":"Rain","description":"light rain","icon":"10d"}],"clouds":{"all":76},"wind":{"speed":14.79,"deg":265.003},"rain":{"3h":0.145},"sys":{"pod":"d"},"dt_txt":"2017-10-07 12:00:00"},{"dt":1507388400,"main":{"temp":62.38,"temp_min":62.38,"temp_max":62.38,"pressure":1020.3,"sea_level":1027.8,"grnd_level":1020.3,"humidity":69,"temp_kf":0},"weather":[{"id":500,"main":"Rain","description":"light rain","icon":"10d"}],"clouds":{"all":92},"wind":{"speed":13.76,"deg":280},"rain":{"3h":0.0049999999999999},"sys":{"pod":"d"},"dt_txt":"2017-10-07 15:00:00"},{"dt":1507399200,"main":{"temp":59.14,"temp_min":59.14,"temp_max":59.14,"pressure":1020.7,"sea_level":1028.21,"grnd_level":1020.7,"humidity":69,"temp_kf
我編輯了我的問題中的代碼以反映這些更改,但在ListView中仍然沒有數據。 –
你沒有在任何地方使用該列表..爲什麼它不顯示數據 – Anonymous
而不是這個天氣日= getItem(位置)使用天氣日= weatherList.get(位置); – Anonymous