0

在我的程序中,我試圖將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 

回答

0

而不是僅僅增加notifyDataSetChanged()通過新arraylist作爲對weatherArrayAdapter的方法,然後調用notifyDataSetChanged()

在你weatherArrayAdapter類創建這樣

public void updateData(List<Weather> weatherList){ 
    this.weatherList=weatherList; 
} 

的方法和你onPostEcecute添加此。

convertJSONtoArrayList(weather); 
weatherArrayAdapter.updateData(weatherList); 
weatherArrayAdapter.notifyDataSetChanged(); 

此外,您的預測列表不會在列表適配器代碼中的任何地方使用。請檢查一次;

編輯: 你逝去的佈局ID爲-1在構造
super(context, -1, forecast)。相反,你需要通過你試圖膨脹ID行吟詩人佈局。

+0

我編輯了我的問題中的代碼以反映這些更改,但在ListView中仍然沒有數據。 –

+0

你沒有在任何地方使用該列表..爲什麼它不顯示數據 – Anonymous

+0

而不是這個天氣日= getItem(位置)使用天氣日= weatherList.get(位置); – Anonymous

相關問題