一、ListView 如何提升其效率?android
當 convertView 爲空時,用 setTag()方法爲每一個 View 綁定一個存放控件的ViewHolder 對象。 當 convertView 不爲空, 重複利用已經建立的 view 的時候,面試
使用 getTag()方法獲取綁定的 ViewHolder 對象,這樣就避免了 findViewById,緩存
對控件的層層查詢,而是快速定位到控件。服務器
① 複用 ConvertView,使用歷史的 view,提高效率 200%
② 自定義靜態類 ViewHolder,減小 findViewById 的次數。提
升效率 50%
③ 異步加載數據,分頁加載數據。
④ 使用 WeakRefrence 引用 ImageView 對象網絡
二、當 ListView 數據集改變後,如何更新 ListView?多線程
使用該 ListView 的 adapter 的 notifyDataSetChanged()方法,該方法會使 ListView 從新繪製。異步
三、ListView 如何實現分頁加載ide
① 設 置 ListView 的 滾 動 監 聽 器 : setOnScrollListener(new OnScrollListener{….})佈局
在 監 聽 器 中 有 兩 個 方 法 : 滾 動 狀 態 發 生 變 化 的 方 法(onScrollStateChanged)和 listView 被滾動時調用的方法(onScroll),優化
② 在滾動狀態發生改變的方法中,有三種狀態:
手指按下移動的狀態: SCROLL_STATE_TOUCH_SCROLL: // 觸摸滑動
慣性滾動(滑翔(flgin)狀態): SCROLL_STATE_FLING: // 滑翔
靜止狀態: SCROLL_STATE_IDLE: // 靜止
對不一樣的狀態進行處理:
分批加載數據,只關心靜止狀態:關心最後一個可見的條目,若是最後一個可見條目就是數據適配器(集合)裏的最後一個,此時可加載更多的數據。在每
次加載的時候,計算出滾動的數量,當滾動的數量大於等於總數量的時候,能夠提示用戶無更多數據了。
四、ListView 能夠顯示多種類型的條目嗎?
這個固然能夠的,ListView 顯示的每一個條目都是經過 baseAdapter 的getView(int position, View convertView, ViewGroup parent)來展現的,理論
上咱們徹底可讓每一個條目都是不一樣類型的 view。 除 此 之 外 adapter 還 提 供 了 getViewTypeCount ( ) 和getItemViewType(int position)兩個方法。
在 getView 方法中咱們能夠根據不一樣的 viewtype 加載不一樣的佈局文件
五、ListView 如何定位到指定位置?
能夠經過 ListView 提供的 lv.setSelection(listView.getPosition());方法。
六、如何在 ScrollView 中如何嵌入 ListView?
一般狀況下咱們不會在 ScrollView 中嵌套 ListView,可是若是面試官非讓咱們嵌套的話也是能夠的。
在 ScrollView 添加一個 ListView 會致使 listview 控件顯示不全,一般只會顯示一條,這是由於兩個控件的滾動事件衝突致使。 因此須要經過 listview 中的
item 數量去計算 listview 的顯示高度,從而使其完整展現,以下提供一個方法供你們參考。
lv = (ListView) findViewById(R.id.lv);
adapter = new MyAdapter();
lv.setAdapter(adapter);
setListViewHeightBasedOnChildren(lv);
----------------------------------------------------
public void setListViewHeightBasedOnChildren(ListView listView) {
ListAdapter listAdapter = listView.getAdapter();
if (listAdapter == null) {
return;
}
int totalHeight = 0;
for (int i = 0; i < listAdapter.getCount(); i++) {
View listItem = listAdapter.getView(i, null, listView);
listItem.measure(0, 0);
totalHeight += listItem.getMeasuredHeight();
}
ViewGroup.LayoutParams params = listView.getLayoutParams();
params.height = totalHeight + (listView.getDividerHeight() *
(listAdapter.getCount() - 1));
params.height += 5;
// if without this statement,the listview will be a
// little short
listView.setLayoutParams(params);
}
現階段最好的處理的方式是: 自定義 ListView,重載 onMeasure()方法,設置所有顯示。代碼以下:
package com.meiya.ui;
import android.widget.ListView;
public class ScrollViewWithListView extends ListView {
public ScrollViewWithListView(android.content.Context context,
android.util.AttributeSet attrs) {
super(context, attrs);
}
/**
* Integer.MAX_VALUE >> 2,若是不設置,系統默認設置是顯示兩條
*/
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2,
MeasureSpec.AT_MOST);
super.onMeasure(widthMeasureSpec, expandSpec);
}
}
七、ListView 中如何優化圖片
圖片的優化策略比較多。
一、處理圖片的方式:
若是 ListView 中自定義的 Item 中有涉及到大量圖片的, 必定要對圖片進行細心的處理,由於圖片佔的內存是 ListView 項中最頭疼的,處理圖片的方法
大體有如下幾種:
①、不要直接拿路徑就去循環 BitmapFactory.decodeFile;使用 Options 保存圖片大小、不要加載圖片到內存去。
②、對圖片必定要通過邊界壓縮尤爲是比較大的圖片,若是你的圖片是後臺服務器處理好的那就不須要了
③、在 ListView 中取圖片時也不要直接拿個路徑去取圖片,而是以WeakReference ( 使 用 WeakReference 代 替 強 引 用 。 比 如 可 以 使 用
WeakReference mContextRef)、SoftReference、WeakHashMap 等的來存儲圖片信息。
④、在 getView 中作圖片轉換時,產生的中間變量必定及時釋放
二、異步加載圖片基本思想:
1)、 先從內存緩存中獲取圖片顯示(內存緩衝)
2)、獲取不到的話從 SD 卡里獲取(SD 卡緩衝)
3)、都獲取不到的話從網絡下載圖片並保存到 SD 卡同時加入內存並顯示
(視狀況看是否要顯示)
原理:
優化一:先從內存中加載,沒有則開啓線程從 SD 卡或網絡中獲取,這裏注意從 SD 卡獲取圖片是放在子線程裏執行的,不然快速滑屏的話會不夠流暢。
優化二:於此同時,在 adapter 裏有個 busy 變量,表示 listview 是否處於滑動狀態,若是是滑動狀態則僅從內存中獲取圖片,沒有的話無需再開啓線程去
外存或網絡獲取圖片。
優化三:ImageLoader 裏的線程使用了線程池,從而避免了過多線程頻繁建立和銷燬,若是每次老是 new 一個線程去執行這是很是不可取的,好一點的
用的 AsyncTask 類,其實內部也是用到了線程池。在從網絡獲取圖片時,先是將其保存到 sd 卡,而後再加載到內存,這麼作的好處是在加載到
內存時能夠作個壓縮處理,以減小圖片所佔內存。
八、ListView 中圖片錯位的問題是如何產生的
圖片錯位問題的本質源於咱們的 listview 使用了緩存 convertView, 假設一種場景,一個 listview 一屏顯示九個 item,那麼在拉出第十個 item 的時候,
事實上該 item 是重複使用了第一個 item,也就是說在第一個 item 從網絡中下載圖片並最終要顯示的時候,其實該 item 已經不在當前顯示區域內了,此時顯示
的後果將可能在第十個 item 上輸出圖像,這就致使了圖片錯位的問題。因此解決之道在於可見則顯示,不可見則不顯示。
九、如何刷新 ListView 中單個 item 的數據,不刷新整個ListView 的數據?
修改單個 Item 的數據,而後調用適配器的 notifyDataSetChanged()方法