程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> C#程序員學習Android開發系列之ListView

C#程序員學習Android開發系列之ListView

編輯:C#入門知識

C#程序員學習Android開發系列之ListView


上篇博客解決了Android客戶端通過WebService與服務器端程序進行交互的問題,這篇博客重點關注兩個問題,一個是Android應用程序如何與本機文件型數據庫SQLite進行交互,另一問題則是如何在ListView中按照我們想要的界面效果進行展示。限於篇幅這篇重點講ListView,下篇博客重點闡述SQLite。

ListView是一個常用的數據顯示控件,假設我們要做一個簡單的界面,如圖所示。

\\\\

這張圖是我直接從Android平板電腦(Android 4.2.2)上面截圖下來的,就是一個普通的列表,能夠點擊報名按鈕獲取到對應行的信息。

這裡面顯示的數據是我從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")
	@Override
	public 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布局文件:



    

        

        

        

        
    

    
    

可以看到這是一個相對布局,裡面有一個線性布局,線性布局裡面又放置了4個TextView作為ListView數據的標題。下面直接是一個ListView控件,由於這是相對布局,為了讓ListView顯示在“表頭”下面,我們設置了layout_below屬性。此外要注意ListView的id的寫法。

接著按照界面的要求,我們准備一下ListView加載布局文件的內容,我們起名為:list_item.xml。

list_item.xml:




    

    

    

    

    
這也是一個普通的線性布局,設置orientation為horizontal(水平)。

布局文件准備好,下面我們准備寫代碼了。

我們讓MainActivity這個類繼承自ListActivity,完整的代碼如下:

public class MainActivity extends ListActivity {

	List> list;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		list = new ArrayList>();
		//初始化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>數據結構當中
		while (cursor.moveToNext()) {
			Map map = new HashMap();
			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);
	}

	@Override
	protected void onListItemClick(ListView l, View v, int position, long id) {
		//ListView的
		@SuppressWarnings("unchecked")
		Map map = (HashMap) 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> mList;
		private ButtonViewHolder holder;
		private LayoutInflater mInflater;
		private String[] keyString;
		private int[] valueViewID;

		// 構造函數初始化變量
		public MyButtonAdapter(Context context, List> 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]);// 報名按鈕
				convertView.setTag(holder);
			}
			Map 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);

				// 報名按鈕事件
				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)
																	+ "按鈕,申請了"
																	+ 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)
																	+ "按鈕",
															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類,在顯示數據的同時,能夠給每一行的按鈕綁定點擊事件。

3、彈出提示框

彈出提示框的代碼很長,完全可以封裝到一個方法中,簡化代碼。這裡完整的列出來,目的就是體驗一下設計思路。經過觀察我們發現,這就是所謂的“鏈式編程”,可以通過連續的".",設置參數(控制顯示效果)。

strings.xml:



    確定
    取消

最終在pad上面的執行效果如下:

\

\







  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved