方案一:php
底部有查看不少其它可以使用HeaderViewListAdapter
假設需要加入數據, 就向Adapter綁定的數據裏面加入. 而後調用Adapter.notifyDataSetChanged()方法, ListView會本身主動刷新;html
java.lang.Object | |
↳ | android.widget.HeaderViewListAdapter |
ListAdapter used when a ListView has header views. This ListAdapter wraps another one and also keeps track of the header views and their associated data objects.java
This is intended as a base class; you will probably not need to use this class directly in your own code.android
1.在listview初始化的時候加個footview,並初始化相關變量以及要設置listview的OnScrollListener: listview = (ListView) layoutMain.findViewById(R.id.vidoe_list); layoutFooter = (RelativeLayout) mLayoutInflater.inflate( R.layout.contact_list_footer, null); listview.addFooterView(layoutFooter); adapter = new VideoListAdapter(); listview.setAdapter(adapter); listview.setOnItemClickListener(mItemClickListener); listview.setOnScrollListener(mHLOnScrollListener); 2.載入數據:載入數據的時候最好用一個線程來執行載入過程,完了以後就用handler發個消息出來。這裏要控制這個線程的 生命週期,假如線程已經啓動並且還沒跑完,就先不要再啓動,等上一次跑完再start一個線程 private Thread threadLoadHLData; List<VidoeDetailInfoItem> listVideoInfo = new ArrayList<VidoeDetailInfoItem>();// 數據列表 List data ; private void onLoadData(final String url, final String pageName) { if (threadLoadHLData == null || !threadLoadHLData.isAlive()) {//檢測線程狀態 threadLoadHLData = new Thread() { public void run() { Looper.prepare(); try { data = VideoDownloadClient.requestPageData( VideoListLayoutManager.this.ctx, url, PageParserFactory.getParser(parserType), pageName); //sleep(200); if(null != data){ HLhandler.obtainMessage(1).sendToTarget(); }else{ HLhandler.obtainMessage(2).sendToTarget(); } } catch (IOException e) { // TODO Auto-generated catch block Log.e("IOException", e.getMessage()); HLhandler.obtainMessage(2).sendToTarget(); } } }; threadLoadHLData.start(); } } 3.在OnScrollListener的實現方法中檢測是否是已經滑動到最後一個: OnScrollListener mHLOnScrollListener = new OnScrollListener(){ public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { // TODO Auto-generated method stub if (firstVisibleItem + visibleItemCount == totalItemCount) {//推斷是否是最後一個 // 開線程去下載網絡數據 if (threadLoadHLData == null || !threadLoadHLData.isAlive()) { onLoadData(url );//這裏的載入數據跟開始初始化時同樣的 //if (pageHLIndex < 82) { pageHLIndex++; //} } } } @Override public void onScrollStateChanged(AbsListView view, int scrollState) { // TODO Auto-generated method stub } }; |
簡單說一下怎麼實現listview分頁載入:
Android market裏軟件列表,每頁顯示10條記錄,沒有顯示上一頁,下一頁的button,依靠手滑動動態載入數據,當向下滾動時,最下邊顯示 Loading… 。數據載入結束,Loading底欄消失。關於ListView的分段顯示,有現成的庫可用,比方 cwac-endless, 這個庫很差之處,就是底部Loading的View沒法定製。另外一個在google code上的androidpageablelistview 這個可以實現主要的分頁,有手動操做顯示上一頁,下一頁的button。查閱了很是多資料,發現事實上ListView自帶一個實現分頁載入的方法,用到addFooterView/removeView 這兩個函數「加入」或「去掉「ListView頁腳。如下是一個研究ListView分頁時作的一個Demo,比較簡單,我把思路我源代碼和你們分享一下,但願對你們有所幫助。
效果圖:
實現思路如是:用onScroll方法實現」滑動「後處理檢查是否還有新的記錄,假設有,調用addFooterView,加入記錄到adapter, adapter調用 notifyDataSetChanged 更新數據;假設沒有記錄了, 把本身定義的mFooterView去掉。這裏沒有重寫onScrollStateChanged函數,那麼在onScroll就需要一個外部變量mFirstCell記錄滑動位置。
代碼例如如下:
import android.app.ListActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.BaseAdapter;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.AbsListView.OnScrollListener;
import android.widget.LinearLayout.LayoutParams;
/**
*
* @author huangbq
*
*/
public class MainActivity extends ListActivity implements OnScrollListener {
private static final String TAG = "MainActivity";
private listViewAdapter adapter = new listViewAdapter();
ListView listView ;
private int lastItem = 0;
LinearLayout loadingLayout;
/**
* 設置佈局顯示屬性
*/
private LayoutParams mLayoutParams =new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,LinearLayout.LayoutParams.WRAP_CONTENT);
/**
* 設置佈局顯示目標最大化屬性
*/
private LayoutParams FFlayoutParams =new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT,LinearLayout.LayoutParams.FILL_PARENT);
private ProgressBar progressBar;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.i(TAG, "onCreate(Bundle savedInstanceState)>>>>>>>>>>>>>>>" );
//線性佈局
LinearLayout layout = new LinearLayout(this);
//設置佈局 水平方向
layout.setOrientation(LinearLayout.HORIZONTAL);
//進度條
progressBar = new ProgressBar(this);
//進度條顯示位置
progressBar.setPadding(0, 0, 15, 0);
//把進度條增長到layout中
layout.addView(progressBar, mLayoutParams);
//文本內容
TextView textView = new TextView(this);
textView.setText("載入中...");
textView.setGravity(Gravity.CENTER_VERTICAL);
//把文本增長到layout中
layout.addView(textView, FFlayoutParams);
//設置layout的重力方向,即對齊方式是
layout.setGravity(Gravity.CENTER);
//設置ListView的頁腳layout
loadingLayout = new LinearLayout(this);
loadingLayout.addView(layout, mLayoutParams);
loadingLayout.setGravity(Gravity.CENTER);
//獲得一個ListView用來顯示條目
listView = getListView();
//加入到頁腳顯示
listView.addFooterView(loadingLayout);
//給ListView加入適配器
setListAdapter(adapter);
//給ListView註冊滾動監聽
listView.setOnScrollListener(this);
}
@Override
public void onScroll(AbsListView v, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
Log.i(TAG , "Scroll>>>first: " + firstVisibleItem + ", visible: " + visibleItemCount + ", total: " + totalItemCount);
lastItem = firstVisibleItem + visibleItemCount - 1;
Log.i(TAG , "Scroll>>>lastItem:" + lastItem);
//顯示50條ListItem,即0-49,因爲onScroll是在「滑動」運行過以後才觸發,因此用adapter.count<=41做條件
if (adapter.count<=41) {
if (firstVisibleItem+visibleItemCount==totalItemCount) {
adapter.count += 10;
adapter.notifyDataSetChanged();
listView.setSelection(lastItem);
int currentPage=adapter.count/10;
Toast.makeText(getApplicationContext(), "第"+currentPage+"頁", Toast.LENGTH_LONG).show();
}
}
else {
listView.removeFooterView(loadingLayout);
}
}
@Override
public void onScrollStateChanged(AbsListView v, int state) {
if (lastItem == adapter.count && state == OnScrollListener.SCROLL_STATE_IDLE) {
Log.i(TAG,"ScrollStateChanged>>>state:"+state+"lastItem:" + lastItem);
//顯示50條ListItem,即0-49,因爲onScrollStateChanged是在「拖動滑動」運行過以後才觸發,因此用adapter.count<=41做條件
if (adapter.count<=41) {
adapter.count += 10;
adapter.notifyDataSetChanged();
}
}
}
/**
* 要用用於生成顯示數據
* @author huangbq
*
*/
class listViewAdapter extends BaseAdapter {
int count = 10;
public int getCount() {
Log.i(TAG, "getCount>>>count:" + count);
return count;
}
public Object getItem(int pos) {
Log.i(TAG, "getItem>>>pos:" + pos);
return pos;
}
public long getItemId(int pos) {
Log.i(TAG, "getItemId>>>ItemId:" + pos);
return pos;
}
public View getView(int pos, View v, ViewGroup p) {
Log.i(TAG, "getView>>>pos:" + pos);
TextView view;
if (v==null) {
view = new TextView(MainActivity.this);
}
else {
view=(TextView)v;
}
view.setText("ListItem " + pos);
view.setTextSize(20f);
view.setGravity(Gravity.CENTER);
view.setHeight(60);
return view;
}
}
}
數據庫
demon下載:http://www.eoeandroid.com/forum.php?mod=viewthread&tid=52761json
方案四:api
這裏僅僅給出關鍵代碼,數據庫和adapter本身去寫吧,實現了listview的上下緩存。數據是從數據庫獲得的
public class HomeActivity extends Activity {
/** Called when the activity is first created. */
TextView mTextView;
ListView mListView;
MusicListViewAdapter mMusicListViewAdapter;
boolean isLoadingMusicData = false;
// 當前可以顯示的LinkedList數據集合
LinkedList<Music> nowMusicList;
// 每次查詢多少條數據
int pageSize = 15;
// 一共多少頁數據
long pageCount;
// 記錄查詢結果總數
long resultTotCount;
// 頂端緩存數據爲第幾頁
int topCachePageNumber;
// 底端緩存數據爲第幾頁
int bottomCachePageNumber;
// 頂端緩存未插入LinkedList數據--OnScrollListener事件改變
LinkedList<Music> cacheTopList;
// 底端緩存未插入LinkedList數據--OnScrollListener事件改變
LinkedList<Music> cacheBottomList;
// 是否可顯示到所有數據頂端
boolean isViewAllDataTop;
// 是否可顯示到所有數據底端
boolean isViewAllDataBottom;
// 是否已經緩存到所有數據頂端
boolean isCacheAllDataTop;
// 是否已經緩存到所有數據底端
boolean isCacheAllDataBottom;
// 可以顯示的頂端ItemView相應數據庫查詢結果第幾條
int topViewListToDbPosition;
// 可以顯示的底端ItemView相應數據庫查詢結果第幾條
int bottomViewListToDbPosition;
// 可以顯示的頂端ItemView相應數據庫查詢結果頁數
int topViewListToPagePosition;
// 可以顯示的底端ItemView相應數據庫查詢結果頁數
int bottomViewListToPagePosition;
// 頂端剩餘未顯示的ItemView--OnScrollListener事件改變
int topNoShowItemViewCount;
// 底端剩餘未顯示的ItemView--OnScrollListener事件改變
int bottomNoShowItemViewCount;
// 當前顯示的最頂端--OnScrollListener事件改變
int topItemViewPosition;
// 當前顯示的最底端--OnScrollListener事件改變
int bottomItemViewPosition;
// 重要!推斷向上滾動仍是向下滾動 --滾動前顯示的最頂端--OnScrollListener事件改變
int oldTopItemViewPosition = -1;
// 重要!推斷向上滾動仍是向下滾動 --滾動前顯示的最底端--OnScrollListener事件改變
int oldBottomItemViewPosition = -1;
// 記錄是滾動方向--OnScrollListener事件改變--事實上不需要在這裏定義
int isUpScroll = 0;
// 是否需要添加頂端緩存數據--OnScrollListener事件改變--事實上不需要在這裏定義
boolean needCacheTopList;
// 是否需要添加底端緩存數據--OnScrollListener事件改變--事實上不需要在這裏定義
boolean needCacheBottomList;
// 是否需要刪除頂端緩存數據--OnScrollListener事件改變--事實上不需要在這裏定義
boolean needDelCacheTopList;
// 是否需要刪除底端緩存數據--OnScrollListener事件改變--事實上不需要在這裏定義
boolean needDelCacheBottomList;
// 是否應該追加頂端ItemView--OnScrollListener事件改變--事實上不需要在這裏定義
boolean needAddTopItemView;
// 是否應該追加底端ItemView--OnScrollListener事件改變--事實上不需要在這裏定義
boolean needAddBottomItemView;
// 是否應該追加頂端ItemView--OnScrollListener事件改變--事實上不需要在這裏定義
boolean needDelTopItemView;
// 是否應該追加底端ItemView--OnScrollListener事件改變--事實上不需要在這裏定義
boolean needDelBottomItemView;
// 是否正在更新
boolean isUping = true;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// 得到符合查詢條件記錄的總數ResultSet totality
resultTotCount = MusicAppliction.mListViewUtil.getAllMusicCount();
// 依據每頁大小計算分頁數量
pageCount = resultTotCount / pageSize + 1;
// 連續取最初2頁數據並給nowMusicList賦值,用於初始化顯示
nowMusicList = MusicAppliction.mListViewUtil.getMusicListLimit(0,
pageSize * 2 - 1);
Log.i("getMusicListLimit", "size:" + nowMusicList.size());
// 設置當前可以顯示ItemView相應數據庫查詢結果
// 可以顯示的頂端ItemView相應數據庫查詢結果第幾條
topViewListToDbPosition = 0;
// 可以顯示的底端ItemView相應數據庫查詢結果第幾條
if (pageCount > 2) {
bottomViewListToDbPosition = pageSize * 2 - 1;
} else {
bottomViewListToDbPosition = nowMusicList.size() - 1;
}
// 是否可顯示到所有數據頂端
isViewAllDataTop = true;
// 是否可顯示到所有數據底端
if (pageCount <= 2) {
isViewAllDataBottom = true;
} else {
isViewAllDataBottom = false;
}
// 可以顯示的頂端ItemView相應數據庫查詢結果頁數
topViewListToPagePosition = 1;
// 可以顯示的底端ItemView相應數據庫查詢結果頁數
if (pageCount >= 2) {
bottomViewListToPagePosition = 2;
} else if (pageCount == 1) {
bottomViewListToPagePosition = 1;
}
// 是否已經緩存到所有數據頂端
isCacheAllDataTop = true;
// 是否已經緩存到所有數據底端
if (pageCount > 2) {
isCacheAllDataBottom = false;
} else {
isCacheAllDataBottom = true;
}
// 頂端緩存數據爲第幾頁
topCachePageNumber = -1;
// 底端緩存數據爲第幾頁
bottomCachePageNumber = -1;
// 頂端的緩存數據
cacheTopList = null;
// 底端的緩存數據
cacheBottomList = null;
// 找到顯示音樂的ListView
mListView = (ListView) findViewById(R.id.MusicListView);
// 建立Adapter給ListView顯示
mMusicListViewAdapter = new MusicListViewAdapter(this, nowMusicList);
// 組合Adapter和ListView
mListView.setAdapter(mMusicListViewAdapter);
mListView.setOnScrollListener(mOnScrollListener);
mListView.setFocusable(true);
mListView.forceLayout();
// 聲明初始化isUping完成
isUping = false;
}
public void initTestData() {
// 創建初始化數據庫和創建相關的表
// InitDataBaseTable繼承自線程
// 初始化後調用需要運行start()方法
InitDataBaseTable mInitDataBaseTable = new InitDataBaseTable(this);
// 運行一個線程,用來在後臺初始化數據庫和表
mInitDataBaseTable.start();
}
OnScrollListener mOnScrollListener = new OnScrollListener() {
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
if (isUping) {
return;
}
// 假設可以顯示所有數據頁則退出
if (topViewListToPagePosition == 1
&& pageCount == bottomViewListToPagePosition
&& firstVisibleItem == 0) {
return;
}
// ------計算並賦值
// 頂端剩餘未顯示的ItemView--OnScrollListener事件改變
topNoShowItemViewCount = firstVisibleItem;
// 底端剩餘未顯示的ItemView--OnScrollListener事件改變
bottomNoShowItemViewCount = totalItemCount - firstVisibleItem
- visibleItemCount;
// 當前顯示的最頂端--OnScrollListener事件改變
topItemViewPosition = firstVisibleItem;
// 當前顯示的最底端--OnScrollListener事件改變
bottomItemViewPosition = visibleItemCount + firstVisibleItem;
//剔除ListView刷新後的Item混亂
if (oldTopItemViewPosition + pageSize == topItemViewPosition) {
Log.i("testa", "oldTopItemViewPosition+pageSize");
oldTopItemViewPosition = topItemViewPosition;
// isUpScroll = 0;
return;
}
//剔除ListView刷新後的Item混亂
if (oldTopItemViewPosition == topItemViewPosition + pageSize) {
Log.i("testa", "topItemViewPosition+pageSize");
oldTopItemViewPosition = topItemViewPosition;
// isUpScroll = 0;
return;
}
//聲明正在更新
isUping = true;
// ------推斷是否需要添加或刪除頂端緩存Cache數據
// 推斷是滾動方向是否向下
if (oldTopItemViewPosition < topItemViewPosition
|| (oldTopItemViewPosition - pageSize == topItemViewPosition)) {
// 推斷是否需要刪除頂端多餘ItemView
// 同一時候更新頂端List緩存
// 同一時候更新各類位置標誌
//Log.i("inUpBottom", "bottomCachePageNumber:"+bottomCachePageNumber);
//推斷是否爲初始化的向下滾動
if (bottomCachePageNumber == -1) {
// 推斷是否有底端數據可以載入
if (pageCount > 2) {
bottomCachePageNumber = 1;
cacheBottomList = MusicAppliction.mListViewUtil
.getMusicListLimit(++bottomCachePageNumber
* pageSize, (bottomCachePageNumber + 1)
* pageSize - 1);
}
// 將底端cache的數據追增長nowMusicList
nowMusicList.addAll(cacheBottomList);
} else if (bottomNoShowItemViewCount < pageSize
) {
//不是初始化的向下滾動則進行略微複雜一點的計算
//推斷是否爲向上滾動後的向下滾動,防止中間丟失1頁
if(isUpScroll == 1){
--bottomCachePageNumber;
}
isUpScroll = 2;
//緩存一個底部頁
cacheBottomList = MusicAppliction.mListViewUtil
.getMusicListLimit(++bottomCachePageNumber
* pageSize, (bottomCachePageNumber + 1)
* pageSize - 1);
//將底部頁追加到列表
nowMusicList.addAll(cacheBottomList);
//推斷是否需要刪除頂部頁
if (topNoShowItemViewCount > pageSize) {
for (int i = 0; i < pageSize; i++) {
nowMusicList.removeFirst();
}
//更新頂部下次需要加載時的起始頁
++topCachePageNumber;
Log.i("topCachePageNumber", "++topCachePageNumber");
}
}
} else if (oldTopItemViewPosition > topItemViewPosition
|| (oldTopItemViewPosition == topItemViewPosition
- pageSize)) {
// 推斷是否需要刪除底端多餘ItemView
// 同一時候更新底端List緩存
// 同一時候更新各類位置標誌
// Log.i("inUpTop", "topCachePageNumber:" + topCachePageNumber);
//推斷是否頂部數據需要追加
if (topNoShowItemViewCount < pageSize) {
Log.i("inUpTop", "應該追加頂部");
if (topCachePageNumber >= 1) {
//防止向上滾動丟失一頁
if(isUpScroll == 2){
++topCachePageNumber;
}
//標示現在是向上滾動
isUpScroll = 1;
//取得需要追加的頂部數據
cacheTopList = MusicAppliction.mListViewUtil
.getMusicListLimit(--topCachePageNumber
* pageSize, (topCachePageNumber + 1)
* pageSize - 1);
//倒序增長東部數據
for (int i = cacheTopList.size(); i > 0; i--) {
nowMusicList.add(0, cacheTopList.get(i - 1));
}
}
}
//更新底部數據
if (bottomNoShowItemViewCount > pageSize*2) {
//刪除多餘的底部數據
for (int i = 0; i < pageSize; i++) {
nowMusicList.removeLast();
}
//標示現在是向上滾動
isUpScroll = 1;
//改動下次追加底部數據的起始頁
//當底部緩存頁面小於2的時候將再也不下降
if(bottomCachePageNumber>2){
--bottomCachePageNumber;
}
Log.i("MybottomCachePageNumber", "bottomCachePageNumber:"+bottomCachePageNumber);
}
}
// Log.i("OnScrollListener", "--oldTopItemViewPosition:"
// + oldTopItemViewPosition + "--topItemViewPosition:"
// + topItemViewPosition);
oldTopItemViewPosition = topItemViewPosition;
mMusicListViewAdapter.notifyDataSetChanged();
isUping = false;
}
};
}
緩存
方案五:網絡
ListView是Android中最爲常用的列表類型控件,ListView中的選擇項目中樣式很是多有的是純文字的、有的還可以帶有圖片。它的繼承關係例如如下:
java.lang.Object
android.view.View
android.view.ViewGroup
android.widget.AdapterView<T extends android.widget.Adapter>
android.widget.AbsListView
android.widget.ListView
android.widget.ListView繼承了android.view.ViewGroup。
首先看一個純文本的ListView樣例,案例執行後會出現一個城市列表如圖6-8所看到的,選擇某個城市,彈出一個Toast,關於Toast的概念和使用會在下一節中介紹。
程序代碼請參考代碼
chapter6_3/src/com/work/ListView_1_Activity.java
public class ListView_1_Activity extends Activity {
private ListView listview;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.listview_activity);
listview = (ListView)findViewById(R.id.ListView01);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1, mStrings);
listview.setAdapter(adapter);
listview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View v, int pos,
long id) {
Toast.makeText(ListView_1_Activity.this, mStrings[pos],
Toast.LENGTH_SHORT).show();
}
});
}
private String[] mStrings = {
"北京市", "天津市", "上海", "重慶", "烏魯木齊", …};
}
對 於ArrayAdapter應該已經很是熟悉了,當中的android.R.layout.simple_list_item_1是使用系統的佈局樣式。 Android系統自己提供了很是多的這種佈局文件,但是有的適合於ListView控件,有的適合於Spinner控件,有的適合於它的列表控件,這是 使用時需要注意的。
在這樣的方式下,需要在佈局文件listview_activity。xml中加入ListView控件:
<ListView android:id="@+id/ListView01" android:layout_width="wrap_content"
android:layout_height="wrap_content"></ListView>
由 於ListView在Android中是非常常常使用的列表類型控件,僅僅要是有多條信息需要顯示的時候都可以考慮使用ListView展現出來,正是由於 ListView使用的廣泛,因此Android又提供了一個列表類型的Activity——ListActivity,來簡化ListView開發。
經過繼承ListActivity類而實現一個簡單的ListView功能,而不要直接使用ListView控件。相同上面案例假設使用ListActivity請參考代碼清單:
chapter6_3/src/com/work/ListView_1.java
public class ListView_1 extends ListActivity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setListAdapter(new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1, mStrings));
getListView().setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View v, int pos,
long id) {
Toast.makeText(ListView_1.this, mStrings[pos],
Toast.LENGTH_SHORT).show();
}
});
}
private String[] mStrings = {
"北京市", "天津市", "上海", "重慶", "烏魯木齊", …};
}
查 看代碼不難發現這裏沒有使用佈局文件,那就意味着不需要使用R文件來得到控件,因此在程序中使用了getListView()方法來得到ListView 控件。處理ListView的項目點擊事件有兩種方法,一種是經過與ListView對象設置setOnItemClickListener方式實現,代 碼例如如下:
getListView().setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View v, int pos,
long id) {
Toast.makeText(ListView_1.this, mStrings[pos],
Toast.LENGTH_SHORT).show();
}
});
第二種是覆蓋ListActivity的onListItemClick(ListView l, View v, int position, long id)方法實現,代碼例如如下所看到的。
@Override
protected void onListItemClick(ListView l, View v, int position, long id) {
Toast.makeText(ListView_1.this, mStrings[position], Toast.LENGTH_SHORT)
。show();
}
再看一個本身定義Adapter的樣例,這是一個帶有圖標的ListView,
本身定義adapter
相關程序代碼請參考代碼清單:
chapter6_3/src/com/work/ListViewIcon_3.java
public class ListViewIcon_3 extends ListActivity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setListAdapter(new EfficientAdapter(this));
}
private static final String[] DATA = {
"北京市", "天津市", "上海", "重慶", "哈爾濱",
"石家莊", "秦皇島", "濟南", "青島", "南京",
"三亞", "昆明", "成都", "長沙", "武漢",
"九江", "香港", "澳門","蘭州","張家口" };
…
}
本身定義的Adapter是EfficientAdapter,EfficientAdapter的相關代碼請參考代碼清單:
chapter6_3/src/com/work/ListViewIcon_3.java
private static class EfficientAdapter extends BaseAdapter {
private LayoutInflater mInflater;
private Bitmap mIcon0;
private Bitmap mIcon1;
… …
public EfficientAdapter(Context context) {
mInflater = LayoutInflater.from(context);
mIcon0 = BitmapFactory.decodeResource(context.getResources(), R.drawable.noicon);
mIcon1 = BitmapFactory.decodeResource(context.getResources(), R.drawable.beijing);
… …
}
public int getCount() {
return DATA.length;
}
public Object getItem(int position) {
return DATA[position];
}
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
convertView = mInflater。inflate(R.layout.main, null);
holder = new ViewHolder();
holder.text = (TextView) convertView.findViewById(R.id.textview);
holder.icon = (ImageView) convertView.findViewById(R.id.icon);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.text.setText(DATA[position]);
switch(position)
{
case 0:
holder.icon.setImageBitmap(mIcon1);
break;
case 1:
holder.icon.setImageBitmap(mIcon2);
break;
…
default:
holder.icon.setImageBitmap(mIcon0);
break;
}
return convertView;
}
static class ViewHolder {
TextView text;
ImageView icon;
}
}
編寫本身定義Adapter可以繼承BaseAdapter類,假設是數據庫使用可以繼承CursorAdapter。在本例中繼承了BaseAdapter類,BaseAdapter是一個抽象類,必須在它的子類中實現如下的方法:
int getCount() 返回總數據源中總的記錄數;
Object getItem(int position) 依據選擇的項目的位置,得到選擇的數據源中某個項目的數據;
long getItemId(int position) 依據選擇的項目的位置;
View getView(int position, View convertView, ViewGroup parent) 得到要展現的項目View對象。
這 裏最爲麻煩的方法就是getView(),getView()方法是ListView的每個列表項目繪製在屏幕上時被調用。該方法當中的一個參數是 convertView,在ListView第一次顯示列表項目的時候,convertView是null值。當向上滑動屏幕時候,屏幕上面的列表項目退 出屏幕,屏幕如下原來不可見的列表項目會進入屏幕,這個時候的convertView不是null值,如下代碼的處理對於提供ListView控件提升性 能是相當重要的。
if (convertView == null) {
convertView = mInflater.inflate(R.layout.main, null);
holder = new ViewHolder();
holder.text = (TextView) convertView
.findViewById(R.id.textview);
holder.icon = (ImageView) convertView.findViewById(R.id.icon);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
僅僅 有在convertView爲null時纔去實例化控件,建立convertView對象、holder對象,當中convertView對象是經過 mInflater。inflate(R.layout.main, null)方法,從一個main.xml佈局文件裏載入並建立的。
而在convertView非null的時候不會實例化控件,不然每次都要實例化控件,當列表項目很是多時,用戶重複滑動屏幕會有「卡」的感受,再也不流暢了。
ViewHolder 類是將每一個項目中的控件封裝起來的類,可以在convertView 爲null時候建立ViewHolder類的實例holder,而後經過convertView.setTag(holder);把它放到 convertView中,而在convertView非null時候,再經過convertView.getTag()過的一個ViewHolder類 的實例,這樣在翻屏的時候就不會重複建立ViewHolder實例對象了,就本例而言僅僅是建立了9個ViewHolder實例。
app
方案六:AsyncTask, json;
代碼介紹:
初學android,寫了個一小demo。功能很是easy,主要是用來學習,
知識要點:
1.android全局變量的使用(用來緩存爬取的數據)。
2.AsyncTask使用。
3.進度條載入數據
4.利用Jsoup爬取網頁數據並解析
demon:http://www.eoeandroid.com/forum.php?mod=viewthread&tid=172517
方案七:下拉載入
http://www.eoeandroid.com/forum.php?mod=viewthread&tid=172777