天气预报APP(2)
之前实现了能够罗列可以罗列出全国所有的省、市、县,然后就是查询全国任意城市的天气信息。查询天气信息使用的是和风天气的api,这个api获得的天气信息是JSON格式的。
使用GSON库解析JSON数据的第一步要先定义用于映照的类。
我对官方实例做了一下删减,然后可以看到这次我想要展示在这次这个项目中的信息:
{
"HeWeather5": [
{
"aqi": {
"city": {
"aqi": "46",
"pm25": "26",
}
},
"basic": {
"city": "秦皇岛",
"id": "CN101091101",
"update": {
"loc": "2017-09-10 14:46",
}
},
"daily_forecast": [
{
"cond": { "txt_d": "小雨",
},
"date": "2017-09-10",
"tmp": {
"max": "26",
"min": "17"
},
},
{ "cond": {
"txt_d": "晴",
},
"date": "2017-09-11", ,
"tmp": {
"max": "25",
"min": "12"
},
},
{
"cond": {
"txt_d": "晴",
},
"date": "2017-09-12",
"tmp": {
"max": "26",
"min": "15"
}, }
],
"status": "ok",
"suggestion": { "comf": {
"brf": "较舒适",
"txt": "白天有雨,从而使空气湿度加大,会使人们感觉有点儿闷热,但早晚的天气很凉爽、舒适。"
},
"cw": {
"brf": "不宜",
"txt": "不宜洗车,未来24小时内有雨,如果在此期间洗车,雨水和路上的泥水可能会再次弄脏您的爱车。"
}, "sport": {
"brf": "较不宜",
"txt": "有降水,推荐您在室内进行健身休闲运动;若坚持户外运动,须注意携带雨具并注意避雨防滑。"
},
}
}
]
}
天气信息总
其中天气情况AQI:
{
"aqi": {
"city": {
"aqi": "46",
"pm25": "26",
}
}
}
定义的AQI类代码为:
public class AQI { public AQIcity city; public class AQIcity{ public String aqi; public String pm25;
}
}
这里要说的就是“{}”包括一个类要用一个类去映照。
然后是城市的信息Basic:
{
"basic": {
"city": "秦皇岛",
"id": "CN101091101",
"update": {
"loc": "2017-09-10 14:46",
}
},
对应应该定义映照的java类:
public class Basic { @SerializedName("city")
public String cityName; @SerializedName("id")
public String weatherId; public Update update; public class Update{ @SerializedName("loc")
public String updateTime;
}
}
如果获得的数据的变量名设置自己不喜欢,可以用@SerializedName("loc")去映照,
然后是天气预测情况daily_forecast:
"daily_forecast": [
{
"cond": { "txt_d": "小雨",
},
"date": "2017-09-10",
"tmp": {
"max": "26",
"min": "17"
},
},
{ "cond": {
"txt_d": "晴",
},
"date": "2017-09-11", ,
"tmp": {
"max": "25",
"min": "12"
},
},
{
"cond": {
"txt_d": "晴",
},
"date": "2017-09-12",
"tmp": {
"max": "26",
"min": "15"
}, }
],
用“[]”包括的是数组,也就是说这个daily_forecast在建立映照的时候,应该也建立一个数组。不过这里先定义数组的成员:
public class Forecast { public String date; @SerializedName("tmp")
public Temperature temperature; @SerializedName("cond")
public More more; public class Temperature{ public String max; public String min;
} public class More{ @SerializedName("txt_d")
public String info; }
}
然后是其他就没什么特殊的了:
public class Now { @SerializedName("tmp")
public String temperature; @SerializedName("cond")
public More more; public class More{ @SerializedName("txt")
public String info;
} }
public class Suggestion { @SerializedName("comf")
public Comfort comfort; @SerializedName("cw")
public CarWash carWash; public Sport sport; public class Comfort { @SerializedName("txt")
public String info; } public class CarWash { @SerializedName("txt")
public String info; } public class Sport { @SerializedName("txt")
public String info; }
}
其他信息
最后要合在一起,因为对于整个天气信息来说,上面的都是用“{}”包括的一个类,所以:
public class Weather { public String status; public Basic basic; public AQI aqi; public Now now; public Suggestion suggestion; @SerializedName("daily_forecast")
public List<Forecast> forecastList;
}
对于[]数组就是在这里定义。
然后就是具体的解析代码:
public class Utility {
/**
* 将返回的JSON数据解析成Weather类
*/
public static Weather handleWeatherResponse(String response){
try {
JSONObject jsonObject = new JSONObject(response);
JSONArray jsonArray = jsonObject.getJSONArray("HeWeather");
String weatherContent = jsonArray.getJSONObject(0).toString();
return new Gson().fromJson(weatherContent,Weather.class);
}catch (Exception e){
e.printStackTrace();
}
return null;
}
}
这样就解析完毕了。
然后是界面的布局代码编写了,
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/colorPrimary"> <ImageView
android:id="@+id/bing_pic_img"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop"/> <ScrollView
android:id="@+id/weather_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="none"
android:overScrollMode="never"> <LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fitsSystemWindows="true"> <include layout="@layout/title"/> <include layout="@layout/now"/> <include layout="@layout/forecast"/> <include layout="@layout/aqi"/> <include layout="@layout/suggestion"/>
</LinearLayout>
</ScrollView> </RelativeLayout>
这是整个活动布局,其中正文部分使用的是子项布局,因为内容比较多,这样显得条理一些。
layout/title:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"> <Button
android:id="@+id/nav_button"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_marginLeft="15dp"
android:layout_centerVertical="true"
android:layout_alignParentLeft="true"
android:background="@drawable/ic_home"/> <TextView
android:id="@+id/title_city"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:textColor="#fff"
android:textSize="20sp"/> <TextView
android:id="@+id/title_update_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="15dp"
android:layout_centerVertical="true"
android:layout_alignParentRight="true"
android:textColor="#fff"
android:textSize="16sp"/> </RelativeLayout>
title
layout/now:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="15dp"
android:layout_marginRight="15dp"> <TextView
android:id="@+id/degree_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end"
android:textColor="#fff"
android:textSize="60sp" /> <TextView
android:id="@+id/weather_info_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end"
android:textAlignment="textEnd"
android:textColor="#fff"
android:textSize="20sp" /> </LinearLayout>
now
layout/forecast:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="15dp"
android:background="#8000"> <TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="预报"
android:layout_marginLeft="15dp"
android:layout_marginTop="15dp"
android:textColor="#fff"
android:textSize="20sp"/> <LinearLayout
android:id="@+id/forecast_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
</LinearLayout>
</LinearLayout>
forecast
layout/forecast_item:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="15dp"> <TextView
android:id="@+id/data_text"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_weight="2"
android:textColor="#fff" /> <TextView
android:id="@+id/info_text"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_weight="1"
android:textColor="#fff" /> <TextView
android:id="@+id/max_text"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_weight="1"
android:gravity="right"
android:textColor="#fff"/> <TextView
android:id="@+id/min_text"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_weight="1"
android:gravity="right"
android:textColor="#fff" />
</LinearLayout>
forcast_item
layout/aqi:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="15dp"
android:background="#8000"> <TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="空气质量"
android:textColor="#fff"
android:textSize="20sp"/> <LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="15dp"> <RelativeLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"> <LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_centerVertical="true"> <TextView
android:id="@+id/aqi_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:textColor="#fff"
android:textSize="40sp"/> <TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="AQI指数"
android:textColor="#fff"/> </LinearLayout>
</RelativeLayout> <RelativeLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"> <LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_centerVertical="true"> <TextView
android:id="@+id/pm25_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:textColor="#fff"
android:textSize="40sp"/> <TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="PM2.5指数"
android:textColor="#fff"/> </LinearLayout> </RelativeLayout> </LinearLayout> </LinearLayout>
aqi
layout/suggestion:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="15dp"
android:background="#8000"> <TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="生活建议"
android:layout_marginLeft="15dp"
android:layout_marginTop="15dp"
android:textColor="#fff"
android:textSize="20sp"/> <TextView
android:id="@+id/comfort_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#fff"
android:layout_margin="15dp"/> <TextView
android:id="@+id/car_wash_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="#fff"
android:layout_margin="15dp"/> <TextView
android:id="@+id/sport_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="#fff"
android:layout_margin="15dp" />
</LinearLayout>
suggestion
然后是活动的java代码:
public class WeatherActivity extends AppCompatActivity { public SwipeRefreshLayout swipeRefreshLayout; private ImageView bingPicImg; private ScrollView weatherLayout; private TextView titleCity; private TextView titleUpdateTime; private TextView degreeText; private TextView weatherInfoText; private LinearLayout forecastLayout; private TextView aqiText; private TextView pm25Text; private TextView comfortText; private TextView carWashText; private TextView sportText; public DrawerLayout drawerLayout; public Button navbutton; String weatherId;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); //使状态栏和背景图融合在一块
if(Build.VERSION.SDK_INT >= 21){
View decorView = getWindow().getDecorView();
decorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_STABLE);//设置为全屏模式
getWindow().setStatusBarColor(Color.TRANSPARENT);
}
setContentView(R.layout.activity_weather); //初始化各个控件
weatherLayout = (ScrollView) findViewById(R.id.weather_layout);
titleCity = (TextView) findViewById(R.id.title_city);
titleUpdateTime = (TextView) findViewById(R.id.title_update_time);
degreeText = (TextView) findViewById(R.id.degree_text);
weatherInfoText = (TextView) findViewById(R.id.weather_info_text);
forecastLayout = (LinearLayout) findViewById(R.id.forecast_layout);
aqiText = (TextView) findViewById(R.id.aqi_text);
pm25Text = (TextView) findViewById(R.id.pm25_text);
comfortText = (TextView) findViewById(R.id.comfort_text);
carWashText = (TextView) findViewById(R.id.car_wash_text);
sportText = (TextView) findViewById(R.id.sport_text);
drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
navbutton = (Button) findViewById(R.id.nav_button); SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
String weatherString = prefs.getString("weather",null);
if(weatherString != null){
//有缓存时直接解析天气数据
Weather weather = Utility.handleWeatherResponse(weatherString);
weatherId = weather.basic.weatherId;
showWeatherInfo(weather);
}else {
//无缓存时直接去服务器查询天气
weatherId = getIntent().getStringExtra("weather_id");
weatherLayout.setVisibility(View.INVISIBLE);
requestWeather(weatherId);
} //向下滑动刷新天气
swipeRefreshLayout = (SwipeRefreshLayout) findViewById(R.id.swipe_refresh);
swipeRefreshLayout.setColorSchemeResources(R.color.colorAccent);
swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener(){
@Override
public void onRefresh() {
requestWeather(weatherId);
}
}); //背景图片
bingPicImg = (ImageView) findViewById(R.id.bing_pic_img);
String bingpic = prefs.getString("bing_pic",null);
if(bingpic != null){
Glide.with(this).load(bingpic).into(bingPicImg);
}else {
loadBingPic();
} //顶部按钮打开侧边栏
navbutton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
drawerLayout.openDrawer(GravityCompat.START);
}
}); } /**
* 根据天气ID请求城市天气信息
*/
public void requestWeather(final String weatherId){
String weatherUrl = "http://guolin.tech/api/weather?cityid=" + weatherId +"&key=32d1c829ed7d483086f4f5b4d5947cef";
HttpUtil.sendOkHttpRequest(weatherUrl, new Callback() {
@Override
public void onResponse(Call call, Response response) throws IOException {
final String responseText = response.body().string();
final Weather weather = Utility.handleWeatherResponse(responseText);
runOnUiThread(new Runnable() {
@Override
public void run() {
if(weather != null && "ok".equals(weather.status)){
SharedPreferences.Editor editor = PreferenceManager.getDefaultSharedPreferences(WeatherActivity.this).edit();
editor.putString("weather", responseText);
editor.apply();
showWeatherInfo(weather);
Toast.makeText(WeatherActivity.this, "天气获取成功", Toast.LENGTH_SHORT).show();
}else {
Toast.makeText(WeatherActivity.this, "天气获取失败", Toast.LENGTH_SHORT).show();
}
swipeRefreshLayout.setRefreshing(false);//传入false表示刷新事件结束
}
});
} @Override
public void onFailure(Call call, IOException e) {
e.printStackTrace();
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(WeatherActivity.this, "天气获取失败", Toast.LENGTH_SHORT).show();
swipeRefreshLayout.setRefreshing(false);//传入false表示刷新事件结束
}
});
} });
} /**
* 处理展示Weather实体类中的数据
*/
private void showWeatherInfo(Weather weather){
String cityName = weather.basic.cityName;
String updateTime = weather.basic.update.updateTime.split(" ")[1];
String degree = weather.now.temperature + "℃";
String weatherInfo = weather.now.more.info;
titleCity.setText(cityName);
titleUpdateTime.setText(updateTime);
degreeText.setText(degree);
weatherInfoText.setText(weatherInfo);
forecastLayout.removeAllViews();
for(Forecast forecast: weather.forecastList){
View view = LayoutInflater.from(this).inflate(R.layout.forecast_item, forecastLayout, false);
TextView dataText = (TextView) view.findViewById(R.id.data_text);
TextView infoText = (TextView) view.findViewById(R.id.info_text);
TextView maxText = (TextView) view.findViewById(R.id.max_text);
TextView minText = (TextView) view.findViewById(R.id.min_text);
dataText.setText(forecast.date);
infoText.setText(forecast.more.info);
maxText.setText(forecast.temperature.max);
minText.setText(forecast.temperature.min);
forecastLayout.addView(view);
}
if(weather.aqi != null){
aqiText.setText(weather.aqi.city.aqi);
pm25Text.setText(weather.aqi.city.pm25);
} String comfort = "舒适度:" + weather.suggestion.comfort.info;
String carWash = "洗车指数:" + weather.suggestion.carWash.info;
String sport = "运动建议:" + weather.suggestion.sport.info; comfortText.setText(comfort);
carWashText.setText(carWash);
sportText.setText(sport);
weatherLayout.setVisibility(View.VISIBLE); } private void loadBingPic(){
String Url = "http://www.bing.com/HPImageArchive.aspx?format=js&idx=0&n=1&mkt=en-US";
HttpUtil.sendOkHttpRequest(Url, new Callback() {
@Override
public void onResponse(Call call, Response response) throws IOException {
String responseText = response.body().string();
final Images images = Utility.handleImagesrResponse(responseText);
final String url = "http://s.cn.bing.net"+ images.url;
try {
runOnUiThread(new Runnable() {
@Override
public void run() {
Glide.with(WeatherActivity.this).load(url).into(bingPicImg);
}
});
}catch (Exception e){
e.printStackTrace();
}
}
@Override
public void onFailure(Call call, IOException e) {
e.printStackTrace();
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(WeatherActivity.this, "图片获取失败", Toast.LENGTH_SHORT).show();
}
});
} });
}
}
WeatherActivity
这个活动实现的功能大概有:
1、向下滑动刷新:
布局代码这样编写。
<android.support.v4.widget.SwipeRefreshLayout
android:id="@+id/swipe_refresh"
android:layout_width="match_parent"
android:layout_height="match_parent"> </ScrollView...> </android.support.v4.widget.SwipeRefreshLayout>
活动中的JAVA代码:
public SwipeRefreshLayout swipeRefreshLayout;
//向下滑动刷新天气
swipeRefreshLayout = (SwipeRefreshLayout) findViewById(R.id.swipe_refresh);
swipeRefreshLayout.setColorSchemeResources(R.color.colorAccent);
swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener(){
@Override
public void onRefresh() {
requestWeather(weatherId);//从服务器获取天气信息
}
});
2、从必应api获得的每天一刷新的图片,使用Glide设置图片。
public class Images { public String url;
}
然后解析java代码:
public class Utility { public static Images handleImagesrResponse(String response){
try {
JSONObject jsonObject = new JSONObject(response);
JSONArray jsonArray = jsonObject.getJSONArray("images");
String weatherContent = jsonArray.getJSONObject(0).toString();
return new Gson().fromJson(weatherContent,Images.class);
}catch (Exception e){
e.printStackTrace();
}
return null;
}
}
活动中调用的代码:
private void loadBingPic(){
String Url = "http://www.bing.com/HPImageArchive.aspx?format=js&idx=0&n=1&mkt=en-US";
HttpUtil.sendOkHttpRequest(Url, new Callback() {
@Override
public void onResponse(Call call, Response response) throws IOException {
String responseText = response.body().string();
final Images images = Utility.handleImagesrResponse(responseText);
final String url = "http://s.cn.bing.net"+ images.url;
try {
runOnUiThread(new Runnable() {
@Override
public void run() {
Glide.with(WeatherActivity.this).load(url).into(bingPicImg);
}
});
}catch (Exception e){
e.printStackTrace();
}
}
@Override
public void onFailure(Call call, IOException e) {
e.printStackTrace();
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(WeatherActivity.this, "图片获取失败", Toast.LENGTH_SHORT).show();
}
});
} });
}
3、侧边栏切换城市:
布局:
<android.support.v4.widget.DrawerLayout
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
</android.support.v4.widget.SwipeRefreshLayout...> <fragment
android:id="@+id/choose_area_fragment"
android:name="xbt.exp20.ChooseAreaFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="start" />
</android.support.v4.widget.DrawerLayout>
之前的省市县列表作为侧边栏,
然后有一个按钮打开侧边栏:
//顶部按钮打开侧边栏
navbutton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
drawerLayout.openDrawer(GravityCompat.START);
}
});
这里打开侧边栏选中某个城市之后要自动把侧边栏关闭,以及刷新天气信息,所以需要修改碎片的列表点击响应:
//列表的点击事件响应
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {
//如果当前级别是省,那点击选取的就是某个省,而想要查询的是选中省有那些城市,市同理 ,想要查询这个城市有那些县
if(currentLevel == LEVEL_PROVINCE){
selectedProvince = provinceList.get(position);
queryCities();//查询全国所有的省,优先从数据库查询,如果没有查到再去服务器上查询
}else if(currentLevel == LEVEL_CITY){
selectedCity = cityList.get(position);
queryCounties();//查询全国所有的省,优先从数据库查询,如果没有查到再去服务器上查询
}else if(currentLevel == LEVEL_COUNTY){
String weatherId = countyList.get(position).getWeatherId();
if(getActivity() instanceof MainActivity) {
Intent intent = new Intent(getActivity(), WeatherActivity.class);
intent.putExtra("weather_id", weatherId);
startActivity(intent);
getActivity().finish();
}else if(getActivity() instanceof WeatherActivity){
WeatherActivity activity = (WeatherActivity) getActivity();
activity.drawerLayout.closeDrawers();
activity.swipeRefreshLayout.setRefreshing(true);
activity.requestWeather(weatherId);
}
}
}
});
使用instanceof关键字判断一个对象是否属于某个类的实例,判断当时碎片处于那个活动中,并设置相应的响应。
基础的根据城市ID获取天气信息,并展示在活动上,以及将获取过的天气缓存下来就不在赘述了
项目截图:
天气预报APP(2)的更多相关文章
- 毕业设计--天气预报App
9月中旬,开始动手做我的毕业设计了,之前一直在纠结做啥,后来想想,既然是做毕业设计,那就大胆地做点自己没接触过的东西吧.然后网上查找资料得知做天气预报需要用到开放的API,而且要用那种现在还在维护的, ...
- android入门学习-天气预报app(一)
引言 学习<android第一行代码>根据书本开发的天气预报app,主要用于熟练操作android开发(android studio3.0平台). 今天主要分享一下从服务器上获取天气信息, ...
- 用Swift实现一款天气预报APP(三)
这个系列的目录: 用Swift实现一款天气预报APP(一) 用Swift实现一款天气预报APP(二) 用Swift实现一款天气预报APP(三) 通过前面的学习,一个天气预报的APP已经基本可用了.至少 ...
- 用Swift实现一款天气预报APP(二)
这个系列的目录: 用Swift实现一款天气预报APP(一) 用Swift实现一款天气预报APP(二) 用Swift实现一款天气预报APP(三) 上篇中主要讲了界面的一些内容,这篇主要讨论网络请求,获得 ...
- 用Swift实现一款天气预报APP(一)
这个系列的目录: 用Swift实现一款天气预报APP(一) 用Swift实现一款天气预报APP(二) 用Swift实现一款天气预报APP(三) Swift作为现在苹果极力推广的语言,发展的非常快.这个 ...
- 基于Android开发的天气预报app(源码下载)
原文:基于Android开发的天气预报app(源码下载) 基于AndroidStudio环境开发的天气app -系统总体介绍:本天气app使用AndroidStudio这个IDE工具在Windows1 ...
- 天气预报APP(1)
一个天气预报APP至少应该具备以下功能: *可以罗列出全国所有的省.市.县: *可以查看全国任意城市的天气信息: *可以自由的切换城市,去查看其他城市的天气: *提供手动更新以及后台自动更新天气的功能 ...
- 69.Android之天气预报app
最近买了本书<Android第一行代码>,通篇看了下感觉不错,书本最后有个实战项目酷欧天气,闲来无事就照着敲了一遍代码,主要在请求天气接口和背景优化做了些小改动,现在来记录下. (1) a ...
- 2.15 学习总结 之 天气预报APP volley(HTTP库)之StringRequest
一.说在前面 昨天 学习了序列化的相关知识 今天 1.学习 volley(HTTP库)的 StringRequest请求 2.使用序列化完成相关案例 遇到问题 请求到的参数的出现中文乱码问题 ...
随机推荐
- .NET Core学习笔记(1)——在Linux下运行Console APP
都说.NET Core可以跨平台,说实话Linux咱也不太懂,咱也不敢问.怎样把一个简单的Console App在Linux下跑起来,真是费了我一番功夫.特做此篇以供指北. .NET Core的大饼我 ...
- nio原理和示例代码
我正在为学习大数据打基础中,为了手撸rpc框架,需要懂得nio的原理,在搞懂nio框架前,我会带着大家手撸一些比较底层的代码,当然今后当我们学会了框架,这些繁琐的代码也就不用写了,但是学一学底层的代码 ...
- Akka-CQRS(16)- gRPC用JWT进行权限管理
前面谈过gRPC的SSL/TLS安全机制,发现设置过程比较复杂:比如证书签名:需要服务端.客户端两头都设置等.想想实际上用JWT会更加便捷,而且更安全和功能强大,因为除JWT的加密签名之外还可以把私密 ...
- c++学习书籍推荐《数据结构C++语言描述:应用标准模板库STL(第2版)》下载
本书是Ford和Topp两位教授于1996看出版的名著Data Structures with C++的第2版,在全球范围内已经有数以万计的学生从中受益.作者将C++语言作为算法描述语言,应用包含规范 ...
- mysql查询语句出现sending data耗时解决
在执行一个简单的sql查询,表中数据量为14万 sql语句为:SELECT id,titile,published_at from spider_36kr_record where is_analyz ...
- [Usaco2007 Open]Fliptile 翻格子游戏题解
问题 B: [Usaco2007 Open]Fliptile 翻格子游戏 时间限制: 5 Sec 内存限制: 128 MB 题目描述 Farmer John knows that an intell ...
- MyBatis 一对多映射
From<MyBatis从入门到精通> <!-- 6.1.2.1 collection集合的嵌套结果映射 和association类似,集合的嵌套结果映射就是指通过一次SQL查询将所 ...
- Jenkins Ci系列目录
Jenkins入门篇 1.Jenkins入门之界面概览 2.Jenkins入门之新建任务 3.Jenkins入门之导航操作 4.Jenkins入门之任务基本操作 5.Jenkins入门之执行Power ...
- 【题解】埃及分数-C++
Description 在古埃及,人们使用单位分数的和(形如1/a的, a是自然数)表示一切有理数. 如:2/3=1/2+1/6,但不允许2/3=1/3+1/3,因为加数中有相同的. 对于一个分数a/ ...
- ASP.NET 前端数据绑定---<%#%>及Eval()的使用
ASP.NET 前端html代码中会经常出现的<%%>的代码,里面的文本其实就是不能直接输出到客户端浏览器的文本,是需要服务器解释的. 在ASP中,<%%>里面的文本是vbsc ...