編輯:關於android開發
大家都知道listview的格式是一定的 而數據源確是多重多樣的 這時候 就需要一種適配器來把數據源轉換成listview要顯示的格式
baseAdapter就誕生了。
listview和gridView的顯示和緩存機制 如下圖
大家都知道屏幕的大小是有限的 可是listview中的數據卻可能很多 所以手機不能一下子展示所有的數據 它只會加載屏幕上顯示的數據 。
如上圖,當我們把屏幕往下滑動時 item1回收到recycler 而item8要顯示在屏幕上 item8從recycler取出這樣一個布局文件 並重新設置好item8要顯示的數據 並設置要要顯示的位置。總之一句話 需要才顯示 顯示完就被回收到緩存。
至於題目為何說BaseAdapter的三重境界(逗比式,普通式,文藝式) 區別在哪裡那?就在如何運用listview的顯示和緩存機制
在listview的適配器上 有這樣一個方法
@Override public View getView(int position, View convertView, ViewGroup parent) { // TODO Auto-generated method stub return null; }
下面我們通過一個實例 來比較adapter的三重境界孰強孰弱
要實現的效果如下
activity_main.xml
<linearlayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical"> <listview android:id="@+id/lv_listView" android:layout_width="match_parent" android:layout_height="match_parent"></listview> </linearlayout>
<!--{cke_protected}{C}%3C!%2D%2D%3Fxml%20version%3D%221.0%22%20encoding%3D%22utf-8%22%3F%2D%2D%3E--> <relativelayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <imageview android:id="@+id/iv_image" android:layout_width="50dp" android:layout_height="50dp" android:layout_alignparentleft="true" android:src="@drawable/ic_launcher"> <textview android:id="@+id/tv_nickName" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_torightof="@id/iv_image" android:gravity="center_horizontal" android:textsize="20sp" android:text="昵稱"> <textview android:id="@+id/tv_content" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_torightof="@id/iv_image" android:layout_below="@id/tv_nickName" android:textsize="15sp" android:text="內容"> </textview></textview></imageview></relativelayout>
MyObject.class
package com.example.baseadapter; import android.widget.ImageView; import android.widget.TextView; public class MyObject { private int imageViewId; private String nickName; private String content; public MyObject(int imageViewId, String nickName, String content) { this.imageViewId = imageViewId; this.nickName = nickName; this.content = content; } public String getNickName() { return nickName; } public String getContent() { return content; } public int getImageViewId() { return imageViewId; } }
package com.example.baseadapter; import java.util.ArrayList; import java.util.List; import android.os.Bundle; import android.app.Activity; import android.view.Menu; import android.widget.ListView; public class MainActivity extends Activity { private Listlist=new ArrayList (); private ListView listView; private MyAdapter myAdapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); listView=(ListView) findViewById(R.id.lv_listView); for(int i=0;i<50;i++){ list.add(new MyObject(R.drawable.ic_launcher, "昵稱"+i, "內容"+i)); } myAdapter=new MyAdapter(list, this); listView.setAdapter(myAdapter); } }
MyAdapter.class
package com.example.baseadapter; import java.util.List; import android.content.Context; import android.util.Log; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.ImageView; import android.widget.TextView; public class MyAdapter extends BaseAdapter { private long sum = 0; private Listlist; private Context context; public MyAdapter(List list, Context context) { this.list = list; this.context = context; } @Override public int getCount() { // TODO Auto-generated method stub return list.size(); } @Override public Object getItem(int position) { // TODO Auto-generated method stub return list.get(position); } @Override public long getItemId(int position) { // TODO Auto-generated method stub return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { // TODO Auto-generated method stub // 逗比式 long star = System.nanoTime(); View view=View.inflate(context, R.layout.item, null); ImageView imageView =(ImageView) view.findViewById(R.id.iv_image); TextView nickName=(TextView) view.findViewById(R.id.tv_nickName); TextView content=(TextView) view.findViewById(R.id.tv_content); MyObject myObject=list.get(position); imageView.setBackgroundResource(myObject.getImageViewId()); nickName.setText(myObject.getNickName()); content.setText(myObject.getContent()); long end = System.nanoTime(); sum += end - star; Log.d("main", "逗比式" + sum); return view; // 普通式 // long star = System.nanoTime();//獲取系統納秒時間 // if (convertView == null) { // convertView = View.inflate(context, R.layout.item, null); // } // ImageView imageView = (ImageView) convertView // .findViewById(R.id.iv_image); // TextView nickName = (TextView) convertView // .findViewById(R.id.tv_nickName); // TextView content = (TextView) convertView.findViewById(R.id.tv_content); // MyObject myObject = list.get(position); // imageView.setBackgroundResource(myObject.getImageViewId()); // nickName.setText(myObject.getNickName()); // content.setText(myObject.getContent()); // long end = System.nanoTime(); // sum += end - star; // Log.d("main", "普通式" + sum); // return convertView; // 文藝式 // long star = System.nanoTime(); // ViewHolder viewHolder; // if (convertView == null) { // viewHolder=new ViewHolder(); // convertView = View.inflate(context, R.layout.item, null); // viewHolder.imageView = (ImageView) convertView // .findViewById(R.id.iv_image); // viewHolder.nickName = (TextView) convertView // .findViewById(R.id.tv_nickName); // viewHolder.content = (TextView) convertView // .findViewById(R.id.tv_content); // //通過setTag方式 使viewHolder和convertView綁定在一起 // convertView.setTag(viewHolder); // } // viewHolder=(ViewHolder) convertView.getTag(); // MyObject myObject = list.get(position); // viewHolder.imageView.setBackgroundResource(myObject.getImageViewId()); // viewHolder.nickName.setText(myObject.getNickName()); // viewHolder.content.setText(myObject.getContent()); // long end = System.nanoTime(); // sum += end - star; // Log.d("main", "文藝式"+sum); // return convertView; } // 避免重復的findViewById class ViewHolder { public ImageView imageView; private TextView nickName; private TextView content; } }
下面我們分析一下第一種為什麼叫逗比式
前面已經說了,liseview具有緩存機制 可以將使用過的item放入緩沖池中,而在這裡 每次調用getview方法的時候 我們都是創建新的view對象 並沒有利用listview的緩存機制
沒有任何處理 ,效率及其低下,所以我們稱它為逗比式
而第二種 普通式是利用了getview方法中傳入的contentview對象 並且加一個if判斷
if (convertView == null) { convertView = View.inflate(context, R.layout.item, null); }雖然只是一個if判斷 但是通過這個判斷 可以避免創建大量的contentview對象 節省了大量的時間 利用了ListView的緩存特性 如果沒有緩存才創建新的view 對getview方法進行了非常好的優化 但這僅僅只算入門,因為findViewById依然會浪費大量的時間 所以我們稱這種方法為普通式
那麼第三種境界 文藝式 就是對findViewById的優化了 把findViewById 也放入if判斷語句中 就ok了
我們需要創建一個內部類 裡面有三個成員變量 都是我們item.xml文件中的三個控件
class ViewHolder { public ImageView imageView; private TextView nickName; private TextView content; }通過viewHolder.setTag()方法 把viewHolder和contentView關聯在一起 然後通過getTag方法得到viewHolder
這種方法不僅利用了listview的緩存,更通過viewHolder來實現顯示視圖的緩存,避免多次使用findViewById方法
作為一個有情懷的程序員 這才是最文藝的寫法~
大家可能看到了我代碼中輸出的log日志 下面我附上結果 大家比較一下 這裡listview中只有50條數據 全部是滑倒底部
至此BaseAdapter的三重境界(逗比式,普通式,文藝式)孰強孰弱 一目了然~(如果有出入 請你把listview中的數據設置多一些)
Menu創建菜單,menu創建 菜單是用戶界面中最常見的元素之一,使用非常頻繁,在And
說明一下JNI 與AIDL,說明JNIAIDL代碼在評論中。 JNI: 為什麼需要JNI: 因為android是由【JAVA & C/C++】組成。Java運行在
Android手機相冊的布局,android相冊布局實現類似下面的這種布局的方法
Android操作系統中集成了一個嵌入式關系型數據庫SQLite,我們在進行A