Flutter天气查询APP的交互式界面
2023-11-08 22:56:57
前言
在上一篇文章中,我们已经创建了一个显示城市、温度、天气、湿度的界面。但是这个界面只有一个显示的功能,没有任何可交互的地方。本篇文章将继续完善查询天气的APP的功能,使其具备交互性。
创建城市选择页面
在Android中新建一个页面,需要用Activity来表示。在res/layout目录下创建一个xml文件,作为Activity的布局文件。在这个布局文件中,我们可以放置各种控件,比如TextView、Button、EditText等。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/city_text_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="城市:" />
<EditText
android:id="@+id/city_edit_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="请输入城市名" />
<Button
android:id="@+id/search_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="查询" />
</LinearLayout>
在这个布局文件中,我们放置了一个TextView、一个EditText和一个Button。TextView用来显示“城市:”的文字,EditText用来输入城市名,Button用来查询天气。
在Activity中,我们需要编写代码来处理这些控件的点击事件。
public class CitySelectActivity extends Activity {
private TextView cityTextView;
private EditText cityEditText;
private Button searchButton;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_city_select);
cityTextView = findViewById(R.id.city_text_view);
cityEditText = findViewById(R.id.city_edit_text);
searchButton = findViewById(R.id.search_button);
searchButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String city = cityEditText.getText().toString();
Intent intent = new Intent(CitySelectActivity.this, MainActivity.class);
intent.putExtra("city", city);
startActivity(intent);
}
});
}
}
在onCreate()方法中,我们首先调用super.onCreate(savedInstanceState)方法来完成Activity的初始化工作。然后,我们通过findViewById()方法来获取控件的实例。最后,我们为searchButton设置了一个点击事件监听器。当searchButton被点击时,我们会获取EditText中输入的城市名,然后通过Intent将城市名传递给MainActivity。
天气查询
在MainActivity中,我们需要编写代码来查询天气。我们可以使用OpenWeatherMap的API来获取天气数据。
public class MainActivity extends Activity {
private TextView cityTextView;
private TextView temperatureTextView;
private TextView weatherTextView;
private TextView humidityTextView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
cityTextView = findViewById(R.id.city_text_view);
temperatureTextView = findViewById(R.id.temperature_text_view);
weatherTextView = findViewById(R.id.weather_text_view);
humidityTextView = findViewById(R.id.humidity_text_view);
String city = getIntent().getStringExtra("city");
cityTextView.setText(city);
// 查询天气
new WeatherQueryTask().execute(city);
}
private class WeatherQueryTask extends AsyncTask<String, Void, WeatherData> {
@Override
protected WeatherData doInBackground(String... params) {
String city = params[0];
WeatherData weatherData = null;
try {
URL url = new URL("http://api.openweathermap.org/data/2.5/weather?q=" + city + "&appid=YOUR_API_KEY");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.connect();
BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
StringBuilder sb = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
sb.append(line);
}
reader.close();
String jsonStr = sb.toString();
weatherData = new WeatherData(jsonStr);
} catch (Exception e) {
e.printStackTrace();
}
return weatherData;
}
@Override
protected void onPostExecute(WeatherData weatherData) {
if (weatherData != null) {
temperatureTextView.setText(weatherData.getTemperature());
weatherTextView.setText(weatherData.getWeather());
humidityTextView.setText(weatherData.getHumidity());
} else {
Toast.makeText(MainActivity.this, "查询天气失败", Toast.LENGTH_SHORT).show();
}
}
}
}
在onCreate()方法中,我们首先调用super.onCreate(savedInstanceState)方法来完成Activity的初始化工作。然后,我们通过findViewById()方法来获取控件的实例。接着,我们从Intent中获取城市名并将其显示在cityTextView中。
接下来,我们创建一个WeatherQueryTask的实例,并调用其execute()方法来查询天气。WeatherQueryTask是一个异步任务,它会在后台查询天气数据。查询完成后,onPostExecute()方法会被调用,在onPostExecute()方法中,我们会将天气数据显示在相应的TextView中。
数据展示
在MainActivity中,我们需要编写代码来展示天气数据。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/city_text_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="城市:" />
<TextView
android:id="@+id/temperature_text_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="温度:" />
<TextView
android:id="@+id/weather_text_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="天气:" />
<TextView
android:id="@+id/humidity_text_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="湿度:" />
</LinearLayout>
在这个布局文件中,我们放置了四个TextView。TextView用来显示城市、温度、天气和湿度。
在Activity中,我们需要编写代码来设置TextView的文本内容。
public class MainActivity extends Activity {
private TextView cityTextView;
private TextView temperatureTextView;
private TextView weatherTextView;
private TextView humidityTextView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
cityTextView = findViewById(R.id.city_text_view);
temperatureTextView = findViewById(R.id.temperature_text_view);
weatherTextView = findViewById(R.id.weather_text_view);
humidityTextView = findViewById(R.id.humidity_text_view);
String city = getIntent().getStringExtra("city");
cityTextView.setText(city);
// 查询天气
new WeatherQueryTask().execute(city);
}
private class WeatherQueryTask extends AsyncTask<String, Void, WeatherData> {
@Override
protected WeatherData doInBackground(String... params) {
String city = params[0];
WeatherData weatherData = null;
try {
URL url = new URL("http://api.openweathermap.org/data/2.5/weather?q=" + city + "&appid=YOUR_API_KEY");
HttpURLConnection connection = (Http