简单天气获取demo的制作(一)
来源:互联网 发布:python爬虫百度云资源 编辑:程序博客网 时间:2024/05/22 03:14
简单天气获取demo的制作(一)
今天创了博客,想分享一下自己学习的东西,也作为记录自己一点一滴进步的空间吧。本人是大一学生,刚入android不久,纯正小菜鸟,平常没事喜欢写点东西,希望大神们不要抨击。(跪谢)
今天玩手机的时候看到了iphone的weather界面挺好看,于是萌生了做一个demo的想法。
界面是这样的,当时就觉得哎呦,不错哦,由于水平有限,各种折叠的动画还不会做,在这里给大家分享一下如何制作简单的weather demo吧。
好啦,是时候打开编辑器啦,首先是xml的制作,各位稍等。哈哈哈
<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.example.howard.weather.MainActivity"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="City" android:id="@+id/main_city" android:textSize="45sp" android:layout_alignParentTop="true" android:layout_centerHorizontal="true" android:layout_marginTop="20dp" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="weather" android:textSize="30sp" android:id="@+id/main_weather" android:layout_below="@+id/main_city" android:layout_centerHorizontal="true" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="temp" android:textSize="60sp" android:id="@+id/main_tmp" android:layout_below="@+id/main_weather" android:layout_centerHorizontal="true" android:layout_marginBottom="25dp"/> <com.example.howard.weather.HorizontalListView android:layout_marginTop="5dp" android:layout_marginBottom="5dp" android:layout_below="@+id/main_tmp" android:layout_width="match_parent" android:layout_height="100dp" android:id="@+id/hor_lv_main" android:background="@color/colorPrimaryDark" android:scrollbars="horizontal"></com.example.howard.weather.HorizontalListView> <TextView android:textSize="20sp" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Monday" android:layout_marginLeft="10dp" android:layout_marginRight="10dp" android:id="@+id/main_today" android:layout_above="@+id/hor_lv_main" android:layout_alignParentStart="true" /> <TextView android:textSize="20sp" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Today" android:id="@+id/textView2" android:layout_alignTop="@+id/main_today" android:layout_toEndOf="@+id/main_today" /> <TextView android:textSize="20sp" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="min" android:layout_alignTop="@+id/main_max" android:layout_toStartOf="@+id/main_max" android:layout_marginRight="15dp" android:id="@+id/main_min"/> <TextView android:textSize="20sp" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="max" android:layout_marginRight="20dp" android:id="@+id/main_max" android:layout_above="@+id/hor_lv_main" android:layout_alignParentEnd="true"/> <ListView android:layout_width="match_parent" android:layout_height="match_parent" android:layout_below="@+id/hor_lv_main" android:id="@+id/lv_main"></ListView></RelativeLayout>
这就是Main xml啦 效果图是这样的。
中间那块是一个水平的listview用的别人给的框架,也不知道能不能实现,先放源码吧。
/* * HorizontalListView.java v1.5 * * * The MIT License * Copyright (c) 2011 Paul Soucy (paul@dev-smart.com) * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * */package com.example.howard.weather;import java.util.LinkedList;import java.util.Queue;import android.annotation.SuppressLint;import android.content.Context;import android.database.DataSetObserver;import android.graphics.Rect;import android.util.AttributeSet;import android.view.GestureDetector;import android.view.GestureDetector.OnGestureListener;import android.view.MotionEvent;import android.view.View;import android.widget.AdapterView;import android.widget.ListAdapter;import android.widget.Scroller;public class HorizontalListView extends AdapterView<ListAdapter> { public boolean mAlwaysOverrideTouch = true; protected ListAdapter mAdapter; private int mLeftViewIndex = -1; private int mRightViewIndex = 0; protected int mCurrentX; protected int mNextX; private int mMaxX = Integer.MAX_VALUE; private int mDisplayOffset = 0; protected Scroller mScroller; private GestureDetector mGesture; private Queue<View> mRemovedViewQueue = new LinkedList<View>(); private OnItemSelectedListener mOnItemSelected; private OnItemClickListener mOnItemClicked; private OnItemLongClickListener mOnItemLongClicked; private boolean mDataChanged = false; public HorizontalListView(Context context, AttributeSet attrs) { super(context, attrs); initView(); } private synchronized void initView() { mLeftViewIndex = -1; mRightViewIndex = 0; mDisplayOffset = 0; mCurrentX = 0; mNextX = 0; mMaxX = Integer.MAX_VALUE; mScroller = new Scroller(getContext()); mGesture = new GestureDetector(getContext(), mOnGesture); } @Override public void setOnItemSelectedListener(OnItemSelectedListener listener) { mOnItemSelected = listener; } @Override public void setOnItemClickListener(OnItemClickListener listener){ mOnItemClicked = listener; } @Override public void setOnItemLongClickListener(OnItemLongClickListener listener) { mOnItemLongClicked = listener; } @Override public void setOnKeyListener(OnKeyListener l) { super.setOnKeyListener(l); } private DataSetObserver mDataObserver = new DataSetObserver() { @Override public void onChanged() { synchronized(HorizontalListView.this){ mDataChanged = true; } invalidate(); requestLayout(); } @Override public void onInvalidated() { reset(); invalidate(); requestLayout(); } }; @Override public ListAdapter getAdapter() { return mAdapter; } @Override public View getSelectedView() { //TODO: implement return null; } @Override public void setAdapter(ListAdapter adapter) { if(mAdapter != null) { mAdapter.unregisterDataSetObserver(mDataObserver); } mAdapter = adapter; mAdapter.registerDataSetObserver(mDataObserver); reset(); } private synchronized void reset(){ initView(); removeAllViewsInLayout(); requestLayout(); } @Override public void setSelection(int position) { //TODO: implement } private void addAndMeasureChild(final View child, int viewPos) { LayoutParams params = child.getLayoutParams(); if(params == null) { params = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT); } addViewInLayout(child, viewPos, params, true); child.measure(MeasureSpec.makeMeasureSpec(getWidth(), MeasureSpec.AT_MOST), MeasureSpec.makeMeasureSpec(getHeight(), MeasureSpec.AT_MOST)); } @SuppressLint("DrawAllocation") @Override protected synchronized void onLayout(boolean changed, int left, int top, int right, int bottom) { super.onLayout(changed, left, top, right, bottom); if(mAdapter == null){ return; } if(mDataChanged){ int oldCurrentX = mCurrentX; initView(); removeAllViewsInLayout(); mNextX = oldCurrentX; mDataChanged = false; } if(mScroller.computeScrollOffset()){ int scrollx = mScroller.getCurrX(); mNextX = scrollx; } if(mNextX <= 0){ mNextX = 0; mScroller.forceFinished(true); } if(mNextX >= mMaxX) { mNextX = mMaxX; mScroller.forceFinished(true); } int dx = mCurrentX - mNextX; removeNonVisibleItems(dx); fillList(dx); positionItems(dx); mCurrentX = mNextX; if(!mScroller.isFinished()){ post(new Runnable(){ @Override public void run() { requestLayout(); } }); } } private void fillList(final int dx) { int edge = 0; View child = getChildAt(getChildCount()-1); if(child != null) { edge = child.getRight(); } fillListRight(edge, dx); edge = 0; child = getChildAt(0); if(child != null) { edge = child.getLeft(); } fillListLeft(edge, dx); } private void fillListRight(int rightEdge, final int dx) { while(rightEdge + dx < getWidth() && mRightViewIndex < mAdapter.getCount()) { View child = mAdapter.getView(mRightViewIndex, mRemovedViewQueue.poll(), this); addAndMeasureChild(child, -1); rightEdge += child.getMeasuredWidth(); if(mRightViewIndex == mAdapter.getCount()-1) { mMaxX = mCurrentX + rightEdge - getWidth(); } if (mMaxX < 0) { mMaxX = 0; } mRightViewIndex++; } } private void fillListLeft(int leftEdge, final int dx) { while(leftEdge + dx > 0 && mLeftViewIndex >= 0) { View child = mAdapter.getView(mLeftViewIndex, mRemovedViewQueue.poll(), this); addAndMeasureChild(child, 0); leftEdge -= child.getMeasuredWidth(); mLeftViewIndex--; mDisplayOffset -= child.getMeasuredWidth(); } } private void removeNonVisibleItems(final int dx) { View child = getChildAt(0); while(child != null && child.getRight() + dx <= 0) { mDisplayOffset += child.getMeasuredWidth(); mRemovedViewQueue.offer(child); removeViewInLayout(child); mLeftViewIndex++; child = getChildAt(0); } child = getChildAt(getChildCount()-1); while(child != null && child.getLeft() + dx >= getWidth()) { mRemovedViewQueue.offer(child); removeViewInLayout(child); mRightViewIndex--; child = getChildAt(getChildCount()-1); } } private void positionItems(final int dx) { if(getChildCount() > 0){ mDisplayOffset += dx; int left = mDisplayOffset; for(int i=0;i<getChildCount();i++){ View child = getChildAt(i); int childWidth = child.getMeasuredWidth(); child.layout(left, 0, left + childWidth, child.getMeasuredHeight()); left += childWidth + child.getPaddingRight(); } } } public synchronized void scrollTo(int x) { mScroller.startScroll(mNextX, 0, x - mNextX, 0); requestLayout(); } @Override public boolean dispatchTouchEvent(MotionEvent ev) { boolean handled = super.dispatchTouchEvent(ev); handled |= mGesture.onTouchEvent(ev); return handled; } protected boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { synchronized(HorizontalListView.this){ mScroller.fling(mNextX, 0, (int)-velocityX, 0, 0, mMaxX, 0, 0); } requestLayout(); return true; } protected boolean onDown(MotionEvent e) { mScroller.forceFinished(true); return true; } private OnGestureListener mOnGesture = new GestureDetector.SimpleOnGestureListener() { @Override public boolean onDown(MotionEvent e) { return HorizontalListView.this.onDown(e); } @Override public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { return HorizontalListView.this.onFling(e1, e2, velocityX, velocityY); } @Override public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { synchronized(HorizontalListView.this){ mNextX += (int)distanceX; } requestLayout(); return true; } @Override public boolean onSingleTapConfirmed(MotionEvent e) { for(int i=0;i<getChildCount();i++){ View child = getChildAt(i); if (isEventWithinView(e, child)) { if(mOnItemClicked != null){ mOnItemClicked.onItemClick(HorizontalListView.this, child, mLeftViewIndex + 1 + i, mAdapter.getItemId( mLeftViewIndex + 1 + i )); } if(mOnItemSelected != null){ mOnItemSelected.onItemSelected(HorizontalListView.this, child, mLeftViewIndex + 1 + i, mAdapter.getItemId( mLeftViewIndex + 1 + i )); } break; } } return true; } @Override public void onLongPress(MotionEvent e) { int childCount = getChildCount(); for (int i = 0; i < childCount; i++) { View child = getChildAt(i); if (isEventWithinView(e, child)) { if (mOnItemLongClicked != null) { mOnItemLongClicked.onItemLongClick(HorizontalListView.this, child, mLeftViewIndex + 1 + i, mAdapter.getItemId(mLeftViewIndex + 1 + i)); } break; } } } private boolean isEventWithinView(MotionEvent e, View child) { Rect viewRect = new Rect(); int[] childPosition = new int[2]; child.getLocationOnScreen(childPosition); int left = childPosition[0]; int right = left + child.getWidth(); int top = childPosition[1]; int bottom = top + child.getHeight(); viewRect.set(left, top, right, bottom); return viewRect.contains((int) e.getRawX(), (int) e.getRawY()); } };}
有需要的同学可以自己研究一下,反正我现在没准备管它,先把主界面和最下面的listview搞定吧。下面做什么呢?解析数据呀!本人用的是和风天气的api,感觉还不错。这是我的一个api接口
json格式是这样的
很复杂是吧,先不管他,我们先看一下他的结构,然后就开始着手item的界面了。(这里我们需要四个数据,今天是周几,第二是天气,还有就是最高温和最低温.)我去写xml啦,嘿嘿,稍等。
<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:paddingTop="5dp" android:paddingBottom="5dp"> <TextView android:textSize="20sp" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Monday" android:layout_marginLeft="10dp" android:layout_marginRight="10dp" android:id="@+id/item_today" /> <TextView android:textSize="20sp" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="min" android:layout_alignTop="@+id/item_max" android:layout_toStartOf="@+id/item_max" android:layout_marginRight="15dp" android:id="@+id/item_min"/> <TextView android:textSize="20sp" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="max" android:layout_marginRight="20dp" android:id="@+id/item_max" android:layout_above="@+id/hor_lv_main" android:layout_alignParentEnd="true"/> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="wea" android:id="@+id/item_wea" android:textSize="20dp" android:layout_alignBottom="@+id/item_today" android:layout_centerHorizontal="true" /></RelativeLayout>
就是一个很简单的界面,因为json数据里面没有提供晴雨天bitmap的url所以我就直接用textview代替啦,效果图是这样的:
好啦,下一步肯定是适配器和数据源的java啦,不多说直接上代码。
package com.example.howard.weather;import java.util.List;/** * Created by Howard on 6/13/16. */public class WeatherBean { /** * city : {"aqi":"31","pm10":"24","pm25":"7"} */ private AqiBean aqi; /** * city : 江浦 * cnty : 中国 * id : CN101190106 * lat : 32.027000 * lon : 118.520000 * update : {"loc":"2016-06-20 00:51","utc":"2016-06-19 16:51"} */ private BasicBean basic; /** * cond : {"code":"300","txt":"阵雨"} * fl : 27 * hum : 97 * pcpn : 0 * pres : 1006 * tmp : 23 * vis : 10 * wind : {"deg":"260","dir":"西北风","sc":"3-4","spd":"16"} */ private NowBean now; /** * aqi : {"city":{"aqi":"31","pm10":"24","pm25":"7"}} * basic : {"city":"江浦","cnty":"中国","id":"CN101190106","lat":"32.027000","lon":"118.520000","update":{"loc":"2016-06-20 00:51","utc":"2016-06-19 16:51"}} * daily_forecast : [{"astro":{"sr":"05:00","ss":"19:15"},"cond":{"code_d":"307","code_n":"302","txt_d":"大雨","txt_n":"雷阵雨"},"date":"2016-06-20","hum":"88","pcpn":"10.0","pop":"93","pres":"1003","tmp":{"max":"29","min":"25"},"vis":"9","wind":{"deg":"208","dir":"西南风","sc":"3-4","spd":"13"}},{"astro":{"sr":"05:00","ss":"19:15"},"cond":{"code_d":"302","code_n":"302","txt_d":"雷阵雨","txt_n":"雷阵雨"},"date":"2016-06-21","hum":"79","pcpn":"29.8","pop":"84","pres":"1001","tmp":{"max":"31","min":"26"},"vis":"10","wind":{"deg":"220","dir":"南风","sc":"3-4","spd":"12"}},{"astro":{"sr":"05:00","ss":"19:15"},"cond":{"code_d":"302","code_n":"101","txt_d":"雷阵雨","txt_n":"多云"},"date":"2016-06-22","hum":"61","pcpn":"8.3","pop":"79","pres":"1003","tmp":{"max":"31","min":"27"},"vis":"10","wind":{"deg":"246","dir":"西风","sc":"3-4","spd":"14"}},{"astro":{"sr":"05:00","ss":"19:15"},"cond":{"code_d":"101","code_n":"101","txt_d":"多云","txt_n":"多云"},"date":"2016-06-23","hum":"81","pcpn":"38.8","pop":"71","pres":"1001","tmp":{"max":"32","min":"27"},"vis":"7","wind":{"deg":"235","dir":"南风","sc":"3-4","spd":"10"}},{"astro":{"sr":"05:01","ss":"19:15"},"cond":{"code_d":"101","code_n":"101","txt_d":"多云","txt_n":"多云"},"date":"2016-06-24","hum":"55","pcpn":"4.2","pop":"61","pres":"1001","tmp":{"max":"33","min":"25"},"vis":"10","wind":{"deg":"255","dir":"西风","sc":"3-4","spd":"12"}},{"astro":{"sr":"05:01","ss":"19:15"},"cond":{"code_d":"302","code_n":"302","txt_d":"雷阵雨","txt_n":"雷阵雨"},"date":"2016-06-25","hum":"65","pcpn":"7.5","pop":"51","pres":"1006","tmp":{"max":"30","min":"24"},"vis":"7","wind":{"deg":"137","dir":"东风","sc":"3-4","spd":"12"}},{"astro":{"sr":"05:02","ss":"19:16"},"cond":{"code_d":"309","code_n":"301","txt_d":"毛毛雨/细雨","txt_n":"强阵雨"},"date":"2016-06-26","hum":"87","pcpn":"15.5","pop":"45","pres":"1008","tmp":{"max":"27","min":"23"},"vis":"2","wind":{"deg":"157","dir":"东南风","sc":"微风","spd":"4"}}] * hourly_forecast : [{"date":"2016-06-20 01:00","hum":"90","pop":"7","pres":"1005","tmp":"25","wind":{"deg":"178","dir":"南风","sc":"微风","spd":"9"}},{"date":"2016-06-20 04:00","hum":"92","pop":"15","pres":"1005","tmp":"24","wind":{"deg":"175","dir":"南风","sc":"微风","spd":"9"}},{"date":"2016-06-20 07:00","hum":"84","pop":"48","pres":"1005","tmp":"25","wind":{"deg":"191","dir":"西南风","sc":"微风","spd":"13"}},{"date":"2016-06-20 10:00","hum":"79","pop":"83","pres":"1005","tmp":"27","wind":{"deg":"208","dir":"西南风","sc":"3-4","spd":"18"}},{"date":"2016-06-20 13:00","hum":"85","pop":"92","pres":"1004","tmp":"29","wind":{"deg":"209","dir":"西南风","sc":"3-4","spd":"19"}},{"date":"2016-06-20 16:00","hum":"90","pop":"91","pres":"1003","tmp":"30","wind":{"deg":"195","dir":"西南风","sc":"微风","spd":"13"}},{"date":"2016-06-20 19:00","hum":"91","pop":"90","pres":"1003","tmp":"28","wind":{"deg":"201","dir":"西南风","sc":"微风","spd":"12"}},{"date":"2016-06-20 22:00","hum":"94","pop":"85","pres":"1004","tmp":"26","wind":{"deg":"186","dir":"南风","sc":"微风","spd":"12"}}] * now : {"cond":{"code":"300","txt":"阵雨"},"fl":"27","hum":"97","pcpn":"0","pres":"1006","tmp":"23","vis":"10","wind":{"deg":"260","dir":"西北风","sc":"3-4","spd":"16"}} * status : ok * suggestion : {"comf":{"brf":"较舒适","txt":"白天有雨,从而使空气湿度加大,会使人们感觉有点儿闷热,但早晚的天气很凉爽、舒适。"},"cw":{"brf":"不宜","txt":"不宜洗车,未来24小时内有雨,如果在此期间洗车,雨水和路上的泥水可能会再次弄脏您的爱车。"},"drsg":{"brf":"热","txt":"天气热,建议着短裙、短裤、短薄外套、T恤等夏季服装。"},"flu":{"brf":"少发","txt":"各项气象条件适宜,无明显降温过程,发生感冒机率较低。"},"sport":{"brf":"较不宜","txt":"有较强降水,建议您选择在室内进行健身休闲运动。"},"trav":{"brf":"较不宜","txt":"温度适宜,风稍大,同时有有较强降水,会给出行产生很多麻烦,建议好还是多选择在室内活动!"},"uv":{"brf":"弱","txt":"紫外线强度较弱,建议出门前涂擦SPF在12-15之间、PA+的防晒护肤品。"}} */ private String status; /** * comf : {"brf":"较舒适","txt":"白天有雨,从而使空气湿度加大,会使人们感觉有点儿闷热,但早晚的天气很凉爽、舒适。"} * cw : {"brf":"不宜","txt":"不宜洗车,未来24小时内有雨,如果在此期间洗车,雨水和路上的泥水可能会再次弄脏您的爱车。"} * drsg : {"brf":"热","txt":"天气热,建议着短裙、短裤、短薄外套、T恤等夏季服装。"} * flu : {"brf":"少发","txt":"各项气象条件适宜,无明显降温过程,发生感冒机率较低。"} * sport : {"brf":"较不宜","txt":"有较强降水,建议您选择在室内进行健身休闲运动。"} * trav : {"brf":"较不宜","txt":"温度适宜,风稍大,同时有有较强降水,会给出行产生很多麻烦,建议好还是多选择在室内活动!"} * uv : {"brf":"弱","txt":"紫外线强度较弱,建议出门前涂擦SPF在12-15之间、PA+的防晒护肤品。"} */ private SuggestionBean suggestion; /** * astro : {"sr":"05:00","ss":"19:15"} * cond : {"code_d":"307","code_n":"302","txt_d":"大雨","txt_n":"雷阵雨"} * date : 2016-06-20 * hum : 88 * pcpn : 10.0 * pop : 93 * pres : 1003 * tmp : {"max":"29","min":"25"} * vis : 9 * wind : {"deg":"208","dir":"西南风","sc":"3-4","spd":"13"} */ private List<DailyForecastBean> daily_forecast; /** * date : 2016-06-20 01:00 * hum : 90 * pop : 7 * pres : 1005 * tmp : 25 * wind : {"deg":"178","dir":"南风","sc":"微风","spd":"9"} */ private List<HourlyForecastBean> hourly_forecast; public AqiBean getAqi() { return aqi; } public void setAqi(AqiBean aqi) { this.aqi = aqi; } public BasicBean getBasic() { return basic; } public void setBasic(BasicBean basic) { this.basic = basic; } public NowBean getNow() { return now; } public void setNow(NowBean now) { this.now = now; } public String getStatus() { return status; } public void setStatus(String status) { this.status = status; } public SuggestionBean getSuggestion() { return suggestion; } public void setSuggestion(SuggestionBean suggestion) { this.suggestion = suggestion; } public List<DailyForecastBean> getDaily_forecast() { return daily_forecast; } public void setDaily_forecast(List<DailyForecastBean> daily_forecast) { this.daily_forecast = daily_forecast; } public List<HourlyForecastBean> getHourly_forecast() { return hourly_forecast; } public void setHourly_forecast(List<HourlyForecastBean> hourly_forecast) { this.hourly_forecast = hourly_forecast; } public static class AqiBean { /** * aqi : 31 * pm10 : 24 * pm25 : 7 */ private CityBean city; public CityBean getCity() { return city; } public void setCity(CityBean city) { this.city = city; } public static class CityBean { private String aqi; private String pm10; private String pm25; public String getAqi() { return aqi; } public void setAqi(String aqi) { this.aqi = aqi; } public String getPm10() { return pm10; } public void setPm10(String pm10) { this.pm10 = pm10; } public String getPm25() { return pm25; } public void setPm25(String pm25) { this.pm25 = pm25; } } } public static class BasicBean { private String city; private String cnty; private String id; private String lat; private String lon; /** * loc : 2016-06-20 00:51 * utc : 2016-06-19 16:51 */ private UpdateBean update; public String getCity() { return city; } public void setCity(String city) { this.city = city; } public String getCnty() { return cnty; } public void setCnty(String cnty) { this.cnty = cnty; } public String getId() { return id; } public void setId(String id) { this.id = id; } public String getLat() { return lat; } public void setLat(String lat) { this.lat = lat; } public String getLon() { return lon; } public void setLon(String lon) { this.lon = lon; } public UpdateBean getUpdate() { return update; } public void setUpdate(UpdateBean update) { this.update = update; } public static class UpdateBean { private String loc; private String utc; public String getLoc() { return loc; } public void setLoc(String loc) { this.loc = loc; } public String getUtc() { return utc; } public void setUtc(String utc) { this.utc = utc; } } } public static class NowBean { /** * code : 300 * txt : 阵雨 */ private CondBean cond; private String fl; private String hum; private String pcpn; private String pres; private String tmp; private String vis; /** * deg : 260 * dir : 西北风 * sc : 3-4 * spd : 16 */ private WindBean wind; public CondBean getCond() { return cond; } public void setCond(CondBean cond) { this.cond = cond; } public String getFl() { return fl; } public void setFl(String fl) { this.fl = fl; } public String getHum() { return hum; } public void setHum(String hum) { this.hum = hum; } public String getPcpn() { return pcpn; } public void setPcpn(String pcpn) { this.pcpn = pcpn; } public String getPres() { return pres; } public void setPres(String pres) { this.pres = pres; } public String getTmp() { return tmp; } public void setTmp(String tmp) { this.tmp = tmp; } public String getVis() { return vis; } public void setVis(String vis) { this.vis = vis; } public WindBean getWind() { return wind; } public void setWind(WindBean wind) { this.wind = wind; } public static class CondBean { private String code; private String txt; public String getCode() { return code; } public void setCode(String code) { this.code = code; } public String getTxt() { return txt; } public void setTxt(String txt) { this.txt = txt; } } public static class WindBean { private String deg; private String dir; private String sc; private String spd; public String getDeg() { return deg; } public void setDeg(String deg) { this.deg = deg; } public String getDir() { return dir; } public void setDir(String dir) { this.dir = dir; } public String getSc() { return sc; } public void setSc(String sc) { this.sc = sc; } public String getSpd() { return spd; } public void setSpd(String spd) { this.spd = spd; } } } public static class SuggestionBean { /** * brf : 较舒适 * txt : 白天有雨,从而使空气湿度加大,会使人们感觉有点儿闷热,但早晚的天气很凉爽、舒适。 */ private ComfBean comf; /** * brf : 不宜 * txt : 不宜洗车,未来24小时内有雨,如果在此期间洗车,雨水和路上的泥水可能会再次弄脏您的爱车。 */ private CwBean cw; /** * brf : 热 * txt : 天气热,建议着短裙、短裤、短薄外套、T恤等夏季服装。 */ private DrsgBean drsg; /** * brf : 少发 * txt : 各项气象条件适宜,无明显降温过程,发生感冒机率较低。 */ private FluBean flu; /** * brf : 较不宜 * txt : 有较强降水,建议您选择在室内进行健身休闲运动。 */ private SportBean sport; /** * brf : 较不宜 * txt : 温度适宜,风稍大,同时有有较强降水,会给出行产生很多麻烦,建议好还是多选择在室内活动! */ private TravBean trav; /** * brf : 弱 * txt : 紫外线强度较弱,建议出门前涂擦SPF在12-15之间、PA+的防晒护肤品。 */ private UvBean uv; public ComfBean getComf() { return comf; } public void setComf(ComfBean comf) { this.comf = comf; } public CwBean getCw() { return cw; } public void setCw(CwBean cw) { this.cw = cw; } public DrsgBean getDrsg() { return drsg; } public void setDrsg(DrsgBean drsg) { this.drsg = drsg; } public FluBean getFlu() { return flu; } public void setFlu(FluBean flu) { this.flu = flu; } public SportBean getSport() { return sport; } public void setSport(SportBean sport) { this.sport = sport; } public TravBean getTrav() { return trav; } public void setTrav(TravBean trav) { this.trav = trav; } public UvBean getUv() { return uv; } public void setUv(UvBean uv) { this.uv = uv; } public static class ComfBean { private String brf; private String txt; public String getBrf() { return brf; } public void setBrf(String brf) { this.brf = brf; } public String getTxt() { return txt; } public void setTxt(String txt) { this.txt = txt; } } public static class CwBean { private String brf; private String txt; public String getBrf() { return brf; } public void setBrf(String brf) { this.brf = brf; } public String getTxt() { return txt; } public void setTxt(String txt) { this.txt = txt; } } public static class DrsgBean { private String brf; private String txt; public String getBrf() { return brf; } public void setBrf(String brf) { this.brf = brf; } public String getTxt() { return txt; } public void setTxt(String txt) { this.txt = txt; } } public static class FluBean { private String brf; private String txt; public String getBrf() { return brf; } public void setBrf(String brf) { this.brf = brf; } public String getTxt() { return txt; } public void setTxt(String txt) { this.txt = txt; } } public static class SportBean { private String brf; private String txt; public String getBrf() { return brf; } public void setBrf(String brf) { this.brf = brf; } public String getTxt() { return txt; } public void setTxt(String txt) { this.txt = txt; } } public static class TravBean { private String brf; private String txt; public String getBrf() { return brf; } public void setBrf(String brf) { this.brf = brf; } public String getTxt() { return txt; } public void setTxt(String txt) { this.txt = txt; } } public static class UvBean { private String brf; private String txt; public String getBrf() { return brf; } public void setBrf(String brf) { this.brf = brf; } public String getTxt() { return txt; } public void setTxt(String txt) { this.txt = txt; } } } public static class DailyForecastBean { /** * sr : 05:00 * ss : 19:15 */ private AstroBean astro; /** * code_d : 307 * code_n : 302 * txt_d : 大雨 * txt_n : 雷阵雨 */ private CondBean cond; private String date; private String hum; private String pcpn; private String pop; private String pres; /** * max : 29 * min : 25 */ private TmpBean tmp; private String vis; /** * deg : 208 * dir : 西南风 * sc : 3-4 * spd : 13 */ private WindBean wind; public AstroBean getAstro() { return astro; } public void setAstro(AstroBean astro) { this.astro = astro; } public CondBean getCond() { return cond; } public void setCond(CondBean cond) { this.cond = cond; } public String getDate() { return date; } public void setDate(String date) { this.date = date; } public String getHum() { return hum; } public void setHum(String hum) { this.hum = hum; } public String getPcpn() { return pcpn; } public void setPcpn(String pcpn) { this.pcpn = pcpn; } public String getPop() { return pop; } public void setPop(String pop) { this.pop = pop; } public String getPres() { return pres; } public void setPres(String pres) { this.pres = pres; } public TmpBean getTmp() { return tmp; } public void setTmp(TmpBean tmp) { this.tmp = tmp; } public String getVis() { return vis; } public void setVis(String vis) { this.vis = vis; } public WindBean getWind() { return wind; } public void setWind(WindBean wind) { this.wind = wind; } public static class AstroBean { private String sr; private String ss; public String getSr() { return sr; } public void setSr(String sr) { this.sr = sr; } public String getSs() { return ss; } public void setSs(String ss) { this.ss = ss; } } public static class CondBean { private String code_d; private String code_n; private String txt_d; private String txt_n; public String getCode_d() { return code_d; } public void setCode_d(String code_d) { this.code_d = code_d; } public String getCode_n() { return code_n; } public void setCode_n(String code_n) { this.code_n = code_n; } public String getTxt_d() { return txt_d; } public void setTxt_d(String txt_d) { this.txt_d = txt_d; } public String getTxt_n() { return txt_n; } public void setTxt_n(String txt_n) { this.txt_n = txt_n; } } public static class TmpBean { private String max; private String min; public String getMax() { return max; } public void setMax(String max) { this.max = max; } public String getMin() { return min; } public void setMin(String min) { this.min = min; } } public static class WindBean { private String deg; private String dir; private String sc; private String spd; public String getDeg() { return deg; } public void setDeg(String deg) { this.deg = deg; } public String getDir() { return dir; } public void setDir(String dir) { this.dir = dir; } public String getSc() { return sc; } public void setSc(String sc) { this.sc = sc; } public String getSpd() { return spd; } public void setSpd(String spd) { this.spd = spd; } } } public static class HourlyForecastBean { private String date; private String hum; private String pop; private String pres; private String tmp; /** * deg : 178 * dir : 南风 * sc : 微风 * spd : 9 */ private WindBean wind; public String getDate() { return date; } public void setDate(String date) { this.date = date; } public String getHum() { return hum; } public void setHum(String hum) { this.hum = hum; } public String getPop() { return pop; } public void setPop(String pop) { this.pop = pop; } public String getPres() { return pres; } public void setPres(String pres) { this.pres = pres; } public String getTmp() { return tmp; } public void setTmp(String tmp) { this.tmp = tmp; } public WindBean getWind() { return wind; } public void setWind(WindBean wind) { this.wind = wind; } public static class WindBean { private String deg; private String dir; private String sc; private String spd; public String getDeg() { return deg; } public void setDeg(String deg) { this.deg = deg; } public String getDir() { return dir; } public void setDir(String dir) { this.dir = dir; } public String getSc() { return sc; } public void setSc(String sc) { this.sc = sc; } public String getSpd() { return spd; } public void setSpd(String spd) { this.spd = spd; } } }}
WeatherBean的类是用git给的gson框架写的,不会的自行Google吧,个人觉得解析数据还是很有必要的。这里我写json类的时候做了一个处理,就是把He Service 3.0:去掉了,保证解析出来是一个jsonObject形式,不然会很麻烦。下面是适配器。这里需要的是获取每日的天气,所以数据源应该是daily_forecasBean.因为没有图片,让我省事了很多,imageloader也不需要了。adapter代码:
package com.example.howard.weather;import com.example.howard.weather.WeatherBean.DailyForecastBean;import java.util.ArrayList;import java.util.List;import android.content.Context;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.BaseAdapter;import android.widget.TextView;public class MainItemAdapter extends BaseAdapter { private List<DailyForecastBean> objects; private LayoutInflater layoutInflater; public MainItemAdapter(Context context,List<DailyForecastBean> mRes) { this.layoutInflater = LayoutInflater.from(context); objects = mRes; } @Override public int getCount() { return objects.size(); } @Override public DailyForecastBean getItem(int position) { return objects.get(position); } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { if (convertView == null) { convertView = layoutInflater.inflate(R.layout.main_item, null); convertView.setTag(new ViewHolder(convertView)); } initializeViews((DailyForecastBean) getItem(position), (ViewHolder) convertView.getTag()); return convertView; } private void initializeViews(DailyForecastBean object, ViewHolder holder) { holder.itemToday.setText(object.getDate()); holder.itemWea.setText(object.getCond().getTxt_d()); holder.itemMax.setText(object.getTmp().getMax()); holder.itemMin.setText(object.getTmp().getMin()); } protected class ViewHolder { private TextView itemToday; private TextView itemMin; private TextView itemMax; private TextView itemWea; public ViewHolder(View view) { itemToday = (TextView) view.findViewById(R.id.item_today); itemMin = (TextView) view.findViewById(R.id.item_min); itemMax = (TextView) view.findViewById(R.id.item_max); itemWea = (TextView) view.findViewById(R.id.item_wea); } }}
下面写个httpUtil来解析json数据吧。就是一些简单的io流操作,大神直接略过吧。。。
package com.example.howard.weather;import java.io.ByteArrayOutputStream;import java.io.IOException;import java.io.InputStream;import java.net.HttpURLConnection;import java.net.URL;public class HttpUtils{ public HttpUtils() { } public static String getJsonContent(String url_path) { try { URL url = new URL(url_path); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.setConnectTimeout(3000); connection.setRequestMethod("GET"); connection.setDoInput(true); int code = connection.getResponseCode(); if (code == 200) { return changeInputStream(connection.getInputStream()); } } catch (Exception e) { } return ""; } private static String changeInputStream(InputStream inputStream) { // TODO Auto-generated method stub String jsonString = ""; ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); int len = 0; byte[] data = new byte[1024]; try { while ((len = inputStream.read(data)) != -1) { outputStream.write(data, 0, len); } jsonString = new String(outputStream.toByteArray()); outputStream.close(); } catch (IOException e) { e.printStackTrace(); } return jsonString; }}
就是一个很简单是工具包,好啦。现在我们来整理一下写好的java代码:HorizontalListView(大神的框架,虽然还不知道有没有用。。),HttpUtils,MainActivity,MainItemAdapter,WeatherBean.嗯,下面开始写主类吧。主类要实现的功能就是解析url并把数据封装到数据源里接着配置好adapter,貌似也不是什么难事。那么就接着撸吧。。
MainActivity.java代码附上:
package com.example.howard.weather;import android.app.Activity;import android.os.AsyncTask;import android.os.Bundle;import android.widget.HorizontalScrollView;import android.widget.ListView;import android.widget.TextView;import com.google.gson.Gson;import java.util.ArrayList;import java.util.List;import butterknife.Bind;import butterknife.ButterKnife;public class MainActivity extends Activity { @Bind(R.id.main_city) TextView mainCity; @Bind(R.id.main_weather) TextView mainWeather; @Bind(R.id.main_tmp) TextView mainTmp; @Bind(R.id.hor_lv_main) HorizontalListView horLvMain; @Bind(R.id.main_today) TextView mainToday; @Bind(R.id.textView2) TextView textView2; @Bind(R.id.main_min) TextView mainMin; @Bind(R.id.main_max) TextView mainMax; @Bind(R.id.lv_main) ListView lvMain; private List<WeatherBean.DailyForecastBean>mRes; private WeatherBean weatherBean; private WeatherBean.BasicBean basicBean; private MainItemAdapter mainItemAdapter; private static String mUrl = "https://api.heweather.com/x3/weather?cityid=CN101190106&key=56f9857126d3463abcd0f88c06700951"; private String json; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mRes = new ArrayList<>(); ButterKnife.bind(this); MyAsyncTask task = new MyAsyncTask(); task.execute(mUrl); } public class MyAsyncTask extends AsyncTask<String,Void,List<WeatherBean.DailyForecastBean>>{ @Override protected void onPostExecute(List<WeatherBean.DailyForecastBean> dailyForecastBeen) { mainCity.setText(weatherBean.getBasic().getCity()); mainMax.setText(weatherBean.getDaily_forecast().get(0).getTmp().getMax()); mainMin.setText(weatherBean.getDaily_forecast().get(0).getTmp().getMin()); mainWeather.setText(weatherBean.getDaily_forecast().get(0).getCond().getTxt_d()); mainToday.setText(weatherBean.getDaily_forecast().get(0).getDate()); mRes = dailyForecastBeen; mainItemAdapter = new MainItemAdapter(MainActivity.this,mRes); lvMain.setAdapter(mainItemAdapter); } @Override protected List<WeatherBean.DailyForecastBean> doInBackground(String... params) { json = HttpUtils.getJsonContent(params[0]); json = format(json); Gson gson = new Gson(); weatherBean = gson.fromJson(json,WeatherBean.class); return weatherBean.getDaily_forecast(); } } public String format(String msg){ msg = msg.substring(0,msg.length()-2); String d1 = msg.substring(31); return d1; }}
代码也不是很多,由于温度daily里面获取不到,应该在实时的天气中,这个数据就先放着吧,等以后解析hourly_weather的时候在补上,大家可以看到,这里写了个format方法就是对util获取下来的json数据进行格式化,保证和我们的类一致,这里就不多说啦,到现在为止主要listview和主界面就完成了。
看一下效果图吧:
到此,大家看出什么问题了吗。。是的,第一个item是今天的数据,我们已经让他在上面显示过了,这里就不需要了,所以我们需要对adapter进行修改:
public MainItemAdapter(Context context,List<DailyForecastBean> mRes) { this.layoutInflater = LayoutInflater.from(context); objects = mRes; objects.remove(0); }
很简单啦,把第一条删除就行了,那么现在来看一下效果吧:
这样就没错啦,好啦,到现在为止一个简单的demo就做好啦,别忘了加入INTERNET权限哦。一些bug和水平listview我会在后面几天抽时间研究啦,希望大家继续关注我,嘿嘿,我是小宇,安卓小菜鸟。
哦对了,忘了说了,这里用到了两个工具包,也是android studio自带的plugins,butterknife和Gson,git上有jar包下载,用的时候放在lib下在导到library就行了,个人还是觉得很好用的,好啦,今天就到这里啦。
大家晚安。
- 简单天气获取demo的制作(一)
- Hadoop Demo(二)【获取天气相关的统计信息】
- unity3d制作小地图(MiniMap)的简单Demo
- 通过jsonp跨域问题制作简单的天气
- [一天一项目]获取当前天气——获取某个地区当前的天气情况。
- 天气预报的简单制作(一)
- 学习OGRE制作简单人物行走demo(一)
- ZendStudio php WebService制作一:简单WebService Demo
- [BlackBerry代码] 简单的访问sina天气频道获取天气信息的例子
- 获取城市天气信息的简单例子-----WebService
- 获取每小时的天气
- 简单的天气查询
- 中国天气网城市代码(JSON)获取实现(一)
- WCF学习笔记(一)创建一个简单的Demo
- 全文检索技术 lucene(一) 一个简单的Demo
- Replugin Demo的简单使用与分析(一)
- 如何简单制作简单的个人主页(一)
- Websocket(一)简单的demo实现
- 【操作系统】UltraEdit 上FTP的配置
- oracle存储过程之游标
- Notes:De-anonymizing Programmers via Code Stylometry
- 设计模式-策略模式
- c++:最简单的动态分配
- 简单天气获取demo的制作(一)
- 如何高效的学习高等数学
- Intellij IDEA社区版打包Maven项目成war包,并部署到tomcat上
- cvGetCaptureProperty 获取视频流的各种属性 用法
- [Android]AutoCompleteTextView自动补全文本框
- HDOJ 2002 计算球体积
- 用户和组账户管理
- 图的表示法
- csdn自定义博客栏目