天气项目·mainActivity

当点击搜索按钮时,跳到->SearchCityActivity,在搜索页面搜索完成,返回->mainActivity,这时mainActivity需要知道SearchCityActivity的查询结果,用反向传值来实现。

mainActivity->(1)SearchCityActivity->(2)mainActivity,在(2)处的传值称为反向传值, mainActivity->BMIResultActivity 即是正向传值。反向传值启动intent的方式不同

通过把用户搜索到的结果存到本地,可以实现下次登录还是用户搜索的城市。把数据保存到SharedPreferences,SharedPreferences是Android APP 的一个保存用户信息的轻量级文件,用于报讯少量的用户信息。
存储格式:键值对的形式保存数据。当app中没有SharedPreferences文件时,getSharedPreferences()会创建一个名为weather的SharedPreferences文件,并设置文件读取权限为该应用私有。当APP中存在SharedPreferences文件,getSharedPreferences()就会读取文件,生成对象。

一、声明变量

在变量中new Handler,并重写handleMessage(Message msg),用handlerMessage先区分不同消息。

  • 当网络请求结束时,停止动画。
  • 如果网络请求出现异常
  • 如果网络请求正常,数据解析完成,将msg的信息封装进一个weatherBean。并取出个字段赋给各textView用于显示.
    根据getWeatherFromNetWork()中的判断分别调用getWeatherDateSuccess(WeatherBean weatherBean)和netWorkRequestError(String errorString)方法 ,赋给message不同值并调用 netWorkFinishHandler.sendMessage(message),将message传回主线程。
public void handleMessage(Message msg) {
     refreshAnimationStop();
     if (msg.what == 404) {
         netWorkErrorTextView.setText((String) msg.obj);
         return
        }
     if (msg.what == 100) {   // 网络请求成功,数据解析完成。
         WeatherBean weatherBean = (WeatherBean) msg.obj;
         cityTextView.setText(weatherBean.getCityName());
         setPmcolor(weatherBean.getPmLevel());
         setFutureDayWeather(weatherBean.getFutureWeatherList());
         Editor editor = sharePreferences.edit();//获取sharePreferences的编辑
         editor.putInt("cityCode", cityCode).commit();//向编辑中添加一个键为cityCode的键值对并调用commit()方法写入文件中
        }
}

二、private void setFutureDayWeatherArrayList<FutureWeatherBean> futureWeatherList)

把一个布局代码转换为view控件:通过布局转换器LayoutInflater对象的inflate(R.layout.futureday_layout, null)方法。获取LayoutInflater的对象用LayoutInflater的from(getApplicationContext())静态方法获取

for (int i = 0; i < futureWeatherList.size(); i++) {// 在向容器中添加布局时,要先清空容器型布局
                FutureWeatherBean futureWeatherBean = futureWeatherList.get(i);// 创建小部件显示未来天气的布局
                View futureDayLayout = LayoutInflater.from(
                        getApplicationContext()).inflate(
                        R.layout.futureday_layout, null);
                TextView futureWeekTextView = (TextView) futureDayLayout
                        .findViewById(R.id.future_week_tv);// 从futureDayLayout找到控件
                TextView futureWeatherTextView = (TextView) futureDayLayout
                        .findViewById(R.id.future_weather_tv);
                TextView futureTempertureTextView = (TextView) futureDayLayout
                        .findViewById(R.id.future_temperture_tv);
                futureTempertureTextView.setText(futureWeatherBean
                        .getTemperture());// 给相关控件赋值
                futureWeatherTextView.setText(futureWeatherBean.getWeather()
                        + futureWeatherBean.getWind());
                futureWeekTextView.setText(futureWeatherBean.getWeek());
                futureDayWeatherListLayout.addView(futureDayLayout);// 把赋值完成的布局加载到横向ScrollView的布局中去
            }

三、配置显示污染程度的颜色条

1.配置color文件:在res文件夹下的values文件夹中新建一个名为color的AndroidXML文件

文件位置

2.在Strings文件中配置pmLevel.(values文件夹里) 从res文件夹下的values文件夹中读取 文字/颜色常量,通过getResources()获取资源目录,再调用getString(R.string.best)/getColor(R.color.yellow) 取出常量

    <color name="green">#00EE00</color>
    <color name="yellow">#EEEE00</color>
    <color name="orange">#EEAD0E</color>
    <color name="red">#FF0000</color>
    <color name="violet">#EE00EE</color>
    <color name="brown">#8B6914</color>
    <string name="best">优</string>
    <string name="better">良</string>
    <string name="pollution">轻度污染</string>
    <string name="mpollution">中度污染</string>
    <string name="spollution">严重污染</string>
    <string name="hpollution">重度污染</string>

</resources>

**3.private void setPmcolor(String pmLevel) **

if (pmLevel.contains(getResources().getString(R.string.best))) {
    pmStateColorView.setBackgroundColor(getResources().getColor(R.color.green));
    } 
else if (pmLevel.contains(getResources().getString(R.string.better))) {
    pmStateColorView.setBackgroundColor(getResources().getColor(R.color.yellow));

四、protected void onCreate(Bundle savedInstanceState)

    sharePreferences = getSharedPreferences("weather", Context.MODE_PRIVATE);
    cityCode = sharePreferences.getInt("cityCode", 101010100);
    findViews();
    getWeatherDateFromNetwork();
    setListener();

getSharedPreferences(String name, int mode):从sharePreferences取出key为cityCode的值,如果sharePreferences文件中没有这个键值,参数二为默认值,设置访问权限。
SharedPreferences: 用来存储轻量级数据,存储格式为“键值对”。

  • 保存:
SharedPreferences mySharedPreferences= getSharedPreferences("test",Activity.MODE_PRIVATE);//实例化
SharedPreferences.Editor editor = mySharedPreferences.edit();//实例化editor
//用putString的方法保存数据
editor.putString("name", "Karl");//保存数据
editor.commit(); //提交当前数据
  • 读取
SharedPreferences sharedPreferences= getSharedPreferences("test",Activity.MODE_PRIVATE);//实例化
String name =sharedPreferences.getString("name", "");// 获得value,参数2是默认值
Toast.makeText(this, "读取数据如下:"+"\n"+"name:" + name ,Toast.LENGTH_LONG).show(); //toast显示信息

五、@Override protected void onActivityResult(int requestCode, int resultCode, Intent data)

反向传值后会调用的方法。用if语句先区分是哪个页面的返回值。

  • 参数1:用于区分不同的Activity的返回值;
  • 参数2:返回值内容;
  • 参数3:返回页面的Intent。
if (requestCode == 300) {
    cityCode = resultCode;// 保存resultCode的值,resultCode即搜索到的城市ID。
    getWeatherDateFromNetwork();
}

六、private void setListener()

refreshImageView响应方法里添加方法getWeatherDateFromNetwork()
searchImageView响应方法里添加反向传值的接收语句。反向传值调用的启动activity的方法。参数2用于区分不同activity的返回值结果。

    Intent intent = new Intent(MainActivity.this,SearchCityCodeActivity.class);//跳转
    startActivityForResult(intent, 300);

七、findViews() 略

八、private void getWeatherDateFromNetwork()

获取网络必须要申请获取网络状态的用户权限 ACCESS_NETWORK_STATE
1.添加用户权限:打开Mamifest文件,选取permission标签


添加Permission

先获取网络状态:用连接管理类ConnectivityManager的对象去获取网络连接 netWorkInfo的对象判断netWorkInfo有无,确定网络有无。此时要申请Users Permission。


申请权限png
  • 处理异常
        ConnectivityManager manager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo netWorkInfo = manager.getActiveNetworkInfo();
        if (netWorkInfo == null) {
            netWorkErrorTextView.setText("网络异常,请检查网络3");
            return;
        }

申请网络连接是耗时操作,在子线程中操作。新建一个线程,如果线程的开启方式调用.run(),线程的Runnable()的run()方法还是在主线程中执行。调用start(),线程的Runnable的run()方法才会在新建的后台线程中执行。 给网址建立网络连接的路径。"+ cityCode + " 则显示行对应的城市,如果为0则显示本地天气。并把代码封装成getWeatherDateSuccess(WeatherBean weatherBean)和netWorkRequestError(String errorString)方法。 新建message,根据if判断赋给message What标签和内容Obj。

refreshAnimationStart();// 不能放在Thread里,要放在UI主线程里。
new Thread(new Runnable() {
    public void run() {
    String urlString = "http://weather.123.duba.net/static/weather_info/"+ cityCode + ".html";
    StringBuffer stringBuffer = new StringBuffer(); //保存网络请求的结果
    try {
        String resultString =NetWorkUtils.doGet(urlString);//新建NetWorkUtils类,将代码封装成其中的一个方法
        if (TextUtils.isEmpty(resultString)) { // 异常处理
            netWorkRequestError("网络加载异常,请重新加载2");
            return;
           }
        if (!resultString.contains("weather_callback")) { //异常处理
            return;
            }   
        WeatherBean weatherBean = new WeatherBean(resultString);
        getWeatherDateSuccess(weatherBean);
    } catch (Exception e) { // 异常捕获:把catch中的异常放大到所有异常
        e.printStackTrace();
        netWorkRequestError("网络加载异常,请重新加载1");
    }
}
  • 创建通知的消息,message.what是给这个消息设置唯一的标识,用于handlerMessage方法中区分不同的消息;message.obj保存要展示的数据对象,用于主线程刷新UI;通过Handler对象的sendMessage方法发送消息,通知主线程
private void getWeatherDateSuccess(WeatherBean weatherBean) {
   Message message = new Message();
   message.what = 100; 
   message.obj = weatherBean; 
   netWorkFinishHandler.sendMessage(message);
}
}).start();// 启动线程

九、private void netWorkRequestError(String errorString)

网络加载数据失败时,通知UI线程去显示提示。message.what为message的标签。动画为帧动画。

Message message = new Message();
message.what = 404;
message.obj = errorString;
netWorkFinishHandler.sendMessage(message);

十、private void refreshAnimationStart()

把动画资源设为refreshImage的背景,获取资源。 启动动画资源,当动画开启时,refreshImageView设为不可点击状态。

refreshImageView.setBackgroundResource(R.drawable.pb_bg);
refreshAnimation = (AnimationDrawable) refreshImageView.getBackground();
refreshAnimation.start();
refreshImageView.setEnabled(false);

十一、private void refreshAnimationStop()

把刷新按钮图片放到refreshImageView上,并将refreshImageView设置为可以点击

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

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,633评论 18 139
  • ¥开启¥ 【iAPP实现进入界面执行逐一显】 〖2017-08-25 15:22:14〗 《//首先开一个线程,因...
    小菜c阅读 6,367评论 0 17
  • 2017年5月17日 Kylin_Wu 标注(★☆)为考纲明确给出考点(必考) 常见手机系统(★☆) And...
    Azur_wxj阅读 1,802评论 0 10
  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,598评论 18 399
  • 是疲惫来得太早, 还是黑夜来得太晚? 你累了, 就歇息。
    小剧在成长阅读 214评论 0 3