Android开发系列之ListView
上篇博客攻克了Androidclient通過WebService與server端程序進行交互的問題,這篇博客重點關注兩個問題,一個是Android應用程序怎樣與本機文件型數據庫SQLite進行交互,還有一問題則是怎樣在ListView中依照我們想要的界面效果進行展示。限于篇幅這篇重點講ListView,下篇博客重點闡述SQLite。
ListView是一個經常使用的數據顯示控件,如果我們要做一個簡單的界面,如圖所看到的。
這張圖是我直接從Android平板電腦(Android 4.2.2)上面截圖下來的,就是一個普通的列表。能夠點擊報名button獲取到相應行的信息。
這里面顯示的數據是我從SQLite數據庫中查詢出來的,封裝的類的代碼例如以下:
public class MyDatabaseHelper extends SQLiteOpenHelper {private static final String name = "mydb.db";// SQLite數據庫文件名稱private static final int version = 1;// SQLite數據庫版本public MyDatabaseHelper(Context context) {super(context, name, null, version);}@SuppressLint("SimpleDateFormat")@Overridepublic void onCreate(SQLiteDatabase db) {try {// 開啟事務db.beginTransaction();String sql = "create table jobInfo (name varchar(20),"+ "num integer," + "date varchar(10),"+ "description text)";db.execSQL(sql);//測試插入10條數據for (int i = 0; i < 10; i++) {db.execSQL("insert into jobInfo(name,num,date,description)values(?,?,?,?)", new Object[] { "name" + i, i, new SimpleDateFormat("yyyy-MM-dd") .format(new Date()), "description" + i }); } // 標識事務成功 db.setTransactionSuccessful(); } finally { // 結束事務 db.endTransaction(); } } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { //數據庫升級操作 } }
在須要創建數據庫、插入數據的地方都能夠實例化MyDatabaseHelper這個類。關于很多其它的SQLite的細節下篇博客將會進行具體的說明。activity_main.xml布局文件:
此外要注意ListView的id的寫法。
接著依照界面的要求,我們準備一下ListView載入布局文件的內容。我們起名為:list_item.xml。
list_item.xml:
布局文件準備好。以下我們準備寫代碼了。
我們讓MainActivity這個類繼承自ListActivity。完整的代碼例如以下:
public class MainActivity extends ListActivity {List<Map<String, Object>> list;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);list = new ArrayList<Map<String, Object>>();//初始化SQLite數據庫操作類對象MyDatabaseHelper dbHelper = new MyDatabaseHelper(MainActivity.this);//查詢數據庫返回Cursor(游標)對象Cursor cursor = dbHelper.getReadableDatabase().query("jobInfo",new String[] { "name", "num", "date", "description" }, null,null, null, null, "name");//將結果集封裝到List<Map<String,Object>>數據結構其中while (cursor.moveToNext()) {Map<String, Object> map = new HashMap<String, Object>();map.put("name", cursor.getString(0));map.put("num", cursor.getInt(1));map.put("date", cursor.getString(2));map.put("description", cursor.getString(3));map.put("btn", R.drawable.ic_launcher);list.add(map);}//查詢完成,記得及時關閉數據庫鏈接cursor.close();MyButtonAdapter adapter = new MyButtonAdapter(MainActivity.this, list,R.layout.list_item, new String[] { "name", "num", "date","description", "btn" }, new int[] { R.id.name,R.id.num, R.id.date, R.id.description, R.id.btn });//給ListView設置數據填充適配器ListView listView = (ListView) findViewById(android.R.id.list);listView.setAdapter(adapter);}@Overrideprotected void onListItemClick(ListView l, View v, int position, long id) {//ListView的@SuppressWarnings("unchecked")Map<String, Object> map = (HashMap<String, Object>) l.getItemAtPosition(position);Toast.makeText(MainActivity.this,"您點擊了:" + map.get("name").toString() + "崗位!", Toast.LENGTH_SHORT).show(); } public class MyButtonAdapter extends BaseAdapter { private class ButtonViewHolder { TextView name; TextView num; TextView date; TextView description; Button btn; } private Context mContext; private List<Map<String, Object>> mList; private ButtonViewHolder holder; private LayoutInflater mInflater; private String[] keyString; private int[] valueViewID; // 構造函數初始化變量 public MyButtonAdapter(Context context, List<Map<String, Object>> list, int resource, String[] from, int[] to) { this.mContext = context; this.mList = list; // 獲得布局文件對象 mInflater = (LayoutInflater) context .getSystemService(Context.LAYOUT_INFLATER_SERVICE); keyString = new String[from.length]; valueViewID = new int[to.length]; // 復制數組 System.arraycopy(from, 0, keyString, 0, from.length); System.arraycopy(to, 0, valueViewID, 0, to.length); } @Override public int getCount() { return list.size(); } @Override public Object getItem(int position) { return list.get(position); } /** * 從list中移除某一項 * * @param position */ public void removeItem(int position) { list.remove(position); // 通知數據集已改變,請求自刷新 this.notifyDataSetChanged(); } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { if (convertView != null) { holder = (ButtonViewHolder) convertView.getTag(); } else { convertView = mInflater.inflate(R.layout.list_item, null); holder = new ButtonViewHolder(); holder.name = (TextView) convertView .findViewById(valueViewID[0]);// 崗位名稱 holder.num = (TextView) convertView .findViewById(valueViewID[1]);// 崗位數量 holder.date = (TextView) convertView .findViewById(valueViewID[2]);// 公布日期 holder.description = (TextView) convertView .findViewById(valueViewID[3]);// 崗位描寫敘述 holder.btn = (Button) convertView.findViewById(valueViewID[4]);// 報名button convertView.setTag(holder); } Map<String, Object> appInfo = mList.get(position); if (appInfo != null) { String aname = (String) appInfo.get(keyString[0]); Integer anum = (Integer) appInfo.get(keyString[1]); String adate = (String) appInfo.get(keyString[2]); String adescription = (String) appInfo.get(keyString[3]); holder.name.setText(aname); holder.num.setText(anum + ""); holder.date.setText(adate); holder.description.setText(adescription); // 報名button事件 holder.btn.setOnClickListener(new lvButtonListener(position)); } return convertView; } class lvButtonListener implements OnClickListener { private int position; lvButtonListener(int pos) { position = pos; } @Override public void onClick(View v) { int vid = v.getId(); if (vid == holder.btn.getId()) { String result = "" + "崗位名稱:" + list.get(position).get("name") + "\r\n" + "崗位人數:" + list.get(position).get("num") + "\r\n" + "公布日期:" + list.get(position).get("date") + "\r\n" + "崗位描寫敘述:" + list.get(position).get("description") + "\r\n"; new AlertDialog.Builder(MainActivity.this) .setTitle("提示") .setIcon(R.drawable.ic_launcher) .setMessage(result + "\r\n" + "您確定要申請該崗位嗎?") .setPositiveButton(R.string.positive, new DialogInterface.OnClickListener() { @Override public void onClick( DialogInterface dialog, int which) { Toast toast = Toast .makeText( MainActivity.this, "您點擊了" + getResources() .getString( R.string.positive) + "button,申請了" + list.get( position) .get("name") + "的崗位!
", Toast.LENGTH_SHORT); toast.setGravity(Gravity.CENTER, 0, 0); toast.show(); } }) .setNegativeButton(R.string.negative, new DialogInterface.OnClickListener() { @Override public void onClick( DialogInterface dialog, int which) { Toast toast = Toast .makeText( MainActivity.this, "您點擊了" + getResources() .getString( R.string.negative) + "button", Toast.LENGTH_SHORT); toast.setGravity(Gravity.CENTER, 0, 0); toast.show(); } }).create().show(); // 如果要刪除行。能夠調用此方法 // removeItem(position); } } } } }
上面的代碼有幾個知識點須要注意:
1、SQLite數據庫的查詢操作
我們通過getReadableDatabase().query方法運行了查詢操作。返回Cursor(游標。與JDBC中的ResultSet相似)對象。
2、ListView控件使用(重點)
我們參考了SimpleAdapter默認的構造函數的方法,創建了自己定義的MyButtonAdapter類,在顯示數據的同一時候,能夠給每一行的button綁定點擊事件。
3、彈出提示框
彈出提示框的代碼非常長,全然能夠封裝到一個方法中,簡化代碼。這里完整的列出來。目的就是體驗一下設計思路。
經過觀察我們發現,這就是所謂的“鏈式編程”。能夠通過連續的".",設置參數(控制顯示效果)。
strings.xml:
<?xml version="1.0" encoding="utf-8"?> <resources><string name="positive">確定</string><string name="negative">取消</string> </resources>終于在pad上面的運行效果例如以下:
總結
以上是生活随笔為你收集整理的Android开发系列之ListView的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: JavaScript ES6箭头函数指南
- 下一篇: Jexus部署.Net Core项目