?通過對數(shù)據(jù)庫操作從而將數(shù)據(jù)存入數(shù)據(jù)庫以及學(xué)習(xí)如何動態(tài)的將一個textview文本控件添加到Linearlayout容器中屋吨。
android:layout_width="fill_parent"
android:layout_height="fill_parent">
android:id="@+id/ll_result"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
注意的是最下方的空白處用了一個linearlayout容器來顯示添加的學(xué)生信息济舆,但是有可能數(shù)據(jù)太多顯示不全,所以包裹了一個ScrollView在外面,可以讓里面的信息進(jìn)行滾動。ScrollView只能有一個子孩子,不能包裹多個葛超。
在MainActivity中定義一個單獨(dú)的方法查詢所有的學(xué)生數(shù)據(jù)并展示到界面上
獲取數(shù)據(jù)庫的全部記錄,刷新顯示數(shù)據(jù)
privatevoidrefreshData() {
List students =dao.findAll();
ll_result.removeAllViews();//把原來的數(shù)據(jù)給清除
for(Student student : students) {
TextView tv =newTextView(this);
tv.setText(student.toString());
ll_result.addView(tv);
}
}
注意的是在將textview添加到linearlayout容器中之前,一定要先將linearlayout中原來存在的textview控件清除延塑,否則會造成重復(fù)的數(shù)據(jù)不斷顯示绣张。
最后在點(diǎn)擊保存按鈕的save()方法中,當(dāng)添加成功一條數(shù)據(jù)時关带,調(diào)用refreshData()方法刷新界面侥涵,以及在oncreate方法中調(diào)用refreshData()將數(shù)據(jù)庫存在的學(xué)生數(shù)據(jù)顯示出來。
ListView
通過數(shù)據(jù)庫中的學(xué)生信息管理系統(tǒng)中的案例讓我們熟悉了數(shù)據(jù)庫的創(chuàng)建和使用豫缨,以及動態(tài)添加一個控件到linearlayout容器中;不過這種方式有一個極大的問題就是:不斷的在創(chuàng)建new一個Textview控件添加到linearlayout端朵,會造成如果有100個學(xué)生就得new100個textview好芭,如果成千上萬那內(nèi)存開銷會巨大導(dǎo)致內(nèi)存溢出,所以android給我們引入了一個對數(shù)據(jù)進(jìn)行列表展示的控件:ListView.
ListView的特點(diǎn):
1冲呢、屏幕上可以展示幾個條目舍败,ListView就初始化幾個,節(jié)省內(nèi)存。
2邻薯、通過使用convertView對創(chuàng)建的視圖對象進(jìn)行復(fù)用裙戏,ListView始終保持創(chuàng)建的對象個數(shù)為:屏幕顯示的條目的個數(shù)+ 1。
3厕诡、ListView自帶ScrollView的功能累榜,可以實(shí)現(xiàn)界面滾動。
4灵嫌、ListView控件的設(shè)計(jì)遵循MVC設(shè)計(jì)模式:mode數(shù)據(jù)模型(數(shù)據(jù)):要被顯示到ListView上的數(shù)據(jù)集合view視圖(展示數(shù)據(jù)):ListView ?controller控制層(把數(shù)據(jù)展示到控件上) :適配器AdapterBaseAdapter
ListView的優(yōu)化
上訴的步驟只是最簡單的顯示出來了一個listview以及里面展示的數(shù)據(jù)壹罚,但是如果我們要顯示的數(shù)據(jù)有一萬條,那么在快速往上滾動的過程中就會不斷的調(diào)用adapter中的getView方法寿羞,不斷的生成新的Textview控件猖凛,消耗內(nèi)存資源,最后導(dǎo)致內(nèi)存不足绪穆,造成oom內(nèi)存溢出辨泳。
ListView復(fù)用的原理
當(dāng)我們滑動listview的時候,每當(dāng)一個item看不見的時候玖院,那么那個item就可以被復(fù)用起來了菠红,也就是成為了convertView,那個時候convertView就不為null了
所謂的復(fù)用,其實(shí)本質(zhì)是就是item的view對象沒有真正的被垃圾回收器回收掉司恳,而是重新將身上的數(shù)據(jù)給換掉了途乃,看起來好像是出現(xiàn)了一個新的item而已
對ListView進(jìn)行優(yōu)化的最簡單有效的措施就是復(fù)用getView方法中的convertView對象。convertView來自緩存池扔傅,緩存池由ListView維護(hù)耍共,緩存池中的數(shù)據(jù)來自getView方法的返回值,也就是說getView方法的返回值用完后并沒有“浪費(fèi)”猎塞,而是被系統(tǒng)放到ListView的緩存池里了试读。緩存池的大小=屏幕顯示的條目數(shù)+1,當(dāng)滑動屏幕時荠耽,被隱藏的項(xiàng)會作為緩存對象钩骇,作為getView的參數(shù)傳遞進(jìn)來。只需修改此緩存對象的數(shù)據(jù)铝量,就可以直接使用倘屹,而不需要再重新new一個新的對象,節(jié)省了內(nèi)存慢叨,防止內(nèi)存溢出纽匙。
打氣筒inflate
當(dāng)我們listview的item條目需要顯示比較復(fù)雜的布局時,這個時候如果還用代碼的方式去實(shí)現(xiàn)就不是很方便了拍谐,所以android給我們提供了一個方便的API烛缔,View對象本身或者任何繼承View對象的控件都有一個方法(下面的代碼是系統(tǒng)View中的源碼)
我們把它形象的比喻為打氣筒馏段,可以將一個布局文件打氣打成一個View對象,方便我們使用践瓷。布局里面的所有控件都可以通過這個View對象來進(jìn)行查找.
Item條目上有一個刪除按鈕院喜,在上訴代碼中給這個按鈕注冊了點(diǎn)擊事件,點(diǎn)擊的時候從數(shù)據(jù)庫刪除數(shù)據(jù)晕翠,這個時候需要更新UI界面喷舀;以及在點(diǎn)擊保存按鈕的時候添加一條數(shù)據(jù)庫的時候,添加成功后需要刷新界面崖面,那么ListView界面如何刷新呢元咙?
通知數(shù)據(jù)適配器刷新數(shù)據(jù)
BaseAdapter適配器中有一個方法adapter.notifyDataSetChanged()該方法是通知適配器進(jìn)行數(shù)據(jù)刷新,會自己調(diào)用adapter中的getCount()和getView()方法進(jìn)行數(shù)據(jù)的刷新巫员。
獲取數(shù)據(jù)庫的全部記錄,刷新顯示數(shù)據(jù)
privatevoidrefreshData() {
students=dao.findAll();
if(adapter==null) {
//第一次顯示數(shù)據(jù)
adapter=newMyAdapter();
lv.setAdapter(adapter);
}else{
//通知數(shù)據(jù)適配器更新數(shù)據(jù),而不是new出來新的數(shù)據(jù)適配器
adapter.notifyDataSetChanged();
}
}
對話框
對話框的初始化
AlertDialog.Builder builder = new Builder(當(dāng)前Activity的上下文);
對話框設(shè)置屬性
builder.setTitle(title);-->設(shè)置標(biāo)題
builder.setMessage(msg);-->設(shè)置提醒信息
設(shè)置對話框按鈕
builder.setPositiveButton(按鈕文字,new DialogInterface.OnClickListener());-->最右邊的按鈕
builder.setNegativeButton(按鈕文字,new DialogInterface.OnClickListener());-->最左邊的按鈕
builder.setNeutralButton(按鈕文字,new DialogInterface.OnClickListener());-->中間的按鈕
對話框顯示
builder.show();
對話框樣式
setSingleChoiceItems()-->單選
setMultiChoiceItems()-->多選
ProgressDialog -->進(jìn)度條