Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android的Adapter用法總結

Android的Adapter用法總結

編輯:關於Android編程

Android之Adapter用法總結

1.Adapter概念

定義為將一個類的接口變換成客戶端所期待的一種接口,從而使原本因接口不匹配而無法在一起工作的兩個類能夠在一起工作。 在android中我們可以這麼看, Adapter是連接後端數據和前端顯示的適配器接口,是數據和UI(View)之間一個重要的紐帶。在常見的View(List View,Grid View)等地方都需要用到Adapter。如下圖直觀的表達了Data、Adapter、View三者的關系:
\
Android中所有的Adapter一覽:
\

由圖可以看到在Android中與Adapter有關的所有接口、類的完整層級圖。在我們使用過程中可以根據自己的需求實現接口或者繼承類進行一定的擴展。比較常用的有 Base Adapter,Impleader,Adapter,Counteradaptation等。

 

  • BaseAdapter是一個抽象類,繼承它需要實現較多的方法,所以也就具有較高的靈活性;
  • ArrayAdapter支持泛型操作,最為簡單,只能展示一行字。
  • SimpleAdapter有最好的擴充性,可以自定義出各種效果。
  • SimpleCursorAdapter可以適用於簡單的純文字型ListView,它需要Cursor的字段和UI的id對應起來。如需要實現更復雜的UI也可以重寫其他方法。可以認為是SimpleAdapter對數據庫的簡單結合,可以方便地把數據庫的內容以列表的形式展示出來。

    2.舉例說明

    1)ArrayAdapter

    列表的顯示需要三個元素:

    a.ListVeiw : 用來展示列表的View。

    b.適配器 : 用來把數據映射到ListView上的中介。

    c.數據 : 具體的將被映射的字符串,圖片,或者基本組件。

    例一:

     

    public class ArrayAdapterActivity extends ListActivity {
         @Override
         public void onCreate(Bundle savedInstanceState) {
             super.onCreate(savedInstanceState);
             //列表項的數據
             String[] strs = {"情景模式1","情景模式2","情景模式3","情景模式4",
    "情景模式5","情景模式6","情景模式7","情景模式8","情景模式9"};
    ArrayAdapter adapter = new ArrayAdapter(this,android.R.layout.simple_expandable_list_item_1,strs); setListAdapter(adapter); } }
    
    

     

     

    例二:

     

    public class MyListView extends Activity {
        
            private ListView listView;
            @Override
            public void onCreate(Bundle savedInstanceState){
                super.onCreate(savedInstanceState);
                 
                listView = new ListView(this);
                listView.setAdapter(new ArrayAdapter(this, android.R.layout.simple_expandable_list_item_1,getData()));
                setContentView(listView);
            }
             
            private List getData(){
                 
                List data = new ArrayList();
                data.add("情景模式");
                data.add("情景模式");
                data.add("情景模式");
                data.add("情景模式");
                data.add("情景模式");
                data.add("情景模式");
                data.add("情景模式");
                data.add("情景模式");
                data.add("情景模式");
    return data; } }
    
    上面代碼使用了Adapter(Context context, int resourcefulness, List objects)來裝配數據,要裝配這些數據就需要一個連接List View視圖對象和數組數據的適配器來兩者的適配工作,Adapter的構造需要三個參數,依次為(this)布局文件(注意這裡的布局文件描述的是列表的每一行的布局,android.R.layout.simple_list_item_1是系統定義好的布局文件只顯示一行文字,數據源(一個List集合)。同時用adapter()完成適配的最後工作。效果圖如下:
    

     

    \

     

     

    2)SimpleAdapter

      simpleAdapter的擴展性最好,可以定義各種各樣的布局出來,可以放上ImageView(圖片),還可以放上Button(按鈕),CheckBox(復選框)等等。下面的代碼都直接繼承了ListActivity,ListActivity和普通的Activity沒有太大的差別,不同就是對顯示ListView做了許多優化,方面顯示而已。

    實現帶圖標的ListView

     

    1.在main.xmlzhong添加一個id為listView1的LisView組件.

     

    
    
       
    
    

    2.新建一個布局文件items.xml(水平布局)

     

    添加一個ImageView組件和TextView組件。

     

    
    
    
        
        
    
    
    3.在主Activity的onCreate()方法中個,首先獲取布局文件中添加的ListView,然後創建兩個用於保存列表項的圖片id和文字的數組,並將這件圖片id和文字添加到List集合中,在創建一個SimpleAdapter簡答適配器,最後將該適配器與ListView關聯,具體代碼如下:

     

     

    @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            ListView listView=(ListView)findViewById(R.id.listView1);      //獲取列表視圖
            int[] imageId=new int[]{R.drawable.img01,R.drawable.img02,R.drawable.img03,
                    R.drawable.img04,R.drawable.img05,R.drawable.img06,R.drawable.img07,
                    R.drawable.img08};                        //定義初始化保存圖片id的數組
            String[] title=new String[]{"aaa","bbb","ccc","ddd","eee","fff","ggg",
                    "iii"};                               //定義初始化保存列表項文字的數組
            List> listItems=new ArrayList>();//創建一個二維List數組
            for(int i=0;i map=new Hashtable();
                map.put("image",imageId[i]);                   //實例化map對象
                map.put("title",title[i]);
                listItems.add(map);                      //將map對象添加到List集合中
            }
    
            SimpleAdapter adapter=new SimpleAdapter(this,listItems,R.layout.items,
                    new String[] {"title","image"},new int[]{R.id.title,R.id.image});//創建SimpleAdapter
            listView.setAdapter(adapter);                        //將適配器與ListView關聯
        }
    
    運行效果圖:
    \


     

    說明:SimpleAdapter類的構造方法SimpleAdapter(Context context,List>data,int resource,String[] from,int[] to)中 參數context用於指定關聯SimpleAdapter運行的視圖上下文; 參數data用於指定一個基於Map的列表,該列表中的每個條目對應列表中的一行; 參數inresource用於指定一個用於定義列表項目的視圖布局文件的唯一表識(新建的items); 參數from用於指定一個將被添加到Map上關聯每一個項目的列名稱的數組; 參數to用於指定一個與參數from顯示列對應的視圖id的數組。

    3)SimpleCursorAdapter

    public class SimpleCursorAdapterActivity extends ListActivity {
         @Override
         public void onCreate(Bundle savedInstanceState) {
             super.onCreate(savedInstanceState);
             //獲得一個指向系統通訊錄數據庫的Cursor對象獲得數據來源
             Cursor cur = getContentResolver().query(People.CONTENT_URI, null, null, null, null);
             startManagingCursor(cur);
             //實例化列表適配器
             
             ListAdapter adapter = new SimpleCursorAdapter(this, android.R.layout.simple_list_item_1, cur, new String[] {People.NAME}, new int[] {android.R.id.text1});
             setListAdapter(adapter);
         }
     }
    
    一定要以數據庫作為數據源的時候,才能使用SimpleCursorAdapter,這裡特別需要注意的一點是:不要忘了在AndroidManifest.xml文件中加入權限

    4)BaseAdapter

    有時候,列表不光會用來做顯示用,我們同樣可以在在上面添加按鈕。添加按鈕首先要寫一個有按鈕的xml文件,然後自然會想到用上面的方法定義一個適配器,然後將數據映射到布局文件上。但是事實並非這樣,因為按鈕是無法映射的,即使你成功的用布局文件顯示出了按鈕也無法添加按鈕的響應,這時就要研究一下ListView是如何現實的了,而且必須要重寫一個類繼承BaseAdapter。下面的示例將顯示一個按鈕和一個圖片,兩行字如果單擊按鈕將刪除此按鈕的所在行。並告訴你ListView究竟是如何工作的。
    
    
        
        
            
            
        

     public class MyListView4 extends ListActivity {
         
         
           private List> mData;
            
            @Override
            public void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
                mData = getData();
                MyAdapter adapter = new MyAdapter(this);
                setListAdapter(adapter);
            }
         
            private List> getData() {
                List> list = new ArrayList>();
         
                Map map = new HashMap();
                map.put("title", "G1");
                map.put("info", "google 1");
                map.put("img", R.drawable.i1);
                list.add(map);
         
                map = new HashMap();
                map.put("title", "G2");
                map.put("info", "google 2");
                map.put("img", R.drawable.i2);
               list.add(map);
         
                map = new HashMap();
                map.put("title", "G3");
                map.put("info", "google 3");
                map.put("img", R.drawable.i3);
                list.add(map);
                 
                return list;
            }
             
            // ListView 中某項被選中後的邏輯
            @Override
           protected void onListItemClick(ListView l, View v, int position, long id) {
                 
                Log.v("MyListView4-click", (String)mData.get(position).get("title"));
            }
             
            /**
             * listview中點擊按鍵彈出對話框
             */
            public void showInfo(){
                new AlertDialog.Builder(this)
                .setTitle("我的listview")
                .setMessage("介紹...")
                .setPositiveButton("確定", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                    }
                })
                .show();
                 
            }
             /** 當Listie有大量的數據需要加載的時候,會占據大量內存,影響性能,這時候   就需要按需填充並重新使用view來減少對象的創建
              *最快的方式是定義一個Pewholder,將convex的tag設置為Pewholder,不為空時重新使用即可
              */
            public final class ViewHolder{
                public ImageView img;
                public TextView title;
                public TextView info;
                public Button viewBtn;
            }
             
             
            public class MyAdapter extends BaseAdapter{
         
                private LayoutInflater mInflater;
                 
                 
                public MyAdapter(Context context){
                    this.mInflater = LayoutInflater.from(context);
                }
                @Override
                public int getCount() {
                    // TODO Auto-generated method stub
                    return mData.size();
                }
         
                @Override
                public Object getItem(int arg0) {
                    // TODO Auto-generated method stub
                    return null;
                }
         
                @Override
                public long getItemId(int arg0) {
                    // TODO Auto-generated method stub
                    return 0;
                }
         
                @Override www.2cto.com
                public View getView(int position, View convertView, ViewGroup parent) {
                     
                    ViewHolder holder = null;
                    if (convertView == null) {
                         
                        holder=new ViewHolder(); 
                         
                        convertView = mInflater.inflate(R.layout.vlist2, null);
                        holder.img = (ImageView)convertView.findViewById(R.id.img);
                        holder.title = (TextView)convertView.findViewById(R.id.title);
                        holder.info = (TextView)convertView.findViewById(R.id.info);
                        holder.viewBtn = (Button)convertView.findViewById(R.id.view_btn);
                        convertView.setTag(holder);
                         
                    }else {
                         
                        holder = (ViewHolder)convertView.getTag();
                    }
                     
                     
                    holder.img.setBackgroundResource((Integer)mData.get(position).get("img"));
                    holder.title.setText((String)mData.get(position).get("title"));
                    holder.info.setText((String)mData.get(position).get("info"));
                     
                    holder.viewBtn.setOnClickListener(new View.OnClickListener() {
                         
                        @Override
                        public void onClick(View v) {
                            showInfo();                
                        }                });
                     
                     
                   return convertView;
               }
                 
           }     
        }
    
    下面將對上述代碼,做詳細的解釋,listView在開始繪制的時候,系統首先調用getCount()函數,根據他的返回值得到listView的長度,然後根據這個長度,調用getView()逐一繪制每一行。如果你的getCount()返回值是0的話,列表將不顯示同樣return 1,就只顯示一行。
    
      系統顯示列表時,首先實例化一個適配器(這裡將實例化自定義的適配器)。當手動完成適配時,必須手動映射數據,這需要重寫getView()方法。系統在繪制列表的每一行的時候將調用此方法。getView()有三個參數,position表示將顯示的是第幾行,covertView是從布局文件中inflate來的布局。我們用LayoutInflater的方法將定義好的vlist2.xml文件提取成View實例用來顯示。然後將xml文件中的各個組件實例化(簡單的findViewById()方法)。這樣便可以將數據對應到各個組件上了。但是按鈕為了響應點擊事件,需要為它添加點擊監聽器,這樣就能捕獲點擊事件。至此一個自定義的listView就完成了,現在讓我們回過頭從新審視這個過程。系統要繪制ListView了,他首先獲得要繪制的這個列表的長度,然後開始繪制第一行,怎麼繪制呢?調用getView()函數。在這個函數裡面首先獲得一個View(實際上是一個ViewGroup),然後再實例並設置各個組件,顯示之。好了,繪制完這一行了。那再繪制下一行,直到繪完為止。在實際的運行過程中會發現listView的每一行沒有焦點了,這是因為Button搶奪了listView的焦點,只要布局文件中將Button設置為沒有焦點就OK了。




     

     



  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved