所謂高級控件就是指不能拖過來直接用的控件,咱們須要在對它們進行管理和控制以後才能使用,與之一塊兒使用的還有一些對應的控制器、相關數據集等。這一篇裏咱們先簡單介紹一下高級控件中的AdapterView控件,固然咱們也須要先要知道與之對應的控制器——適配器Adapter,以及數據源DataSource,和三者之間的關係。
java
咱們都應該聽過或者瞭解MVC框架吧,MVC全名是Model View Controller,是模型(model)-視圖(view)-控制器(controller)的縮寫,一種軟件設計典範,用於組織代碼用一種業務邏輯和數據顯示分離的方法,這個方法的假設前提是若是業務邏輯被彙集到一個部件裏面,並且界面和用戶圍繞數據的交互能被改進和個性化定製而不須要從新編寫業務邏輯MVC被獨特的發展起來用於映射傳統的輸入、處理和輸出功能在一個邏輯的圖形化用戶界面的結構中。MVC的結構圖以下:android
到此爲止,咱們已經明白了這個框架的原理,簡單的來講就是利用控制器(C)將數據集(M)與視圖(V)對應起來。好吧,咱們用這個思想說說Adapter、AdapterView和DataSource之間的關係:
app
Adapter——C(控制器)框架
AdapterView——V(視圖)less
DataSource——M(數據集)ide
明白了這個關係,咱們就能夠進入今天的主講內容了:佈局
(1)Adapter類及其相關類和接口;
測試
(2)AdapterView控件之一ListView;this
1.ArrayAdapter類的使用spa
經過ArrayAdapter咱們只能綁定數據到TextView控件中,其餘的很少說,直接看下面的代碼,注意的地方我都標記了註釋:
(1)MainActivity.java
package com.example.arrayadapter; import android.app.Activity; import android.os.Bundle; import android.widget.ArrayAdapter; import android.widget.ListView; public class MainActivity extends Activity { //聲明視圖ListView控件 private ListView lv; //聲明適配器(控制器)ArrayAdapter private ArrayAdapter<String> aAdapter; //聲明並定義數據源 private String datas[]={ "Wireless & networks","Call settings","Sound","Display","Location & security", "Applications","Accounts & sync","Privacy","CD card & phone storage","Search","Language & keyboard", "Voice input & output","Accessibility","Date & Time","About phone"}; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //實現適配器,包括三個參數 aAdapter=new ArrayAdapter<String>(this, R.layout.cell,datas); lv=(ListView)findViewById(R.id.listView1); //經過Adapter的setAdapter方法綁定數據於視圖 lv.setAdapter(aAdapter); } }
(2)activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#000000" tools:context=".MainActivity" > <ListView android:id="@+id/listView1" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_weight="1" > </ListView> </LinearLayout>
(3)引入的資源文件cell.xml
<?xml version="1.0" encoding="utf-8"?> <TextView xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="50dip" android:gravity="center_vertical" android:id="@+id/tv" android:textColor="#ffffff"></TextView>
(4)實現效果以下:
2.SimpleAdapter類的使用
相對於ArrayAdapter而言SimpleAdapter的實現的功能更全面一些,不只可也實現TextView的綁定,還能夠在引用的資源文件(cell.xml)中使用佈局,從而綁定ImageView等其餘一些控件,接下來咱們就來完善上面這個佈局:
(1)MainActivity.java
package com.example.arrayadapter; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import android.app.Activity; import android.os.Bundle; import android.widget.ListView; import android.widget.SimpleAdapter; public class MainActivity extends Activity { //聲明視圖ListView控件 private ListView lv; //聲明適配器(控制器)SimpleAdapter private SimpleAdapter sAdapter; //聲明List和Map存放數據 private List<Map<String,Object>> lists; private Map<String ,Object> maps; //聲明並定義數據源 private String datas[]={ "Wireless & networks","Call settings","Sound","Display","Location & security", "Applications","Accounts & sync","Privacy","CD card & phone storage","Search", "Language & keyboard","Voice input & output","Accessibility","Date & Time","About phone"}; private int p_w_picpath[]={ R.drawable.ic_settings_wireless,R.drawable.ic_settings_call,R.drawable.ic_settings_sound, R.drawable.ic_settings_display,R.drawable.ic_settings_location,R.drawable.ic_settings_applications, R.drawable.ic_settings_sync,R.drawable.ic_bt_config,R.drawable.ic_settings_sim, R.drawable.ic_power_system,R.drawable.ic_settings_language,R.drawable.ic_settings_voice_calls, R.drawable.ic_settings_accessibility,R.drawable.ic_settings_date_time,R.drawable.ic_settings_about}; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); lv=(ListView)findViewById(R.id.listView1); lists=new ArrayList<Map<String,Object>>(); //經過for循環添加數據 for(int i=0;i<p_w_picpath.length;i++){ maps=new HashMap<String,Object>(); maps.put("data", datas[i]); maps.put("p_w_picpath", p_w_picpath[i]); lists.add(maps); } //實現SimpleAdapter適配器,有5個參數 sAdapter=new SimpleAdapter(this, lists, R.layout.cell, new String[]{"data","p_w_picpath"}, new int[]{R.id.tv,R.id.iv}); //經過Adapter的setAdapter方法綁定數據於視圖 lv.setAdapter(sAdapter); } }
(2)activity_main.java同上
(3)資源文件cell.java
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="horizontal" tools:context=".MainActivity" > <ImageView android:layout_width="50dip" android:layout_height="50dip" android:id="@+id/iv"/> <TextView android:layout_width="fill_parent" android:layout_height="50dip" android:gravity="center_vertical" android:id="@+id/tv" android:textColor="#ffffff"></TextView> </LinearLayout>
(4)測試結果圖:
3.自定義的Adapter——BaseAdapter的使用:
若是系統提供的適配器不能知足開發人員的要求,咱們也能夠經過BaseAdapter來自定義知足須要的適配器,這裏爲了說明狀況咱們就用BaseAdapter自定義的適配器(下面咱們叫MyAdapter)來完成和上面相同的功能。
(1)MyAdapter.java(新建的類,實現自定義的適配器)
package myAdapter; import android.content.Context; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.TextView; import com.example.arrayadapter.R; public class MyAdapter extends BaseAdapter{ private Context context; private String data[]; private int p_w_picpath[]; public MyAdapter(Context context,String[] data,int[] p_w_picpath){ this.context=context; this.data=data; this.p_w_picpath=p_w_picpath; } //重寫一下四個方法,並修改返回值 @Override public int getCount() { return this.data.length; } @Override public Object getItem(int position) { return data[position]; } @Override public long getItemId(int position) { return position; } //這個重寫的方法是最重要的,用於加載視圖 @Override public View getView(int position, View convertView, ViewGroup parent) { LayoutInflater lif=(LayoutInflater) context.getSystemService(context.LAYOUT_INFLATER_SERVICE); LinearLayout layout=(LinearLayout) lif.inflate(R.layout.cell, null); TextView tv=(TextView)layout.findViewById(R.id.tv); ImageView iv=(ImageView)layout.findViewById(R.id.iv); tv.setText(data[position]); iv.setBackgroundResource(p_w_picpath[position]); return layout; } }
(2)MainActivity.java
package com.example.arrayadapter; import myAdapter.MyAdapter; import android.app.Activity; import android.os.Bundle; import android.widget.ListView; public class MainActivity extends Activity { //聲明視圖ListView控件 private ListView lv; //聲明適配器(控制器)MyAdapter private MyAdapter mAdapter; //聲明並定義數據源 private String datas[]={ "Wireless & networks","Call settings","Sound","Display","Location & security", "Applications","Accounts & sync","Privacy","CD card & phone storage","Search", "Language & keyboard","Voice input & output","Accessibility","Date & Time","About phone"}; private int p_w_picpath[]={ R.drawable.ic_settings_wireless,R.drawable.ic_settings_call,R.drawable.ic_settings_sound, R.drawable.ic_settings_display,R.drawable.ic_settings_location,R.drawable.ic_settings_applications, R.drawable.ic_settings_sync,R.drawable.ic_bt_config,R.drawable.ic_settings_sim, R.drawable.ic_power_system,R.drawable.ic_settings_language,R.drawable.ic_settings_voice_calls, R.drawable.ic_settings_accessibility,R.drawable.ic_settings_date_time,R.drawable.ic_settings_about}; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); lv=(ListView)findViewById(R.id.listView1); //實現MyAdapter適配器 mAdapter=new MyAdapter(this,datas,p_w_picpath); //經過Adapter的setAdapter方法綁定數據於視圖 lv.setAdapter(mAdapter); } }
(3)運行效果:
(4)最後補充一個問題——ListView的緩衝
讓咱們來看一下MyAdapter.java代碼:
public View getView(int position, View convertView, ViewGroup parent) { ViewHolder holder; if (convertView == null) { convertView = LayoutInflater.from(context). inflate(R.layout.cell,null); holder = new ViewHolder(); holder.tv = (TextView) convertView.findViewById(R.id.tv); holder.iv = (ImageView) convertView.findViewById(R.id.iv); convertView.setTag(holder); } else { holder = (ViewHolder) convertView.getTag(); } holder.tv.setText(data[position]); holder.iv.setBackgroundResource(p_w_picpath[position]); return convertView; } private static class ViewHolder { TextView tv; ImageView iv; }