Android之简洁天气

去年,做了一个简单的桌面天气插件:Android之高仿墨迹天气桌面组件(AppWidgetProvider)   简单得不能再简单了,而且到现在估计都用不了啦,其实一直都想好好修改一下,由于一直比较懒,再加上工作比较忙,转眼就快一年了。最近抽出几天时间,重新完善了一下,很简单,但是个人觉得对于天气一类的应用来说,完全够了。不需要那么多花哨的功能,能简单得告诉我们天气信息就可以了,好了,废话不多说,我们来看看效果:

百度应用apk下载:http://as.baidu.com/a/item?docid=4064176&pre=web_am_se

老版本V1.2.0已上传:http://download.csdn.net/detail/weidi1989/5951563

changelog:

①.加入SplashActivity,减少进入应用时黑屏时间,更好的用户体验。

②.重写BladeView,修复选择城市后,popwindow还未关闭会导致程序异常关闭的bug。

③.修复因空气质量api更改导致获取失败的bug。

④.其他一些小细节优化。

2013年10月28日更新到V1.6.0(中间跳过几个小版本):http://download.csdn.net/detail/weidi1989/6465083

Change Log:

1.增加手势返回。可以手势拖动Activity实现返回,是本次最大的更新,仿ios7.0效果,如下图所示。

2.更换天气接口,之前是使用的天气网信息接口,先更新为自己的服务器,天气信息更加全面,只用请求一次服务器。

3.改变splash实现方式,用一个View代替Activity,使代码更加简洁。

Android之简洁天气_第1张图片


Android之简洁天气_第2张图片 Android之简洁天气_第3张图片
 

1.简单的一个桌面插件,上面是我的,下面是墨迹天气的,当然,图片资源都是来自墨迹天气。字体有些偏差,颜色改成白色就好了。

2.主界面,图片资源来自网易新闻,因为感觉它的图片很小清新,有没有这种感觉啊?哈哈,标题栏跟墨迹天气的功能差不多,左边这个是城市管理,右边两个按钮一个自动定位,一个是刷新天气。下面主界面右上角显示的是空气质量pm2.5值,中间是当天天气情况,下面是未来三天内的天气情况。

Android之简洁天气_第4张图片   Android之简洁天气_第5张图片


3.全国各地城市,总共有2500多个。

4.自动匹配搜索,只是全拼、城市首字母、中文三种搜索方式。

Android之简洁天气_第6张图片   Android之简洁天气_第7张图片


好吧!今天是周六,我就不贴全代码了,估计也没什么人看,就说说主要思路吧!

①.主界面天气信息,是通过解析3个地址才获取到的。

简要天气:http://www.weather.com.cn/data/sk/101280601.html   

详细天气:http://m.weather.com.cn/data/101280601.html        

空气质量:http://www.pm25.in/api/querys/pm2_5.json?city=shenzhen&token=5j1znBVAsnSf5xQyNQyq&stations=no    

注意空气质量这里的token是公钥,每个小时可以请求500次,请别频繁请求,给别的开发工程师留点机会吧~谢谢。


②.桌面插件,我这里就不多说了,基本的使用,在之前的那个博文里面讲得还算比较详细,我这里只是优化了一下,优化了维护插件更新的那个服务,使其不至于轻易得被系统给回收掉。看来还是得贴代码了,我在AndroidManifest.xml文件中做了如下处理:

[html]  view plain  copy
  1. <receiver  
  2.     android:name="com.way.weather.WeatherWidget"  
  3.     android:label="@string/app_name" >  
  4.     <intent-filter>  
  5.         <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />  
  6.         <action android:name="android.intent.action.USER_PRESENT" />  
  7.     </intent-filter>  
  8.   
  9.     <meta-data  
  10.         android:name="android.appwidget.provider"  
  11.         android:resource="@xml/weather_widget_4x2" />  
  12. </receiver>  

多了一个android.intent.action.USER_PRESENT事件的监听,其实他是监听系统唤醒的广播,当系统在睡眠的时候,我们的服务最容易被回收,所以,监听这个广播,当系统唤醒时,重新启动一下这个服务。会使得这个服务变得比较顽强一点。我测试了3天左右,都没出现服务干掉的情况。


③.重点说一下城市列表的匹配搜索吧,首先,2500多个城市,要想快速匹配,临时读取数据库是不可能达到快速的,所以,我们在应用启动时,就可以把这2000多个城市从数据库中读入内存中。然后,根据首字的拼音首字母排序整理好,以便我们设置ListView的Adapter。我们看一下搜索城市的SearchCityAdapter:它实现了Filterable这个接口,覆盖了getFilter这个函数,这个函数是最重要的部分了,匿名内部类Filter将动态传入的字符串进行匹配处理(performFiltering函数处理),然后动态的更新adapter,从而实现动态匹配搜索。

