Android中ListView控件的使用android
ListView展現數據的原理web
在Android中,其實ListView就至關於web中的jsp,Adapter是適配器,它就至關於web中的Servlet,緩存
適配器的做用app
Adapter的做用就是把數據展現在Listview中jsp
使用ListView的奇怪問題?ide
在使用ListView的時候,若是把ListView的高設置爲wrap_content,它會反覆讀取屢次數據,而後在ListView中把數據顯示出來,效率很是低,,這時候咱們應該把ListView的高設置爲match_parent,這樣就能很好的解決讀取屢次再顯示數據的問題了,由於ListView的高寫成wrap_content,那麼它的高不肯定的,須要作屢次的校驗,確認數據是否能徹底顯示出來。佈局
下面咱們經過案例說明這個問題優化
當ListViewf控件的高度設置爲wrap_content時,就會出現如下問題,以下圖:ui
圖1 圖2this
咱們能夠看到手機屏幕圖1中最多可以顯示31條數據,可是圖2中很明顯看到當加載完31條記錄時,緊接着又從0開始加載這31條記錄,其實後面還加載了好幾回,在這裏就不一一截圖出來了,那麼如何解決呢?其實只須要修改一下ListView控件的高就能夠了,把ListView控件中的高設置爲match_parent
可是還要注意一點,當是引入佈局的時候,咱們也須要設置它的父元素的高爲match_parent
也就是說,父元素和引入佈局的ListView都須要設置爲match_parent
ListView控件的父子關係關係也是同樣
解決了讀取屢次數據問題後,咱們來看看如下代碼,而後運行看看結果是怎樣的?
1 import android.app.Activity; 2 import android.os.Bundle; 3 import android.view.View; 4 import android.view.ViewGroup; 5 import android.widget.BaseAdapter; 6 import android.widget.ListView; 7 import android.widget.TextView; 8
9
10 public class MainActivity extends Activity { 11
12 @Override 13 protected void onCreate(Bundle savedInstanceState) { 14 super.onCreate(savedInstanceState); 15 setContentView(R.layout.weixin); 16
17 //獲取所需控件
18 ListView ll = (ListView) findViewById(R.id.listView1); 19
20 //使用適配器
21 ll.setAdapter(new MyAdapter()); 22
23 } 24
25 //定義一個適配器
26 private class MyAdapter extends BaseAdapter{ 27
28 //返回條目數
29 @Override 30 public int getCount() { 31 return 10000; 32 } 33
34 @Override 35 public Object getItem(int position) { 36
37 return null; 38 } 39
40 @Override 41 public long getItemId(int position) { 42
43 return 0; 44 } 45
46 /**
47 * 獲取一個view,用來顯示listView的數據,會做爲listView的一個條目顯示 48 * 49 * position : 對應getCount()返回的索引 50 * convertView : 緩存數據的對象 51 */
52 @Override 53 public View getView(int position, View convertView, ViewGroup parent) { 54
55 /**
56 * 若是convertView是null,那麼說明沒有緩存,那麼咱們就建立TextView對象 57 */
58 TextView tv = tv = new TextView(MainActivity.this); 59 System.out.println("建立新的View"+position); 60
62 tv.setText("呵呵"+position); 63 return tv; 64 } 65
66 } 67 }
運行結果:
咱們從結果能夠看到,每次都是建立了一個新的對象,這樣效率很是低,那麼咱們下面進行ListView的優化
ListView的優化策略
1 package com.example.uicustomviews; 2
3 import android.app.Activity; 4 import android.os.Bundle; 5 import android.view.View; 6 import android.view.ViewGroup; 7 import android.widget.BaseAdapter; 8 import android.widget.ListView; 9 import android.widget.TextView; 10
11
12 public class MainActivity extends Activity { 13
14 @Override 15 protected void onCreate(Bundle savedInstanceState) { 16 super.onCreate(savedInstanceState); 17 setContentView(R.layout.weixin); 18
19 //獲取所需控件
20 ListView ll = (ListView) findViewById(R.id.listView1); 21
22 //使用適配器
23 ll.setAdapter(new MyAdapter()); 24
25 } 26
27 //定義一個適配器
28 private class MyAdapter extends BaseAdapter{ 29
30 //返回條目數
31 @Override 32 public int getCount() { 33 return 10000; 34 } 35
36 @Override 37 public Object getItem(int position) { 38
39 return null; 40 } 41
42 @Override 43 public long getItemId(int position) { 44
45 return 0; 46 } 47
48 /**
49 * 獲取一個view,用來顯示listView的數據,會做爲listView的一個條目顯示 50 * 51 * position : 對應getCount()返回的索引 52 * convertView : 緩存數據的對象 53 */
54 @Override 55 public View getView(int position, View convertView, ViewGroup parent) { 56
57 TextView tv = null; 58
59 /**
60 * 若是convertView是null,那麼說明沒有緩存,那麼咱們就建立TextView對象 61 */
62 if(convertView==null){ 63 System.out.println("建立新的View"+position); 64 tv = new TextView(MainActivity.this); 65 }else{ 66 /**
67 * 不然就是有緩存,爲了提升效率,那麼咱們就使用緩存中對象,不須要再次new了 68 */
69 tv = (TextView) convertView ; 70 System.out.println("使用緩存的View"+position); 71 } 72
73 tv.setText("呵呵"+position); 74 return tv; 75 } 76
77 } 78 }
運行結果以下圖:
顯然提升了效率,再也不建立新的View,而是使用了緩存中的View
下面咱們把一個佈局文件轉爲一個View(ListView中的一個條目)
1 package com.example.uicustomviews; 2
3 import android.app.Activity; 4 import android.os.Bundle; 5 import android.view.LayoutInflater; 6 import android.view.View; 7 import android.view.ViewGroup; 8 import android.widget.BaseAdapter; 9 import android.widget.ListView; 10
11
12
13 public class MainActivity extends Activity { 14
15 @Override 16 protected void onCreate(Bundle savedInstanceState) { 17 super.onCreate(savedInstanceState); 18 setContentView(R.layout.weixin); 19
20 //獲取所需控件
21 ListView ll = (ListView) findViewById(R.id.listView1); 22
23 //使用適配器
24 ll.setAdapter(new MyAdapter()); 25
26 } 27
28 //定義一個適配器
29 private class MyAdapter extends BaseAdapter{ 30
31 //返回條目數
32 @Override 33 public int getCount() { 34 return 10000; 35 } 36
37 @Override 38 public Object getItem(int position) { 39
40 return null; 41 } 42
43 @Override 44 public long getItemId(int position) { 45
46 return 0; 47 } 48
49 /**
50 * 獲取一個view,用來顯示listView的數據,會做爲listView的一個條目顯示 51 * 52 * position : 對應getCount()返回的索引 53 * convertView : 緩存數據的對象 54 */
55 @Override 56 public View getView(int position, View convertView, ViewGroup parent) { 57
58 /**
59 * 能夠插入廣告 60 */
61
62 View view = null; 63
64 /**
65 * 若是convertView是null,那麼說明沒有緩存,那麼咱們就建立TextView對象 66 */
67 if(convertView==null){ 68 //System.out.println("建立新的View"+position); 69 //建立一個新的View對象,能夠經過打氣筒把一個佈局資源轉換成一個View對象 70 //resource就是咱們定義好的佈局文件
71 //方式一 72 //view = View.inflate(MainActivity.this, R.layout.weixin_item, null); 73
74 //方式二 75 //view = LayoutInflater.from(getApplicationContext()).inflate(R.layout.weixin_item, null); 76
77 //方式三
78 LayoutInflater inflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE); 79
80 view = inflater.inflate(R.layout.weixin_item, null); 81 }else{ 82 /**
83 * 不然就是有緩存,爲了提升效率,那麼咱們就使用緩存中對象,不須要再次new了 84 */
85 view = convertView ; 86 //System.out.println("使用緩存的View"+position);
87 } 88
90 return view; 91 } 92
93 } 94 }