Android 編程之天氣預報下來重新整理資料及城市容器配置--3

來源:互聯網
上載者:User

標籤:des   android   style   blog   http   color   io   os   ar   

前面已經把活動和服務講了講,要注意的是服務的用法,我們在這裡是 extends IntentService implements LocationListener ,下面看下 IntentService


IntentService是一個通過Context.startService(Intent)啟動可以處理非同步請求的Service,使用時你只需要繼承IntentService和重寫其中的onHandleIntent(Intent)方法接收一個Intent對象,在適當的時候會停止自己(一般在工作完成的時候). 所有的請求的處理都在一個背景工作執行緒中完成,它們會交替執行(但不會阻塞主線程的執行),一次只能執行一個請求,訊息佇列模式    這是一個基於訊息的服務,每次啟動該服務並不是馬上處理你的工作,而是首先會建立對應的Looper,Handler並且在MessageQueue中添加的附帶客戶Intent的Message對象,當Looper發現有Message的時候接著得到Intent對象通過在onHandleIntent((Intent)msg.obj)中調用你的處理常式.處理完後即會停止自己的服務.意思是Intent的生命週期跟你的處理的任務是一致的.所以這個類用下載任務中非常好,下載任務結束後服務自身就會結束退出.IntentService使用隊列的方式將請求的Intent排入佇列,然後開啟一個worker thread(線程)來處理隊列中的Intent,對於非同步startService請求,IntentService會處理完成一個之後再處理第二個,每一個請求都會在一個單獨的worker thread中處理,不會阻塞應用程式的主線程,這裡就給我們提供了一個思路,如果有耗時的操作與其在Service裡面開啟新線程還不如使用IntentService來處理耗時操作