[java]  view plain  copy
  1. public class SearchCityAdapter extends BaseAdapter implements Filterable {  
  2.   
  3.     private List<City> mAllCities;  
  4.     private List<City> mResultCities;  
  5.     private LayoutInflater mInflater;  
  6.     private Context mContext;  
  7.   
  8.   
  9.     public SearchCityAdapter(Context context, List<City> allCities) {  
  10.         mContext = context;  
  11.         mAllCities = allCities;  
  12.         mResultCities = new ArrayList<City>();  
  13.         mInflater = LayoutInflater.from(mContext);  
  14.     }  
  15.   
  16.     @Override  
  17.     public int getCount() {  
  18.         return mResultCities.size();  
  19.     }  
  20.   
  21.     @Override  
  22.     public City getItem(int position) {  
  23.         return mResultCities.get(position);  
  24.     }  
  25.   
  26.     @Override  
  27.     public long getItemId(int position) {  
  28.         return position;  
  29.     }  
  30.   
  31.     @Override  
  32.     public View getView(int position, View convertView, ViewGroup parent) {  
  33.         if (convertView == null) {  
  34.             convertView = mInflater.inflate(R.layout.search_city_item, null);  
  35.         }  
  36.         TextView provinceTv = (TextView) convertView  
  37.                 .findViewById(R.id.search_province);  
  38.         provinceTv.setText(mResultCities.get(position).getProvince());  
  39.         TextView cityTv = (TextView) convertView  
  40.                 .findViewById(R.id.column_title);  
  41.         cityTv.setText(mResultCities.get(position).getCity());  
  42.         return convertView;  
  43.     }  
  44.       
  45.       
  46.     //下面这部分代码是至关重要的  
  47.     @Override  
  48.     public Filter getFilter() {  
  49.         Filter filter = new Filter() {  
  50.             protected void publishResults(CharSequence constraint,  
  51.                     FilterResults results) {  
  52.                 mResultCities = (ArrayList<City>) results.values;  
  53.                 if (results.count > 0) {  
  54.                     notifyDataSetChanged();  
  55.                 } else {  
  56.                     notifyDataSetInvalidated();  
  57.                 }  
  58.             }  
  59.   
  60.             protected FilterResults performFiltering(CharSequence s) {  
  61.                 String str = s.toString().toUpperCase();  
  62.                 // mFilterStr = str;  
  63.                 FilterResults results = new FilterResults();  
  64.                 ArrayList<City> cityList = new ArrayList<City>();  
  65.                 if (mAllCities != null && mAllCities.size() != 0) {  
  66.                     for (City cb : mAllCities) {  
  67.                         // 匹配全屏、首字母、和城市名中文  
  68.                         if (cb.getAllFristPY().indexOf(str) > -1  
  69.                                 || cb.getAllPY().indexOf(str) > -1  
  70.                                 || cb.getCity().indexOf(str) > -1) {  
  71.                             cityList.add(cb);  
  72.                         }  
  73.                     }  
  74.                 }  
  75.                 results.values = cityList;  
  76.                 results.count = cityList.size();  
  77.                 return results;  
  78.             }  
  79.         };  
  80.         return filter;  
  81.     }  
  82.   
  83. }  

接下来让我们看一下,数据是如何传递给SearchCityAdapter进行处理的,我就贴出监听EditText动态变化的那个函数,mSearchCityAdapter.getFilter().filter(s);这样一句话就可以了。其实也不是很难嘛!

[java]  view plain  copy
  1. @Override  
  2.     public void onTextChanged(CharSequence s, int start, int before, int count) {  
  3.         mSearchCityAdapter = new SearchCityAdapter(SelectCtiyActivity.this,  
  4.                 mCities);  
  5.         mSearchListView.setAdapter(mSearchCityAdapter);  
  6.         mSearchListView.setTextFilterEnabled(true);  
  7.         if (mCities.size() < 1 || TextUtils.isEmpty(s)) {  
  8.             mCityContainer.setVisibility(View.VISIBLE);  
  9.             mSearchContainer.setVisibility(View.INVISIBLE);  
  10.             mClearSearchBtn.setVisibility(View.GONE);  
  11.         } else {  
  12.             mClearSearchBtn.setVisibility(View.VISIBLE);  
  13.             mCityContainer.setVisibility(View.INVISIBLE);  
  14.             mSearchContainer.setVisibility(View.VISIBLE);  
  15.             mSearchCityAdapter.getFilter().filter(s);  
  16.         }  
  17.     }  

转自:http://blog.csdn.net/way_ping_li/article/details/9260915

你可能感兴趣的:(Android之简洁天气)