安卓Listview和Adapter資料設計
ListView是一種用於垂直顯示的列表控制元件,如果顯示內容過多,則會自動出現垂直滾動條,每一行是一個View物件,在每一行上可以放置任何元件,Adapter介面卡是資料和UI的橋樑,為資料顯示提供了統一的封裝。
常用的Adapter有:
ArrayAdapter<T>:用來繫結一個數組,支援泛型操作,最為簡單,只能展示一行字。
SimpleAdapter:用來繫結在佈局xml中定義的控制元件對應的資料,有好的擴充性,可以自定義出各種效果
BaseAdapter:是一個抽象類,繼承它需要實現較多的方法,所以也就具有較高的靈活性
ArrayAdapter的使用:
該類的構造方法為:public ArrayAdapter(Context context, int textViewResourceId, List<T> objects)其中引數1為上下文;引數2為佈局檔案,通常使用系統提供的單文字佈局(android.R.layout.simple_list_item_1);引數3為資料,通常為List集合或者陣列。
1、簡單的一個列表實現:
佈局檔案:
1 <ListView 2 android:layout_width="match_parent" 3android:id="@+id/main_list" 4 android:layout_height="match_parent"> 5 </ListView>
資料新增和適配:
1 //新建一個list存放資料 2 List<String> listdata=new ArrayList<String>(); 3 listdata.add("東小東1"); 4 listdata.add("東小東2"); 5 listdata.add("東小東3");6 listdata.add("叮叮噹噹"); 7 listdata.add("咚咚咚嘻嘻嘻"); 8 9 //列表 10 main_list=(ListView)findViewById(R.id.main_list); 11 //android.R.layout.simple_list_item_1不可改成自定義佈局檔案 12 final ArrayAdapter<String> adp2=new ArrayAdapter<String>(MainActivity.this,android.R.layout.simple_list_item_1,listdata); 13 main_list.setAdapter(adp2);
listview的事件監聽:
1 //點選事件 2 main_list.setOnItemClickListener(new AdapterView.OnItemClickListener() { 3 @Override 4 public void onItemClick(AdapterView<?> parent, View view, int position, long id) { 5 6 Toast.makeText(MainActivity.this,"你點選了:"+position+"項 內容為:"+adp2.getItem(position),Toast.LENGTH_SHORT).show(); 7 8 } 9 }); 10 11 //長按事件 12 main_list.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() { 13 @Override 14 public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) { 15 16 Toast.makeText(MainActivity.this,"你長按了:"+position+"項 內容為:"+adp2.getItem(position),Toast.LENGTH_SHORT).show(); 17 18 return true; 19 } 20 });
2、下拉選擇欄實現和輸入匹配:
佈局檔案:
1 <Spinner 2 android:layout_width="match_parent" 3 android:layout_height="wrap_content" 4 android:id="@+id/main_spinner" 5 > 6 7 </Spinner> 8 9 <!--completionThreshold="1" 表示從第一個字元開始匹配 --> 10 <AutoCompleteTextView 11 android:id="@+id/main_autotv" 12 android:layout_width="match_parent" 13 android:layout_height="wrap_content" 14 android:hint="在這裡輸入會自動提示" 15 android:completionThreshold="1" /> 16 17 <Button 18 android:layout_width="match_parent" 19 android:text="點.." 20 android:id="@+id/main_but" 21 android:layout_height="wrap_content" /> 22 23 <TextView 24 android:layout_width="wrap_content" 25 android:text="請點選按鈕" 26 android:id="@+id/main_tv" 27 android:layout_gravity="center" 28 android:layout_height="wrap_content" />
簡單邏輯實現:
1 /配置一個公用的陣列做測試 2 //arrayadapter實現字串適配 3 String[] str_arr={"東小東","東東","大東東","叮叮噹噹"}; 4 5 //選擇框 6 main_sp=(Spinner)findViewById(R.id.main_spinner); 7 ArrayAdapter<String> adp=new ArrayAdapter<String>(MainActivity.this,android.R.layout.simple_spinner_item,str_arr); 8 adp.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); 9 main_sp.setAdapter(adp); 10 11 //輸入提示 12 main_atv=(AutoCompleteTextView)findViewById(R.id.main_autotv); 13 ArrayAdapter<String> adp2=new ArrayAdapter<String>(MainActivity.this,android.R.layout.simple_list_item_1,str_arr); 14 main_atv.setAdapter(adp2); 15 16 //按鈕監聽,獲取兩個框的值 17 findViewById(R.id.main_but).setOnClickListener(new View.OnClickListener() { 18 @Override 19 public void onClick(View v) { 20 String strsp=main_sp.getSelectedItem().toString().trim(); 21 String stratv=main_atv.getText().toString().trim(); 22 main_tv.setText(strsp+"\n"+stratv); 23 24 25 } 26 });
SimpleAdapter的使用:
該類的構造方法為:public SimpleAdapter(Context context, List<? Extends Map<String, ?>> data, int resource, String[] from, int[] to)其中引數1為上下文;引數2為資料,一個Map的list,List裡每一項都是map物件,一個map物件就表示listview中一行的內容;引數3為布布局資源,可以知己寫也可以使用系統提供的;引數4為map裡的鍵,其對應著引數5中佈局資源的每一個顯示控制元件id。
建立listview中每一個item的基本佈局:
新建一個xml檔案即可
主佈局檔案:
1 <ListView 2 android:layout_width="match_parent" 3 android:id="@+id/main_list" 4 android:layout_height="match_parent"> 5 </ListView>
資料設定和適配及listview事件監聽:
1 String str_con="一秒就成為了下一秒的過去,既然很多東西註定要失去的,那麼,我們唯一可以做到的就是不輕易忘記。“讀過一句話,當你總是緬懷過去的時候,證明你現在過的並不好。所以,美好的回憶可以,但絕不留戀。要永遠憧憬,永遠在現在努力。"; 2 3 //新建一個list存放資料 4 List<Map<String,Object>> listdata=new ArrayList<Map<String,Object>>(); 5 6 //第一行內容 7 Map<String,Object> mapdata=new HashMap<String, Object>(); 8 mapdata.put("img",R.mipmap.zcy1); 9 mapdata.put("title","東小東1"); 10 mapdata.put("context","1: "+str_con); 11 listdata.add(mapdata); 12 13 //第二行內容 14 mapdata=new HashMap<String, Object>(); 15 mapdata.put("img",R.mipmap.zcy2); 16 mapdata.put("title","東小東2"); 17 mapdata.put("context","2: "+str_con); 18 listdata.add(mapdata); 19 20 //第三行內容 21 mapdata=new HashMap<String, Object>(); 22 mapdata.put("img",R.mipmap.zcy3); 23 mapdata.put("title","東小東3"); 24 mapdata.put("context","3: "+str_con); 25 listdata.add(mapdata); 26 27 28 //鍵和顯示控制元件的id必須一一對應 29 String[] key_data={"img","title","context"}; 30 int[] res_data={R.id.dong_img,R.id.dong_title,R.id.dong_context}; 31 32 //列表 33 main_list=(ListView)findViewById(R.id.main_list); 34 final SimpleAdapter adp2=new SimpleAdapter(MainActivity.this,listdata,R.layout.dong,key_data,res_data); 35 main_list.setAdapter(adp2); 36 37 //長按事件 38 main_list.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() { 39 @Override 40 public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) { 41 42 //方法1------------------------------ 43 // Map<String, Object> mMap = (Map<String, Object>) adp2.getItem(position); 44 45 //得到標題 46 // String title=mMap.get("title").toString(); 47 //得到內容 48 // String cont=mMap.get("context").toString(); 49 50 //得到圖片資源 51 // int img=(int)mMap.get("img"); 52 53 //方法2----------------------------- 54 HashMap<String,String> map=(HashMap<String,String>)parent.getItemAtPosition(position); 55 //得到標題 56 String title=map.get("title"); 57 //得到內容 58 String cont=map.get("context"); 59 60 Toast.makeText(MainActivity.this,"\n你長按了第:"+position+"項\n標題為:"+title+"\n內容為:"+cont,Toast.LENGTH_SHORT).show(); 61 62 return true; 63 } 64 });
BaseAdapt使用:
相比前面兩個,其baseadapt使用較為複雜,但實現的功能較多,對複雜介面資料顯示能力強,是學習listview資料適配的重點。baseadapt是一個抽象類,繼承它需要實現較多的方法,所以也就具有較高的靈活性。
建立listview中每一個item的基本佈局:
新建一個xml檔案即可
建立一個存放資料的類,並實現其Get和Set方法:
1 class BaseData{ 2 //分別為標題和內容 3 private String title,text; 4 //圖片資源 5 private int img; 6 7 public String getTitle() { 8 return title; 9 } 10 11 public void setTitle(String title) { 12 this.title = title; 13 } 14 15 public String getText() { 16 return text; 17 } 18 19 public void setText(String text) { 20 this.text = text; 21 } 22 23 public int getImg() { 24 return img; 25 } 26 27 public void setImg(int img) { 28 this.img = img; 29 } 30 }
設定資料:
1 String str_con="一秒就成為了下一秒的過去,既然很多東西註定要失去的,那麼,我們唯一可以做到的就是不輕易忘記。“讀過一句話,當你總是緬懷過去的時候,證明你現在過的並不好。所以,美好的回憶可以,但絕不留戀。要永遠憧憬,永遠在現在努力。"; 2 3 List<BaseData> listdatax=new ArrayList<>(); 4 BaseData bd=new BaseData(); 5 bd.setImg(R.mipmap.zcy1); 6 bd.setTitle("東小東111"); 7 bd.setText("111"+str_con); 8 listdatax.add(bd); 9 10 bd=new BaseData(); 11 bd.setImg(R.mipmap.zcy2); 12 bd.setTitle("東小東222"); 13 bd.setText("222"+str_con); 14 listdatax.add(bd); 15 16 bd=new BaseData(); 17 bd.setImg(R.mipmap.zcy3); 18 bd.setTitle("東小東333"); 19 bd.setText("333"+str_con); 20 listdatax.add(bd);
viewholder快取設計:
通過ViewHolder快取convertView,這種利用快取contentView的方式可以判斷如果快取中不存在View才建立View,如果已經存在可以利用快取中的View,提升了效能 。 ViewHolder只是將需要快取的那些view封裝好。
1 private static class mViewHolder{ 2 TextView htext,htitle; 3 ImageView himg; 4 5 }
介面卡類:
1 //介面卡類 2 public class MyBaseAdapter extends BaseAdapter { 3 4 private List<BaseData> listdatax2; 5 //建構函式,獲取到資料列表 6 public MyBaseAdapter(List<BaseData> datex){ 7 this.listdatax2=datex; 8 } 9 10 @Override 11 public int getCount() {//總條數 12 return listdatax2.size(); 13 } 14 @Override 15 public Object getItem(int position) {//根據一個索引(位置)獲得該位置的物件 16 return listdatax2.get(position); 17 } 18 @Override 19 public long getItemId(int position) {//獲取條目的id 20 return 0; 21 } 22 @Override 23 public View getView(int position, View convertView, ViewGroup parent) {//獲取該條目要顯示的介面 24 mViewHolder holder = null; 25 26 if (convertView == null) { 27 //無快取時進入 28 holder = new mViewHolder(); 29 //這裡要注意有一個是上下文,一個是顯示每一行的行佈局檔案 30 convertView=MainActivity.this.getLayoutInflater().inflate(R.layout.dong,parent,false); 31 32 holder.htitle = (TextView) convertView.findViewById(R.id.dong_title); 33 holder.htext= (TextView) convertView.findViewById(R.id.dong_context); 34 holder.himg = (ImageView) convertView.findViewById(R.id.dong_img); 35 convertView.setTag(holder); 36 }else { 37 //快取時進入 38 holder = (mViewHolder) convertView.getTag(); 39 } 40 //匹配資料 41 holder.htitle.setText(listdatax2.get(position).getTitle()); 42 holder.htext.setText(listdatax2.get(position).getText()); 43 holder.himg.setImageResource(listdatax2.get(position).getImg()); 44 45 /* 46 lilayoutx.p1tx.setOnClickListener(new View.OnClickListener() { 47 @Override 48 public void onClick(View v) { 49 iteminterx.onclick(position); 50 } 51 }); 52 53 */ 54 return convertView; 55 } 56 }
結果顯示及事件監聽:
1 //新建介面卡物件 2 final MyBaseAdapter myadapterx=new MyBaseAdapter(listdatax); 3 //列表 4 main_list=(ListView)findViewById(R.id.main_list); 5 //設定介面卡 6 main_list.setAdapter(myadapterx); 7 //新增點選事件 8 main_list.setOnItemClickListener(new AdapterView.OnItemClickListener() { 9 @Override 10 public void onItemClick(AdapterView<?> parent, View view, int position, long id) { 11 //使用物件方法獲取 12 BaseData itemx; 13 itemx = (BaseData) myadapterx.getItem(position); 14 int img=itemx.getImg(); 15 16 //可自接通過此處改變控制元件上的某個圖片顯示 17 //圖片顯示控制元件,main_img=(ImageView)findViewById(R.id.main_img); 18 main_img.setImageResource(img); 19 20 //資料輸出 21 Toast.makeText(MainActivity.this,position + " *** " + itemx.getTitle() + " " + img,Toast.LENGTH_SHORT).show(); 22 } 23 });
下一步將整理出基本的詳細內容展示頁編寫和ListView下拉重新整理實現