編輯:關於Android編程
對於ListVie來說,數據項的設置有很多種方式,而自定義實現BaseAdapter是最經常用的了,那麼這裡我們來講解一下自定義實現BaseAdapter的普通實現。
MainActivity.java
public class MainActivity extends AppCompatActivity { //數據源 private List<String> data; //ListView控件 private ListView mList; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //獲取控件ID mList = (ListView)findViewById(R.id.mList); data = new ArrayList<>(); //數據賦初值 for(int i = 0; i < 20; i ++){ data.add("數據項"+ i); } //創建適配器 MyAdapter adapter = new MyAdapter(data); //設置適配器 mList.setAdapter(adapter); } }
MyAdapter.java
public class MyAdapter extends BaseAdapter { //數據項 private List<String> data; public MyAdapter(List<String> data) { this.data = data; } @Override /** * 返回數據源的長度,表示ListView的item項顯示多少個 */ public int getCount() { return data == null ? 0 : data.size(); } /** * 返回指定位置的 item 數據源的對象,這個方法為手動調用,非設置適配器時候調用 * @param position 指定位置 * @return */ @Override public Object getItem(int position) { return data.get(position); } /** * 返回指定位置的 item的標記 id,很少使用到 * @param position 指定位置 * @return */ @Override public long getItemId(int position) { return position; } /** * 工廠方法,設置好模板,返回視圖,每個視圖是怎麼顯示出來的, 核心點,怎麼產生一個View, View 裡面怎麼 * 放置對應的內容 * @param position 當前加載的位置 * @param convertView 復用的view * @param parent listview * @return */ @Override public View getView(int position, View convertView, ViewGroup parent) { //獲取布局 View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item,null); //獲取布局中的TextView控件1 TextView tv1 = (TextView) view.findViewById(R.id.mTv1); //設置控件1的數據 tv1.setText(data.get(position)); //獲取布局中的TextView控件2 TextView tv2 = (TextView) view.findViewById(R.id.mTv2); //設置控件2數據 tv2.setText(data.get(position)); return view; } }
以上是普通的使用,但是這樣的效率會非常低,因為每次加載一個item都會調用getView方法,而每次都會去解析一個view布局,這樣一直解析會對內存的消耗特別大,所以效率會大大降低,那麼我們在此基礎上先稍微優化下,讓view解析次數變少一點,最基本的操作就是采用convertView復用控件來進行操作。
這裡只需要修改getView方法中的處理:
@Override public View getView(int position, View convertView, ViewGroup parent) { Log.i("TAG", "getView: " + position); if (convertView == null) { convertView = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item, null); } TextView tv1 = (TextView) convertView.findViewById(R.id.mTv1); tv1.setText(data.get(position)); TextView tv2 = (TextView) convertView.findViewById(R.id.mTv2); tv2.setText(data.get(position)); return convertView; } }
以上的處理方式相比上面的處理方式相對於上面的解析要少很多次,因為第一種實現方式是任何一個需要顯示的控件都需要去解析一次布局,而這裡我們使用了系統給的converView復用控件,他的基本原理是,系統會自動創建好界面顯示n個item的數據項(比如一個界面可見的item為5個,默認創建好了5個view布局對象),保存到converView中(這裡可以把他當成一個循環數組吧,他的總容量相當於是n + 1),當顯示第n + 1個的時候,他會解析一次,之後的顯示的view布局會復用自己的converView中已經存在的布局項,而不再去重新解析。簡單的畫個圖吧:
如上圖所示,相當於只解析了6次,其他的view都是復用的,所以相對於上面的實現,這樣的效率會相對高一點,不過,雖然解析的次數是少了,但是每個控件需要findViewById還是會重復調用,而且其實每個不同對象view中的控件id對象肯定是相同的,所以,重復的去調用又會顯得效率不高,那麼如何解決不重復findViewById呢,那就要使用到我們的優化布局了,關於優化,將在下一篇博客中介紹。
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持本站。
目錄:1.SeekBar的應用場景2.SeekBar的簡單使用與事件監聽3.圖片資源自定義SeekBar+手機音量調節4.xml繪制自定義SeekBar1.SeekBar
由於研究生畢業項目需要完成一個基於移動終端的場景文字識別系統,雖然離畢業尚早,但出於興趣的緣故,近一段抽時間完成了這樣一套系統。基本的架構如下: 客戶端:
原因一:Activity的啟動模式那麼Activity以哪種啟動模式進行跳轉時,會導致目標Activity獲取不到傳遞過來的數據呢?在上一篇博客中講到Activity以不
SwipeBackLayout其實github上已經有這個開源庫了,我是個菜鳥,我喜歡用開源庫,同時也非常好奇它的實現原理。很多大神寫的代碼注釋都特別少,可能是他們覺得很