Android动态创建表格 .
来源:互联网 发布:杜月笙 知乎 编辑:程序博客网 时间:2024/06/14 19:04
一、摘要
最近接触到Android开发,由于涉及到Android和服务器端要发送http请求,服务器端通过查表,可以得到结果集(ResultSet),在服务器端,将结果集封装成json对象,以字符串的形式响应给Android端。Android端则需要将对应的字符串再进行一次解析,形成json字符串。然后利用json字符串再在页面动态生成一张表格。这就是大致需要完成的项目中一个环节,下面将上述自己做的过程详细写出来。
二、Android发送http请求封装
这里,我借用网友的代码,他的post请求参数封装非常完善,以servlet为服务器语言为例,发送http请求源代码如下:
- String uri = "http://192.168.191.1:8080/LYunMIS/servlet/ProcessStorageList";
- Map<String, String> params = new HashMap<String, String>();
- params.put("operator", "select");
- params.put("tablename", Constant.Tbl_ProductStorage);//表名
- params.put("NowAdmStatus", "0");//查询条件
- String responseStr = URLUtil.submitPostData(params, Constant.UTF8, uri);
- URLUtil.java
- public class URLUtil {
- public static HttpURLConnection createConn(String uri,String type,String charset) {
- URL url = null;
- HttpURLConnection urlConn = null;
- try {
- url = new URL(uri);
- urlConn = (HttpURLConnection) url.openConnection();
- urlConn.setDoInput(true);//设置输入流采用字节流
- urlConn.setDoOutput(true);
- urlConn.setRequestMethod(type);//请求方式为POST
- urlConn.setUseCaches(false);//不起用缓存
- urlConn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");//设置meta参数
- urlConn.setRequestProperty("Charset", charset);
- } catch (MalformedURLException e) {
- e.printStackTrace();
- } catch (ProtocolException e) {
- e.printStackTrace();
- } catch (IOException e) {
- e.printStackTrace();
- }
- return urlConn;
- }
- public static String submitPostData(Map<String, String> params, String encode, String uri) {
- byte[] data = getRequestData(params, encode).toString().getBytes();//获得请求体
- try {
- URL url = new URL(uri);
- HttpURLConnection httpURLConnection = (HttpURLConnection)url.openConnection();
- httpURLConnection.setConnectTimeout(3000); //设置连接超时时间
- httpURLConnection.setDoInput(true); //打开输入流,以便从服务器获取数据
- httpURLConnection.setDoOutput(true); //打开输出流,以便向服务器提交数据
- httpURLConnection.setRequestMethod("POST"); //设置以Post方式提交数据
- httpURLConnection.setUseCaches(false); //使用Post方式不能使用缓存
- //设置请求体的类型是文本类型
- httpURLConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
- //设置请求体的长度
- httpURLConnection.setRequestProperty("Content-Length", String.valueOf(data.length));
- //获得输出流,向服务器写入数据
- OutputStream outputStream = httpURLConnection.getOutputStream();
- outputStream.write(data);
- int response = httpURLConnection.getResponseCode(); //获得服务器的响应码
- if(response == HttpURLConnection.HTTP_OK) {
- InputStream inptStream = httpURLConnection.getInputStream();
- return dealResponseResult(inptStream); //处理服务器的响应结果
- }
- } catch (IOException e) {
- e.printStackTrace();
- }
- return "";
- }
- /*
- * Function : 封装请求体信息
- * Param : params请求体内容,encode编码格式
- */
- public static StringBuffer getRequestData(Map<String, String> params, String encode) {
- StringBuffer stringBuffer = new StringBuffer(); //存储封装好的请求体信息
- try {
- for(Map.Entry<String, String> entry : params.entrySet()) {
- stringBuffer.append(entry.getKey())
- .append("=")
- .append(URLEncoder.encode(entry.getValue(), encode))
- .append("&");
- }
- stringBuffer.deleteCharAt(stringBuffer.length() - 1); //删除最后的一个"&"
- } catch (Exception e) {
- e.printStackTrace();
- }
- return stringBuffer;
- }
- /*
- * Function : 处理服务器的响应结果(将输入流转化成字符串)
- * Param : inputStream服务器的响应输入流
- */
- public static String dealResponseResult(InputStream inputStream) throws UnsupportedEncodingException {
- String resultData = null; //存储处理结果
- ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
- byte[] data = new byte[1024];
- int len = 0;
- try {
- while((len = inputStream.read(data)) != -1) {
- byteArrayOutputStream.write(data, 0, len);
- }
- } catch (IOException e) {
- e.printStackTrace();
- }
- resultData = new String(byteArrayOutputStream.toByteArray(),"UTF-8"); //设置UTF-8编码,保持编码格式一致否则会出现乱码
- return resultData;
- }
- }
servlet这段的业务的处理与写servlet处理B/S浏览器端的处理类似,主要用到PrintWriter对象的print方法向Android传递字符串,字符串以何种方式传递效率较高呢?当然,对于一般的长度较短的字符串,可以直接进行解析。但如果是一个表的数千万行数据,自己解析效率就会相当低,而且对编写两层间通信接口造成相当大的维护难度。
目前,对于java有两种比较成熟的方式,xml和json解析。这里介绍一下,json的封装和解析。
三、json的封装和解析
从数据库查询一条或多条记录,jdbc将会得到一个结果集ResultSet,如果查询的记录为0条,封装的json为"[]".
Result封装称jsonArray的方法
- public static JSONArray ResultSetToJsonArray(ResultSet rs) throws SQLException, JSONException {
- //获取列数
- ResultSetMetaData md = rs.getMetaData();
- int columnCount = md.getColumnCount();
- //json数组
- JSONArray array = new JSONArray();
- while (rs.next()) {
- JSONObject jsonObj = new JSONObject();
- for (int i = 1; i <= columnCount; i++) {
- String columnName = md.getColumnLabel(i);
- Object obj = rs.getObject(columnName);
- // String value = rs.getString(columnCount);
- jsonObj.put(columnName, obj);
- }
- array.put(jsonObj);
- }
- return array;
- }
得到了jsonArray对象,就可以将它以字符串的形式向Android端发送数据,Android端接收到的是json字符串,如何进行解析呢?
Android已经有专门的类为我们解析做好了准备了。
如果明确得到的是jsonArray字符串:JSONArrayjsonArray = new JSONArray(str);
而如果是jsonObject字符串:JSONObjectjsonObj = new JSONObject(str);
有了jsonArray或者jsonObjet我们就可以动态创建表格了
四、Android动态创建表格
动态创建表格需要自己来写相应的表格的实现类,这里借助网友的实现TableRow和TableCell代码如下:
- /**
- * TableRow 实现表格的行
- */
- public class TableRow {
- private TableCell[] cell;
- public TableRow(TableCell[] cell) {
- this.cell = cell;
- }
- public int getSize() {
- return cell.length;
- }
- public TableCell getCellValue(int index) {
- if (index >= cell.length)
- return null;
- return cell[index];
- }
- }
- /**
- * TableCell 实现表格的格单元
- * @author hellogv
- */
- public class TableCell {
- static public final int STRING = 0;
- static public final int IMAGE = 1;
- public Object value;
- public int width;
- public int height;
- public int type;
- public TableCell(Object value, int width, int height, int type) {
- this.value = value;
- this.width = width;
- this.height = height;
- this.type = type;
- }
- }
- public static List<TableRow> addData(int width,String jsonArray,String[] columnsKey,String[] columnsHead) {
- List<TableRow> table = new ArrayList<TableRow>();
- TableCell[] titles = new TableCell[columnsHead.length];// 每行4个单元
- try{
- // 定义标题
- for (int i = 0; i < titles.length; i++) {
- titles[i] = new TableCell(columnsHead[i],
- width,
- LayoutParams.MATCH_PARENT,
- TableCell.STRING);
- }
- table.add(new TableRow(titles));
- List<String[]> tables = JsonUtil.parseJsonArray(jsonArray, columnsKey);
- for (int i = 0; i < tables.size(); i++) {
- TableCell[] cols = new TableCell[columnsKey.length];// 每行4个单元
- String[] contents = tables.get(i);
- for(int j = 0;j < contents.length;j++) {
- cols[j] = new TableCell(contents[j], width, LayoutParams.MATCH_PARENT, TableCell.STRING);
- }
- table.add(new TableRow(cols));
- }
- }catch(Exception e) {
- Log.d("添加表格异常", "Error:", e);
- }
- return table;
- }
参数说明:jsonArray是对应的jsonArray字符串,columnsKey则是查询结果中的字段名也即key,columnsHead是表头,可以自己自定义为中文。
有时候,也会将一条数据显示在一个表格中,同样借助上面的方式,可以自己改写,实现代码如下:
- public static List<TableRow> addSingleRecord(int width,String jsonObjStr,String[] columnKey,String[] columnHead) {
- List<TableRow> table = new ArrayList<TableRow>();
- try{
- TableCell[] titles = new TableCell[2];// 每行2个单元
- titles[0] = new TableCell("字段名",
- width,
- LayoutParams.MATCH_PARENT,
- TableCell.STRING);
- titles[1] = new TableCell("字段值",
- width,
- LayoutParams.MATCH_PARENT,
- TableCell.STRING);
- table.add(new TableRow(titles));
- int size = columnHead.length;
- JSONObject jsonObj = new JSONObject(jsonObjStr);
- for (int i = 0; i < size; i++) {
- TableCell[] body = new TableCell[2];// 每行2个单元
- Object col = jsonObj.get(columnKey[i]);
- body[0] = new TableCell(columnHead[i], width, LayoutParams.MATCH_PARENT, TableCell.STRING);
- body[1] = new TableCell(col, width, LayoutParams.MATCH_PARENT, TableCell.STRING);
- table.add(new TableRow(body));
- }
- }catch(Exception e) {
- Log.d("添加表格异常", "Error:", e);
- }
- return table;
- }
这里就不贴图了,内容比较多,对需要的朋友应该会有很大的帮助。
仅仅有上面这些还不够,真正要将数据添加到页面,还需要一个table的适配器,它是继承自BaseAdatper
- public class TableAdapter extends BaseAdapter {
- private Context context;
- private List<TableRow> table;
- public TableAdapter(Context context, List<TableRow> table) {
- this.context = context;
- this.table = table;
- }
- @Override
- public int getCount() {
- return table.size();
- }
- @Override
- public long getItemId(int arg0) {
- return arg0;
- }
- @Override
- public View getView(int arg0, View arg1, ViewGroup arg2) {
- TableRow tableRow = table.get(arg0);
- return new TableRowView(this.context, tableRow,arg0);
- }
- @Override
- public Object getItem(int arg0) {
- return arg0;
- }
- }
这些实现代码都帮助我们实现了,将数据真正添加到table已不是问题
五、Activity中添加数据
list_process_storage为页面的ListView对象
- List<TableRow> table;//声明为全局变量,供之后单条记录使用
- table = TableUtil.addData(width, responseStr, TableUtil.Tbl_ProductStorage,TableUtil.Tbl_ProductStorage_zh);
- TableAdapter tableAdapter = new TableAdapter(this, table);
- list_process_storage.setAdapter(tableAdapter);
- list_process_storage.setOnItemClickListener(new ItemClickEvent());
- class ItemClickEvent implements OnItemClickListener {
- @Override
- public void onItemClick(AdapterView<?> listView, View v, int position, long arg3) {
- if(position == 0) return;//点击表头不跳转
- // TableRowView tableRowView = (TableRowView) v;
- // TextView teView = (TextView) tableRowView.getChildAt(0);
- //再将teView中的值在json中找到,跳转到确认状态页面
- // TableRow row = table.get(position);
- // Toast.makeText(DesignCommittingMtTblActivity.this,row.getCellValue(0).value.toString(),Toast.LENGTH_LONG).show();
- try {
- JSONArray jsonArray = new JSONArray(arrayStr);
- JSONObject jsonObj = jsonArray.getJSONObject(position - 1);
- Intent intent = new Intent();
- intent.setClass(ProcessStorageActivity.this, ProcessStorageSingleActivity.class);
- intent.putExtra("single", jsonObj.toString());
- intent.putExtra("enable", true);
- startActivityForResult(intent, 0);
- } catch (JSONException e) {
- e.printStackTrace();
- }
- }
- }
注意:别小看注释部分,可能就是这里的细节对你有用!
漏了一点内容,多亏网友提醒,现加到后面
- public class TableRowView extends LinearLayout {
- public TableRowView(Context context, TableRow tableRow,int odd) {
- super(context);
- this.setOrientation(LinearLayout.HORIZONTAL);
- for (int i = 0; i < tableRow.getSize(); i++) {//逐个格单元添加到行
- TableCell tableCell = tableRow.getCellValue(i);
- LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(
- tableCell.width, tableCell.height);//按照格单元指定的大小设置空间
- layoutParams.setMargins(1, 1, 1, 1);//预留空隙制造边框
- if (tableCell.type == TableCell.STRING) {//如果格单元是文本内容
- TextView textCell = new TextView(context);
- textCell.setLines(1);
- textCell.setGravity(Gravity.CENTER);
- if(odd % 2 == 0)
- textCell.setBackgroundColor(Color.GREEN);//背景 灰色
- else
- textCell.setBackgroundColor(Color.WHITE);//背景 白色
- textCell.setText(String.valueOf(tableCell.value));
- addView(textCell, layoutParams);
- } else if (tableCell.type == TableCell.IMAGE) {//如果格单元是图像内容
- ImageView imgCell = new ImageView(context);
- imgCell.setBackgroundColor(Color.WHITE);//背景灰色
- imgCell.setImageResource((Integer) tableCell.value);
- addView(imgCell, layoutParams);
- }
- }
- this.setBackgroundColor(Color.BLUE);//背景白色,利用空隙来实现边框
- }
- }
- Android动态创建表格
- Android动态创建表格 .
- js动态创建表格
- javascript 动态创建表格
- javascript 动态创建表格
- javascript 动态创建表格
- 动态创建表格c#
- js动态创建表格
- js动态创建表格
- MecGrid 动态创建表格
- JS动态创建表格
- 动态表格创建
- JQuery动态创建表格
- JS动态创建表格
- JS 动态创建表格
- javascript 动态创建表格
- javascript动态创建表格
- js 动态创建表格
- Mac系统终端命令行不执行命令 总出现command not found解决方法
- VC调用matlab中定义的.m文件中的函数的实例
- ScrollView嵌套ListView,GridView,ViewPager,以及这些控件自动滚动到底部问题的解决
- appium robotframework 真机测试体验
- ipa终端打包
- Android动态创建表格 .
- 磁盘空间不足,在线移动Oracle的数据文件
- 使用JXPath访问java对象、集合和XML文件
- JAVA Web 要关闭IE缓存,并且要重新关闭页面,重新加载
- android ListView 几个重要属性
- iOS第三方开源库的吐槽和备忘
- DB2两个经纬度间的距离(米)
- android:layout_alignParentRight
- Mysql 安装流程图解