Android:Moring-早安闹钟开发过程记录(三)

FragmentWeather天气界面实现

1.界面预览

(放大了看真的是丑哭啊)


FragmentWeather.jpg

该Fragment需要实现以下的一些功能

  • A.天气数据的显示
  • B.背景图白天晚上进行切换
  • C.菜单键业务逻辑
    这个Fragment的业务逻辑的实现还是比较简单,没有遇到什么太大的困难。简单记录一下实现的过程。

A

  • 数据来源
    这里我使用的接口是聚合数据的天气预报API(免费)
    API地址:https://www.juhe.cn/docs/api/id/73 (非广告~)
    在官方给的文档中有很详细的关于各种语言如何请求数据的示例代码,直接Copy到项目中稍加改动就可以了。为了保持代码的简洁,我将请求代码封装为一个工具类WeatherUtils.class
//1.根据城市查询天气
public static String  getRequest1(String city){
    String result =null;
    String url ="http://op.juhe.cn/onebox/weather/query";//请求接口地址
    Map<String, Object> params = new HashMap<String, Object>();//请求参数
    params.put("cityname",city);//要查询的城市,如:温州、上海、北京
    params.put("key",APPKEY);//应用APPKEY(应用详细页查询)
    params.put("dtype","json");//返回数据的格式,xml或json,默认json
    try {
        result =net(url, params, "GET");
    } catch (Exception e) {
        e.printStackTrace();
    }
    return result;
}

这段代码是copy过来的稍微修改了一下,接收一个用户选择的城市作为参数,另外因为我是用Gson来解析数据,因此需要将返回类型改为String,return获取到的数据。
考虑到以后需要在本地缓存读取数据因此将解析数据的代码也封装成方法

if (result==null){
    Toast.makeText(mActivity,"请求天气数据出错,请检查网络",Toast.LENGTH_SHORT).show();
    return;
}
Gson gson=new Gson();
mWetherData = gson.fromJson(result, WetherData.class);

这里需要定义一个类用于接收所需要的天气信息
解析完数据后判断一下error code,在官方文档里面给出了error code

注意 定义变量名称的时候必须与Json返回数据中的变量名称完全一致,且变量类型也必须一致!

推荐一个Json格式化的工具 HiJson,另外也可以在线进行格式化,方便阅读
在线解析Json地址:http://json.cn/ (直接粘贴上去就OK 简单粗暴)

  • 初始化数据
  • 加载数据的逻辑是,先检查本地缓存,是否有缓存,如果有的话优先加载缓存,再向服务器请求数据,避免出现网络不好,长时间不显示内容,影响用户体验。
  • 另外由于天气变化在几个小时内的变化不会特别大,频繁请求服务器的话会浪费用户很多流量,因此每次从服务器请求到数据后记录下此时的时间,当下一次初始化数据的时候如果没有超过四个小时就不请求服务器而直接从缓存读取,节省用户流量。(用户贵为天啊)
protected void initData() {    
          cityName=PrefUtils.getString(mActivity,ConsUtils.CURRENT_CITY,"重庆");
    //如果不展示直接return
          if(isClose) return;
    //每次如果本地有缓存的话 先从本地读取缓存
          getWetherInfoFromLocal();
    //判断当前有没有网络
          if(NetUtils.isInternetAvilable(mActivity)){
        //如果有网络请求网络数据前判断一下上一次请求是什么时候,如果超过四个小时就请求
              long last=PrefUtils.getlong(mActivity,ConsUtils.Last_REQUEST_TIME,0l);              
              long currentTime=System.currentTimeMillis();
              Log.d("changecity","last"+last+"current"+currentTime);
              if((currentTime-last)>4*60*60*1000){
                  getWetherInfoFromServer();
              }
          }else{
              Toast.makeText(mActivity,"更新天气失败,请检查网络",Toast.LENGTH_SHORT).show();
          }
}

请求服务器之前一定要判断下一下是否有网络,因为从官方copy过来的代码里没有判断,不然会崩的。

public static boolean isInternetAvilable(Context context) {
          Boolean isOn=false;
          ConnectivityManager cm= (ConnectivityManager) context.getSystemService(context.CONNECTIVITY_SERVICE);
          NetworkInfo net=cm.getActiveNetworkInfo();
          if(net!=null){
              isOn=cm.getActiveNetworkInfo().isAvailable();
          }
          return isOn;
}

补充:还可以进一步判断当前是手机流量还是wifi,这里因为数据流量很小不再进一步判断
请求到服务器后需要将数据缓存到本地

