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<String> loadFileContentForList(String filePath, Context ctx) throws IOException {
		InputStream is = ctx.getAssets().open(filePath);
		BufferedReader br = new BufferedReader(new InputStreamReader(is, "gbk"));
		ArrayList<String> results = new ArrayList<String>();
		String readLine = null;
		while((readLine = br.readLine()) != null) {
			results.add(readLine);
		}
		return results;
	}
以上方法将文件中的数据按行加载到列表中,由于在保存数据源时保存为ASCII格式,所以此处采用gbk加载。

2 从网络中获取高校查询结果

采用Android自带的HttpClient进行实现,我们首先封装一个简单的HttpUtils处理类,提供httpGet请求方法:

       /**
	 * 获取指定URL请求的结果信息,以字符串方式返回请求内容
	 * @param url 请求地址
	 * @param param 请求所需参数
	 * @return
	 */
	public static String httpGet(String url, HashMap<String, Object> param) {
		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<String, Object> 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;
	}
3 为了便于控件渲染数据,我们将所有数据均转为SimpleAdapter可识别的格式ArrayList<HashMap<String, Object>>

通过MUtils类提供各个数据的转化:

loadSchool方法用于提供所有学校信息数据转化,其中Map的key表示省份ID,value为学校列表

@SuppressLint("UseSparseArrays")
public static HashMap<Integer, ArrayList<HashMap<String, Object>>> loadSchool(Context ctx) {
	HashMap<Integer, ArrayList<HashMap<String, Object>>> result = new HashMap<Integer, ArrayList<HashMap<String,Object>>>();
		try {
			List<String> contents = FileUtils.loadFileContentForList("m/data", ctx);
			for(int i = 0, len = contents.size(); i < len; i++) {
				String[] item = contents.get(i).split("#");
				HashMap<String, Object> data = new HashMap<String, Object>();
				data.put("id", item[1]);
				data.put("name", item[2]);
				ArrayList<HashMap<String, Object>>  itemList = result.get(Integer.parseInt(item[0]));
				if(itemList == null) {
					itemList = new ArrayList<HashMap<String,Object>>();
					result.put(Integer.parseInt(item[0]), itemList);
				}
				itemList.add(data);
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
		return result;
}
loadResult方法用于将网络获取的查询结果信息进行转化,主要将返回的JSON格式进行处理

public static ArrayList<HashMap<String, Object>> loadResult(final String schoolId, final int type, final int prov2) throws Exception{
		//从网络获取查询结果,返回格式为JSON
		String netStr = HttpUtils.httpGet(BASE_URL, new HashMap<String, Object>(){{
			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<HashMap<String, Object>> result = new ArrayList<HashMap<String,Object>>();
		for(int i = 0, len = resultArray.length(); i < len; i++) {
			//依次处理每一条数据信息
			JSONObject jobj = resultArray.getJSONObject(i);
			HashMap<String, Object> d = new HashMap<String, Object>();
			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<String, String> batchMap = new HashMap<String, String>(){{
		put("00", "不详");
		put("01", "本科提前批");
		put("11", "本科一批");
		put("12", "本科二批");
		put("13", "本科三批");
		put("123", "本科二、三批");
		put("21", "专科");
	}};
其中BASE_URL = "http://kaoshi.edu.sina.com.cn/iframe/i_collegescore.php", batchMap从原有数据网站中获取并初始化数据

二、Activity实现

Activity中所有变量定义如下所示:

        //依次为省份选择ID,用户所在地ID,学校序号,文理科类型
	int prov1, prov2, school, type;
	ArrayList<HashMap<String, Object>> resultData;	//查询录取结果
	HashMap<Integer, ArrayList<HashMap<String, Object>>> 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<String>(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<String>(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("<html>");
				sb.append("<font color='#006400'><b>");
				sb.append(datas.get(prov1).get(school).get("name"));
				sb.append("</b></font>");
				sb.append("在");
				sb.append("<font color='#006400'><b>");
				sb.append(provs[prov2 - 1]);
				sb.append("</b></font>");
				sb.append("的");
				sb.append(types[type]);
				sb.append("录取线");
				sb.append("</html>");
				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);
		}
	}

完整的Activity代码如下所示:

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("<html>");
				sb.append("<font color='#006400'><b>");
				sb.append(datas.get(prov1).get(school).get("name"));
				sb.append("</b></font>");
				sb.append("在");
				sb.append("<font color='#006400'><b>");
				sb.append(provs[prov2 - 1]);
				sb.append("</b></font>");
				sb.append("的");
				sb.append(types[type]);
				sb.append("录取线");
				sb.append("</html>");
				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);
		}
	}

	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();
	}

	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<String>(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();
	}

	/**
	 * 显示省份弹窗。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<String>(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();
	}

	@Override
	protected void onResume() {
		super.onResume();
		if (Utils.screenHeight <= 0) {
			Utils.initSize(this);
		}
		if (datas == null) {
			datas = MUtils.loadSchool(this);
		}
	}

	//依次为省份选择ID,用户所在地ID,学校序号,文理科类型
	int prov1, prov2, school, type;
	ArrayList<HashMap<String, Object>> resultData;	//查询录取结果
	HashMap<Integer, ArrayList<HashMap<String, Object>>> 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;

	@Override
	public boolean onKeyDown(int keyCode, KeyEvent event) {
		if (keyCode == KeyEvent.KEYCODE_BACK) {
			if (!isExit) {
				isExit = true;
				Toast.makeText(this, "再按一次返回键退出", Toast.LENGTH_SHORT).show();
				tExit = new Timer();
				tExit.schedule(new TimerTask() {
					@Override
					public void run() {
						isExit = false;
						tExit.cancel();
					}
				}, 3000);
			} else {
				finish();
				android.os.Process.killProcess(android.os.Process.myPid());
				System.gc();
			}
		} else {
		}
		return false;
	}

	private boolean isExit = false;
	Timer tExit;
}







  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值