今天說說下來重新整理和城市容器管理,很多關於 ListView 的內容通常會用到下來重新整理和上拉載入更多操作,就比如QQ手機端的訊息列表,下拉可以重新整理訊息列表一樣,城市容器呢,我們這裡暫時只是寫了一個ArrayList自己定義了一組已經存在的城市資料,後期有需要可以考慮用 xml 存取資料,包括一些天氣資訊可以存起來,就是在網路狀況不好的情況下,讓我們的APP可以用本機資料,介面才不會顯得那麼空洞,XML存取,SharedPreferences適合一些賬戶資訊或其他小資料存取
城市容器、添加城市Dialog:
package com.newer.myweather;/** *城市容器,城市添加Dialog *@author Engineer-Jsp *@date 2014.10.27 * */import java.util.ArrayList;import android.app.Activity;import android.app.AlertDialog;import android.app.AlertDialog.Builder;import android.content.DialogInterface;import android.content.DialogInterface.OnClickListener;import android.os.Bundle;import android.view.ActionMode;import android.view.Menu;import android.view.MenuItem;import android.view.View;import android.widget.AbsListView.MultiChoiceModeListener;import android.widget.ArrayAdapter;import android.widget.EditText;import android.widget.ListView;public class LocationActivity extends Activity implementsMultiChoiceModeListener {private ListView locationListView;private ArrayAdapter<String> adapter;private EditText editText;private long mposition;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.location);MainActivity.locations.clear();MainActivity.locations.add("長  沙");MainActivity.locations.add("深  圳");MainActivity.locations.add("嶽  陽");MainActivity.locations.add("常  德");locationListView = (ListView) findViewById(R.id.locations);adapter = new ArrayAdapter<String>(this,R.layout.city_item,R.id.city_item_content, MainActivity.locations);locationListView.setAdapter(adapter);adapter.notifyDataSetChanged();locationListView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);locationListView.setMultiChoiceModeListener(this);}@Overridepublic boolean onCreateOptionsMenu(Menu menu) {getMenuInflater().inflate(R.menu.location, menu);return super.onCreateOptionsMenu(menu);}@Overridepublic boolean onOptionsItemSelected(MenuItem item) {if (item.getItemId() == R.id.ic_action_add) {showAddDialog();}return super.onOptionsItemSelected(item);}private void showAddDialog() {editText = new EditText(this);editText.setHint("請輸入地址");editText.setSingleLine(true);AlertDialog.Builder builder = new Builder(this).setTitle("添加地址").setView(editText).setNegativeButton("取消", null).setPositiveButton("確定", new OnClickListener() {@Overridepublic void onClick(DialogInterface dialog, int which) {String input = editText.getText().toString().trim();MainActivity.locations.add(input);}});builder.show();}@Overridepublic boolean onCreateActionMode(ActionMode mode, Menu menu) {getMenuInflater().inflate(R.menu.location, menu);mode.setTitle("選擇");return true;}@Overridepublic boolean onPrepareActionMode(ActionMode mode, Menu menu) {return false;}@Overridepublic boolean onActionItemClicked(ActionMode mode, MenuItem item) {if (item.getItemId() == R.id.ic_action_delete) {///MainActivity.locations.remove(mposition);}return false;}@Overridepublic void onDestroyActionMode(ActionMode mode) {}@Overridepublic void onItemCheckedStateChanged(ActionMode mode, int position,long id, boolean checked) {mposition = id;int count = locationListView.getCheckedItemCount();mode.setSubtitle(count + "項");}}

下拉重新整理:
package com.newer.myweather.weight;/** * 下拉重新整理資料 * @author Engineer-Jsp * @date 2014.10.27 * */import java.util.Date;import com.newer.myweather.R;import android.content.Context;import android.util.AttributeSet;import android.view.LayoutInflater;import android.view.MotionEvent;import android.view.View;import android.view.ViewGroup;import android.view.animation.Animation;import android.view.animation.LinearInterpolator;import android.view.animation.RotateAnimation;import android.widget.AbsListView;import android.widget.ImageView;import android.widget.ListAdapter;import android.widget.ListView;import android.widget.AbsListView.OnScrollListener;import android.widget.ProgressBar;import android.widget.TextView;public class MyListView extends ListView implements OnScrollListener {private View headView;private ImageView arror;private ProgressBar progressBar;private TextView title;private TextView last_update;private int headContentWidth;private int headContentHeight;private int firstVisableIndex;//在頁面中 第一個能夠看見item(listView)的位置private Animation animation;private Animation animation2;private float startY;//用來記錄headeVIew將要顯示時位置   在整個滑動中 只記錄一次private boolean isRecord = false; //用來記錄startY 是否已經記錄private float tempY;//動態Y軸座標private final static int PULL_TO_REFRESH = 0;//下拉重新整理private final static int RELEASE_TO_REFRESH = 1;//鬆開重新整理private final static int REFRESHING = 2;//正在重新整理private final static int DONE = 3;//重新整理完成private int state ;//當前下拉重新整理控制項的狀態private boolean isBack= false;//記錄是否從鬆開重新整理回到的下拉重新整理private OnRefreshListener refreshListener;//重新整理監聽器private final static int RATIO = 3;//實際拉動的距離 和  headview距離頁面頂端距離的比例// 300px100px;public MyListView(Context context) {super(context);init(context);}public MyListView(Context context, AttributeSet attrs) {super(context, attrs);init(context);}private void init(Context context) {//1:將header 與listView 合成//LayoutInflater inflater = LayoutInflater.from(context);//inflater.inflate(resource, root, attachToRoot);headView = View.inflate(context, R.layout.header, null);arror = (ImageView) headView.findViewById(R.id.arror);progressBar = (ProgressBar) headView.findViewById(R.id.progressBar);title = (TextView) headView.findViewById(R.id.title);last_update = (TextView) headView.findViewById(R.id.last_update);arror.setMinimumWidth(70);arror.setMinimumHeight(50);//測量出header控制項的尺寸measureView(headView);//得到haderView測量後的尺寸headContentWidth = headView.getMeasuredWidth();headContentHeight = headView.getMeasuredHeight();//指定headView 位置headView.setPadding(0, -1 * headContentHeight, 0, 0);//綁定addHeaderView(headView);//listView 添加OnScrollListenersetOnScrollListener(this);//建立箭頭使用的動畫//右→左animation = new RotateAnimation(0, -180, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);animation.setDuration(250);animation.setFillAfter(true);animation.setInterpolator(new LinearInterpolator());//修改動畫 運行效果/** * Interpolator 定義了動畫的變化速度,可以實現勻速、正加速、負加速、無規則變加速等;AccelerateDecelerateInterpolator,延遲減速,在動作執行到中間的時候才執行該特效。AccelerateInterpolator, 會使慢慢以(float)的參數降低速度。LinearInterpolator,平穩不變的DecelerateInterpolator,在中間加速,兩頭慢CycleInterpolator,曲線運動特效,要傳遞float型的參數。 * *///左→右animation2 = new RotateAnimation(-180, 0, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);animation2.setDuration(200);animation2.setFillAfter(true);animation2.setInterpolator(new LinearInterpolator());//修改動畫 運行效果}//測量出header控制項的尺寸private void measureView(View child) {//child <==> headViewViewGroup.LayoutParams lp = child.getLayoutParams();//初始化操作if(lp == null){lp = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);}//設定控制項尺寸int childWidth = ViewGroup.getChildMeasureSpec(0, 0, lp.width);int childHeight;if(lp.height > 0){//headView有自己的高度childHeight = MeasureSpec.makeMeasureSpec(lp.height, MeasureSpec.EXACTLY);} else {//headView沒有高度  指定為0childHeight = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);}//記錄測量後 控制項的尺寸child.measure(childWidth, childHeight);}@Overridepublic void onScroll(AbsListView arg0, int firstVisableItem, int arg2, int arg3) {// TODO Auto-generated method stub//firstVisableItem  在頁面中 第一個能夠看見item(listView)的位置firstVisableIndex = firstVisableItem;}@Overridepublic void onScrollStateChanged(AbsListView arg0, int arg1) {// TODO Auto-generated method stub}@Overridepublic boolean onTouchEvent(MotionEvent event) {switch (event.getAction()) {case MotionEvent.ACTION_DOWN://按下//如果當前第一個看見的item為0的位置 同時  startY沒有被記錄過, 這個時候記錄StartYif(firstVisableIndex == 0 && !isRecord){startY = event.getY();isRecord = true;//修正記錄StartY 點的狀態}break;case MotionEvent.ACTION_MOVE://移動tempY = event.getY();if(firstVisableIndex == 0 && !isRecord){startY = tempY;isRecord = true;}//在非正在滑動狀態時, listView的滑動效果if(state != REFRESHING){//下拉重新整理狀態if(state == PULL_TO_REFRESH){setSelection(0);if((tempY - startY) <= 0){//下拉重新整理狀態 向上推了 把整個headView全部隱藏  回到了 重新整理完成state = DONE;//headView控制項狀態變化changeHeadViewOfState();} else if((tempY - startY) /RATIO > headContentHeight){//下拉重新整理狀態 向下拉了   把整個headView全部顯示  來到了 鬆開重新整理state = RELEASE_TO_REFRESH;//headView控制項狀態變化changeHeadViewOfState();}}//鬆開重新整理狀態if(state == RELEASE_TO_REFRESH){setSelection(0);if((tempY - startY) <= 0){//下拉重新整理狀態 向上推了 把整個headView全部隱藏  回到了 重新整理完成state = DONE;//headView控制項狀態變化changeHeadViewOfState();} else if((tempY - startY) /RATIO < headContentHeight && (tempY - startY) > 0){//鬆開重新整理狀態 向上推了   把headView隱藏一部分 顯示一部分   來到了 下拉重新整理state = PULL_TO_REFRESH;isBack = true;//鬆開重新整理 -->下拉重新整理//headView控制項狀態變化changeHeadViewOfState();}}//重新整理完成狀態if(state == DONE){if((tempY - startY) > 0){//重新整理完成 下拉  進入了  下拉重新整理狀態state = PULL_TO_REFRESH;//headView控制項狀態變化changeHeadViewOfState();}}}//setPadding(int left, int top, int right, int bottom)headView.setPadding(0, (int) ((tempY-startY) /RATIO - headContentHeight), 0, 0);break;case MotionEvent.ACTION_UP://鬆手if(state == PULL_TO_REFRESH){//回到重新整理完成狀態state = DONE;changeHeadViewOfState();}if(state == RELEASE_TO_REFRESH){//進入正在重新整理狀態state = REFRESHING;changeHeadViewOfState();//資料重新整理onRefresh();}break;}invalidate();//listView重繪return true;//return super.onTouchEvent(event);}//headView控制項狀態變化private void changeHeadViewOfState(){switch (state) {case PULL_TO_REFRESH://下拉重新整理arror.setVisibility(View.VISIBLE);progressBar.setVisibility(View.GONE);title.setVisibility(View.VISIBLE);last_update.setVisibility(View.VISIBLE);title.setText("下拉重新整理");//指定動畫arror.clearAnimation();if(isBack){//鬆開重新整理 --> 下拉重新整理//左-->右  順指標arror.startAnimation(animation2);isBack = false;}break;case RELEASE_TO_REFRESH://鬆開重新整理arror.setVisibility(View.VISIBLE);progressBar.setVisibility(View.GONE);title.setVisibility(View.VISIBLE);last_update.setVisibility(View.VISIBLE);title.setText("鬆開重新整理");arror.clearAnimation();//右-->左  逆時針arror.startAnimation(animation);break;case REFRESHING://正在重新整理arror.setVisibility(View.GONE);progressBar.setVisibility(View.VISIBLE);title.setVisibility(View.VISIBLE);last_update.setVisibility(View.VISIBLE);title.setText("正在重新整理中...");//setPadding(int left, int top, int right, int bottom)headView.setPadding(0, 0, 0, 0);break;case DONE://重新整理完成arror.setVisibility(View.VISIBLE);progressBar.setVisibility(View.GONE);title.setVisibility(View.VISIBLE);last_update.setVisibility(View.VISIBLE);title.setText("下拉重新整理");headView.setPadding(0, -1 * headContentHeight, 0, 0);break;}}//重新整理資料private void onRefresh() {refreshListener.onRefresh();}//提供提供者public interface OnRefreshListener{abstract void onRefresh();}public void setOnRefreshListener(OnRefreshListener listener){refreshListener = listener;}//重新整理後 執行的操作    更新時間、更新headView的狀態public void onRefreshComplete() {//更新headView的狀態state = DONE;changeHeadViewOfState();//更新時間last_update.setText("更新於: " + new Date().toLocaleString());}@Overridepublic void setAdapter(ListAdapter adapter) {super.setAdapter(adapter);//更新時間last_update.setText("更新於: " + new Date().toLocaleString());}}

下拉重新整理:

鬆開重新整理中:

重新整理完成,更新資料:

重新整理資料以官方提供的資料為準,若官方無更新,列表內容跟沒重新整理之前一樣,因為資料來自官方提供

Android 編程之天氣預報下來重新整理資料及城市容器配置--3

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.