private void saveDataToLocal(String result) {
          File file=new File(mActivity.getCacheDir(),"wether.json");
          FileWriter fw=null;    BufferedWriter bw=null;
          try {
              if(!file.exists()) file.createNewFile();
              fw=new FileWriter(file);
              bw=new BufferedWriter(fw);
              bw.write(result);
              bw.flush();
          } catch (IOException e) {
              e.printStackTrace();
          }finally {
              try {
                  bw.close();
              } catch (IOException e) {
                  e.printStackTrace();
              }
          }
      }

同理还要写一个方法从本来读取,代码就不贴了,又顺便复习了下IO流

从服务器请求的时候判断一下返回数据是否成功,再缓存到本地,否则万一返回的是错误数据还缓存了起来就悲剧了~

获取数据就完成了,接下来需要将数据显示出来

  • 显示数据
    显示数据就比较简单了。
    首先在在onCreateView中初始化控件initView()通过findViewById拿到对应的控件对象
    然后在解析数据parseData()方法中加入显示代码,再加个小动画就OK啦
    我的天气图标也是聚合天气提供的(为什么不自己找?因为懒)有两套图标,因此在显示图标是判断下当前时间是白天还是晚上。
if(currentHour>=6&&currentHour<=18){
    //白天
          mBackground.setBackgroundResource(R.color.blue);
          if(img<ConsUtils.WETHER_IMG_DAY.length){
              mIcon.setImageResource(ConsUtils.WETHER_IMG_DAY[img]);
          }else{
              mIcon.setImageResource(ConsUtils.WETHER_IMG_DAY[0]);
          }
      }else{
       //夜晚
          mBackground.setBackgroundResource(R.color.purple);
          //防止脚标越界
          if(img<ConsUtils.WETHER_IMG_NIGHT.length){
              mIcon.setImageResource(ConsUtils.WETHER_IMG_NIGHT[img]);
          }else{
              mIcon.setImageResource(ConsUtils.WETHER_IMG_NIGHT[0]);    
      }
}

说明:天气的图标我是存放在两个数组中总共32张,因为服务器返回的数据为序号 img “0”,这种格式,有可能返回的数字超出了数组长度,所以为了保证健壮性,我进行了角标的判断,以免发生越界

B

就在上面的代码中实现了~

C

菜单键的业务逻辑就是切换菜单嘛。。。
侧滑菜单是直接用的开源框架SlidingMenu
github地址:https://github.com/jfeinstein10/SlidingMenu
有这个框架实现起来就So easy
有多easy?两行代码

//拿到侧滑菜单对象
SlidingMenu slidingMenu=getSlidingMenu();
slidingMenu.toggle();

补充一下:因为SlidingMenu是在HomeActivtiy中创建的,而菜单键是放在FragmentWeather中的,如果在FragmentWeather中实现的话还需要先拿到HomeActivity对象,再拿到SlidingMenu对象代码如下

HomeActivity home=getActivity();
SlidingMenu sildingMenu=home.getSlidingMenu();
SlidingMenu slidingMenu=getSlidingMenu();
slidingMenu.toggle();

ps.还需要实现ImageView的监听事件。
对于我这么懒得人当然希望代码越少越好,我就试着在布局文件中添加onClick属性,然后直接在HomeActivity中去实现,居然没有问题。
所以我读书少,没见识,一直以为Fragment中的控件不能再Activity中去实现相应逻辑。
完整代码

public void openMenu(View view){
    //拿到侧滑菜单对象
          SlidingMenu slidingMenu=getSlidingMenu();
          slidingMenu.toggle();
      }

结尾

天气页面的基本业务逻辑就实现完成啦,但代码还没有完,在FragmentMenu的处理中时还会在FragmentWeather中添加一些代码

未完待续...

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,332评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,508评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,812评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,607评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,728评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,919评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,071评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,802评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,256评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,576评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,712评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,389评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,032评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,798评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,026评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,473评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,606评论 2 350

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,834评论 25 707
  • 工厂模式类似于现实生活中的工厂可以产生大量相似的商品,去做同样的事情,实现同样的效果;这时候需要使用工厂模式。简单...
    舟渔行舟阅读 7,728评论 2 17
  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 12,066评论 4 62
  • 問君歸期路,佳期又负。風流總把韶華誤。 对花眉蹙,谓叹幽情难诉。几番红泪垂,心悲苦。 卫鬓楚步,燕歌赵舞,绮户空闺...
    时光不留恋悲伤阅读 203评论 0 4
  • 我的第二故乡 当年我离开你的时候 想到从此再不来此地了 命运却让我 一而在再而三地 回到熟悉的第二故...
    申维希阅读 298评论 0 3