編輯:關於Android編程
本系列文章提供簡單Android應用開發實例方法,文章步驟如下所示:
1 獲取應用所需的數據源
數據源一般來源於互聯網、個人搜集或者其他方式
2 應用UI設計
每個應用軟件都需要有一個簡單的UI設計草圖,便於開發者更好的實現編碼
3 應用實現
實現完整的Android應用
特此說明:本系列文章的數據源均采用互聯網方式獲取,僅作為示例演示
提供各個高校歷屆的分數線錄取查詢功能,作為高考學子填寫志願的參考應用。最終效果圖:
1 從Assets中獲取到學校信息,學校存儲格式為:
1#10001#北京大學
1#10002#中國人民大學
1#10003#清華大學
1#10004#北京交通大學
其中1代表省份ID,10001代表學校ID,最後的為學校名稱
我們新建FileUtils類,提供獲取Assets下文件的方法:
public static List以上方法將文件中的數據按行加載到列表中,由於在保存數據源時保存為ASCII格式,所以此處采用gbk加載。loadFileContentForList(String filePath, Context ctx) throws IOException { InputStream is = ctx.getAssets().open(filePath); BufferedReader br = new BufferedReader(new InputStreamReader(is, gbk)); ArrayList results = new ArrayList (); String readLine = null; while((readLine = br.readLine()) != null) { results.add(readLine); } return results; }
2 從網絡中獲取高校查詢結果
采用Android自帶的HttpClient進行實現,我們首先封裝一個簡單的HttpUtils處理類,提供httpGet請求方法:
/** * 獲取指定URL請求的結果信息,以字符串方式返回請求內容 * @param url 請求地址 * @param param 請求所需參數 * @return */ public static String httpGet(String url, HashMap3 為了便於控件渲染數據,我們將所有數據均轉為SimpleAdapter可識別的格式ArrayListparam) { HttpParams httpParams = new BasicHttpParams(); HttpConnectionParams.setConnectionTimeout(httpParams, 5000); HttpConnectionParams.setSoTimeout(httpParams, 5000); HttpClient mHttpClient = new DefaultHttpClient(httpParams); String mUrl = url; if(param != null && param.size() > 0) { StringBuilder sb = new StringBuilder(); sb.append(url); sb.append(?); for(Entry m : param.entrySet()) { sb.append(m.getKey()); sb.append(=); sb.append(m.getValue()); sb.append(&); } mUrl = sb.substring(0, sb.length()-1); } HttpGet httpRequest = new HttpGet(mUrl); try { HttpResponse httpResponse = mHttpClient.execute(httpRequest); if (httpResponse.getStatusLine().getStatusCode() == HttpURLConnection.HTTP_OK) { String str = EntityUtils.toString(httpResponse.getEntity()); return str; } } catch (Exception e) { e.printStackTrace(); } finally { httpRequest.abort(); } return null; }
通過MUtils類提供各個數據的轉化:
loadSchool方法用於提供所有學校信息數據轉化,其中Map的key表示省份ID,value為學校列表
@SuppressLint(UseSparseArrays) public static HashMaploadResult方法用於將網絡獲取的查詢結果信息進行轉化,主要將返回的JSON格式進行處理>> loadSchool(Context ctx) { HashMap >> result = new HashMap >>(); try { List contents = FileUtils.loadFileContentForList(m/data, ctx); for(int i = 0, len = contents.size(); i < len; i++) { String[] item = contents.get(i).split(#); HashMap data = new HashMap (); data.put(id, item[1]); data.put(name, item[2]); ArrayList > itemList = result.get(Integer.parseInt(item[0])); if(itemList == null) { itemList = new ArrayList >(); result.put(Integer.parseInt(item[0]), itemList); } itemList.add(data); } } catch (IOException e) { e.printStackTrace(); } return result; }
public static ArrayList其中BASE_URL = http://kaoshi.edu.sina.com.cn/iframe/i_collegescore.php, batchMap從原有數據網站中獲取並初始化數據> loadResult(final String schoolId, final int type, final int prov2) throws Exception{ //從網絡獲取查詢結果,返回格式為JSON String netStr = HttpUtils.httpGet(BASE_URL, new HashMap (){{ put(_action, collegescore); put(num, 0); put(provid, prov2); put(wl, type); put(collegeid, schoolId); }}); if(netStr == null) { //異常直接返回null return null; } JSONArray resultArray = new JSONArray(netStr); ArrayList > result = new ArrayList >(); for(int i = 0, len = resultArray.length(); i < len; i++) { //依次處理每一條數據信息 JSONObject jobj = resultArray.getJSONObject(i); HashMap d = new HashMap (); int tempInt; d.put(year, jobj.getString(syear)); tempInt = jobj.optInt(plan, -1); d.put(plan, (tempInt <= 0 ? -- : + tempInt)); tempInt = jobj.optInt(score_min, -1); d.put(score_min, tempInt <= 0 ? -- : + tempInt); tempInt = jobj.optInt(score_avg, -1); d.put(score_avg, (tempInt <= 0 ? -- : + tempInt)); tempInt = jobj.optInt(score_td, -1); d.put(score_td, (tempInt <= 0 ? -- : + tempInt)); tempInt = jobj.optInt(score_max, -1); d.put(score_max, (tempInt <= 0 ? -- : + tempInt)); d.put(batch, batchMap.get(jobj.getString(batch))); d.put(batch_diff, jobj.getString(batch_diff)); result.add(d); } return result; } public static final HashMap batchMap = new HashMap (){{ put(00, 不詳); put(01, 本科提前批); put(11, 本科一批); put(12, 本科二批); put(13, 本科三批); put(123, 本科二、三批); put(21, 專科); }};
Activity中所有變量定義如下所示:
//依次為省份選擇ID,用戶所在地ID,學校序號,文理科類型 int prov1, prov2, school, type; ArrayList> resultData; //查詢錄取結果 HashMap >> datas; //保存省份下的學校信息 //依次為省份選擇彈窗、學校選擇彈窗和文理科選擇彈窗 PopupWindow provWindow, schoolWindow, typeWindow; TextView prov1Sel, schoolSel, typeSel, prov2Sel, tipView, resultTitleView; ListView provList, schoolList, resultList; LinearLayout resultLayout; Button queryButton; //依次為省份信息和文理科信息(從strings.xml中獲取) String[] provs, types;
/** * 顯示省份彈窗。type=0表示學校省份彈窗,=1表示用戶所在地省份彈窗 * @param type */ public void showProvWindow(final int type) { if (provWindow == null) { View v = LayoutInflater.from(this).inflate(R.layout.pop_list, null); provList = (ListView) v.findViewById(R.id.pop_list); provList.setAdapter(new ArrayAdapter文理科類型彈窗實現如下所示:(this, R.layout.pop_list_item, R.id.pop_list_item_name, provs)); provWindow = new PopupWindow(v, Utils.screenWidth, Utils.screenHeight / 2, true); } provList.setOnItemClickListener(new OnItemClickListener() { @Override public void onItemClick(AdapterView av, View arg1, int position, long arg3) { //ID為選擇序號+1 if (type == 0) { prov1 = position + 1; prov1Sel.setText(provs[position]); } else { prov2 = position + 1; prov2Sel.setText(provs[position]); } if (provWindow != null) { provWindow.dismiss(); } } }); if (type == 0 && prov1 > 0) { provList.setSelection(prov1 - 1); } else if (type == 1 && prov2 > 0) { provList.setSelection(prov2 - 1); } else { provList.setSelection(0); } provWindow.showAsDropDown(type == 0 ? prov1Sel : prov2Sel, 0, 0); provWindow.update(); }
public void showTypeWindow() { if (typeWindow == null) { View v = LayoutInflater.from(this).inflate(R.layout.pop_list, null); ListView tList = (ListView) v.findViewById(R.id.pop_list); tList.setAdapter(new ArrayAdapter學校下拉彈窗實現如下所示:(this, R.layout.pop_list_item, R.id.pop_list_item_name, types)); typeWindow = new PopupWindow(v, Utils.screenWidth / 2, Utils.screenHeight / 2, true); tList.setOnItemClickListener(new OnItemClickListener() { @Override public void onItemClick(AdapterView av, View arg1, int position, long arg3) { type = position; typeSel.setText(types[position]); if (typeWindow != null) { typeWindow.dismiss(); } } }); } typeWindow.showAsDropDown(typeSel, 0, 0); typeWindow.update(); }
public void showSchoolWindow() { if (prov1 <= 0) { Toast.makeText(this, 請先選擇省份!, Toast.LENGTH_SHORT).show(); return; } if (schoolWindow == null) { View v = LayoutInflater.from(this).inflate(R.layout.pop_list, null); schoolList = (ListView) v.findViewById(R.id.pop_list); schoolList.setOnItemClickListener(new OnItemClickListener() { @Override public void onItemClick(AdapterView av, View arg1, int position, long arg3) { school = position; schoolSel.setText((String) datas.get(prov1).get(school) .get(name)); if (schoolWindow != null) { schoolWindow.dismiss(); } } }); schoolWindow = new PopupWindow(v, Utils.screenWidth, Utils.screenHeight / 2, true); } //每次點擊都需要更新數據,防止省份改變 schoolList.setAdapter(new SimpleAdapter(this, datas.get(prov1), R.layout.pop_list_item, new String[] { name }, new int[] { R.id.pop_list_item_name })); schoolList.setSelection(school); schoolWindow.showAsDropDown(schoolSel, 0, 0); schoolWindow.update(); }因為Http請求不能在主線程實現,我們通過新開線程,通過Handler實現UI刷新,請求查詢並渲染結果如下所示:
@Override public void run() { try { resultData = MUtils.loadResult((String) datas.get(prov1).get(school) .get(id), type + 1, prov2); } catch (Exception e) { resultData = null; } handler.sendEmptyMessage(0); } public void search() { if (!Utils.canAccessNetwork(this)) { tipView.setText(無法連接到網絡!); changeView(false); return; } if (prov1 <= 0) { tipView.setText(請選擇學校!); changeView(false); return; } if (prov2 <= 0) { tipView.setText(請選擇您的所在地!); changeView(false); return; } tipView.setText(正在努力為您加載中...); changeView(false); new Thread(this).start(); } Handler handler = new Handler() { public void handleMessage(android.os.Message msg) { if (resultData == null) { tipView.setText(獲取結果失敗,請稍後再試!); changeView(false); } else { StringBuilder sb = new StringBuilder(); sb.append(); sb.append(); sb.append(datas.get(prov1).get(school).get(name)); sb.append(); sb.append(在); sb.append(); sb.append(provs[prov2 - 1]); sb.append(); sb.append(的); sb.append(types[type]); sb.append(錄取線); sb.append(); resultTitleView.setText(Html.fromHtml(sb.toString())); resultList .setAdapter(new SimpleAdapter(MainActivity.this, resultData, R.layout.result_item, new String[] { year, score_max, score_avg, score_td, plan, batch, batch_diff }, new int[] { R.id.result_item_year, R.id.result_item_max, R.id.result_item_avg, R.id.result_item_real, R.id.result_item_persons, R.id.result_item_pici, R.id.result_item_xiancha })); changeView(true); } }; }; public void changeView(boolean flag) { if (flag) { resultLayout.setVisibility(View.VISIBLE); tipView.setVisibility(View.GONE); } else { resultLayout.setVisibility(View.GONE); tipView.setVisibility(View.VISIBLE); } }
package com.gklq.zl; import java.util.ArrayList; import java.util.HashMap; import java.util.Timer; import java.util.TimerTask; import com.my.lib.Utils; import android.app.Activity; import android.os.Bundle; import android.os.Handler; import android.text.Html; import android.view.KeyEvent; import android.view.LayoutInflater; import android.view.View; import android.view.View.OnClickListener; import android.widget.AdapterView.OnItemClickListener; import android.widget.AdapterView; import android.widget.ArrayAdapter; import android.widget.Button; import android.widget.LinearLayout; import android.widget.ListView; import android.widget.PopupWindow; import android.widget.SimpleAdapter; import android.widget.TextView; import android.widget.Toast; public class MainActivity extends Activity implements OnClickListener, Runnable { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); if (Utils.screenHeight <= 0) { Utils.initSize(this); } if (datas == null) { datas = MUtils.loadSchool(this); } setContentView(R.layout.activity_main); prov1Sel = (TextView) findViewById(R.id.prov1_sel); prov1Sel.setOnClickListener(this); schoolSel = (TextView) findViewById(R.id.school_sel); schoolSel.setOnClickListener(this); typeSel = (TextView) findViewById(R.id.type_sel); typeSel.setOnClickListener(this); prov2Sel = (TextView) findViewById(R.id.prov2_sel); prov2Sel.setOnClickListener(this); queryButton = (Button) findViewById(R.id.query_btn); queryButton.setOnClickListener(this); tipView = (TextView) findViewById(R.id.text_tip); resultLayout = (LinearLayout) findViewById(R.id.layout_result); resultTitleView = (TextView) findViewById(R.id.text_result); resultList = (ListView) findViewById(R.id.list_result); provs = getResources().getStringArray(R.array.province); types = getResources().getStringArray(R.array.type); } public void onClick(android.view.View v) { switch (v.getId()) { case R.id.prov1_sel: showProvWindow(0); break; case R.id.prov2_sel: showProvWindow(1); break; case R.id.type_sel: showTypeWindow(); break; case R.id.school_sel: showSchoolWindow(); break; case R.id.query_btn: search(); break; default: break; } } @Override public void run() { try { resultData = MUtils.loadResult((String) datas.get(prov1).get(school) .get(id), type + 1, prov2); } catch (Exception e) { resultData = null; } handler.sendEmptyMessage(0); } public void search() { if (!Utils.canAccessNetwork(this)) { tipView.setText(無法連接到網絡!); changeView(false); return; } if (prov1 <= 0) { tipView.setText(請選擇學校!); changeView(false); return; } if (prov2 <= 0) { tipView.setText(請選擇您的所在地!); changeView(false); return; } tipView.setText(正在努力為您加載中...); changeView(false); new Thread(this).start(); } Handler handler = new Handler() { public void handleMessage(android.os.Message msg) { if (resultData == null) { tipView.setText(獲取結果失敗,請稍後再試!); changeView(false); } else { StringBuilder sb = new StringBuilder(); sb.append(
背景:新年之際,微信微博支付寶紅包是到處飛,但是,自己的手速總是比別人慢一點最後導致紅包沒搶到,紅包助手就應運而生。需求:收到紅包的時候進行提醒,然後跳轉到紅包的界面方便
JSON即JavaScript Object Natation, 是一種輕量級的數據交換格式,采用完全獨立於語言的文本格式,為Web應用開發提供了一種理想的數據交換格式。
綜述對於MVP (Model View Presenter)架構是從著名的MVC(Model View Controller)架構演變而來的。而對於Android應用的開
一、效果圖二、描述更改Android項目中的語言,這個作用於只用於此APP,不會作用於整個系統三、解決方案(一)布局文件<LinearLayout xmlns:an