适配器(Adapter)

适配器(Adapter)

1.概念

Adapter是连接后端数据和前端显示的适配器接口,是数据和UI(View)之间一个重要的纽带。在常见的 View(ListView,GridView)等地方都需要用到Adapter。如下图直观的表达了Data、Adapter、View三者的关系:

Adapter.png

在我们使用过程中可以根据自己的需求实现接口或者继承类进行一定的 扩展。比较常用的有 BaseAdapter,SimpleAdapter,ArrayAdapter等。

  • BaseAdapter是一个抽象类,继承它需要实现较多的方法,所以也就具有较高的灵活性;
  • ArrayAdapter支持泛型操作,最为简单,只能展示一行字。
  • SimpleAdapter有最好的扩充性,可以自定义出各种效果。

2.应用案例

1.ArrayAdapter

列表的显示需要三个元素:

  • a.ListVeiw 用来展示列表的View。
  • b.适配器 用来把数据映射到ListView上的中介。
  • c.数据 具体的将被映射的字符串,图片,或者基本组件。
 ListView lv=new ListView(this);
 lv=(ListView) findViewById(R.id.lv);
 //1.准备数据
 String[] strs = {"1","2","3","4","5"};
 //2.设置适配器
 ArrayAdapter<String> adapter = new ArrayAdapter<String>(
                this,
                android.R.layout.simple_expandable_list_item_1,
                strs);
 //3.
 lv.setAdapter(adapter);

2. SimpleAdapter

simpleAdapter的扩展性最好,可以定义各种各样的布局出来,可以放上ImageView(图片),还可以放上Button(按钮),CheckBox(复选框)等等。
下面的代码都直接继承了ListActivity,ListActivity和普通的Activity没有太大的差别,不同就是对显示ListView做了许 多优化,方面显示而已。

自定义布局:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
    <ImageView
        android:id="@+id/img"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margin="5dp"/>
    <TextView
        android:id="@+id/title"
        android:layout_width="wrap_content" 
        android:layout_height="wrap_content" 
        android:textColor="#ffffff"
        android:textSize="20sp"/>
</LinearLayout>
 ListView lv=new ListView(this);
 lv=(ListView) findViewById(R.id.lv);

 //1.准备数据容器
 List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
 //2.装在数据
 Map<String, Object> map = new HashMap<String, Object>();
 map.put("title", "小米手机");
 map.put("img", R.mipmap.icon);
 list.add(map);
 //设置适配器
 SimpleAdapter adapter = new SimpleAdapter(
                            this, 
                            getData(), 
                            R.layout.simple, 
                            new String[]{ "title","img" }, 
                            new int[]{ R.id.title,R.id.img }
                            );
 lv.setAdapter(adapter);


3. BaseAdapter

有时候,列表不光会用来做显示用,我们同样可以在在上面添加按钮。添加按钮首先要写一个有按钮的xml文件,然后自然会想到用上面的方法定义一 个适配器,然后将数据映射到布局文件上。但是事实并非这样,因为按钮是无法映射的,即使你成功的用布局文件显示出了按钮也无法添加按钮的响应,这时就要研 究一下ListView是如何现实的了,而且必须要重写一个类继承BaseAdapter。下面的示例将显示一个按钮和一个图片,两行字如果单击按钮将删 除此按钮的所在行。并告诉你ListView究竟是如何工作的。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="horizontal"   android:layout_width="fill_parent"
   android:layout_height="fill_parent">
   <ImageView android:id="@+id/img" 
            android:layout_width="wrap_content" 
            android:layout_height="wrap_content" 
            android:layout_margin="5px"/>
                
   <LinearLayout android:orientation="vertical" 
                android:layout_width="wrap_content" 
                android:layout_height="wrap_content">
        <TextView android:id="@+id/title" 
                android:layout_width="wrap_content" 
                android:layout_height="wrap_content"
             android:textColor="#FFFFFFFF" 
             android:textSize="22px" />
             
         <TextView android:id="@+id/info" 
                android:layout_width="wrap_content" 
                android:layout_height="wrap_content"
             android:textColor="#FFFFFFFF" 
             android:textSize="13px" />
   </LinearLayout>

   <Button android:id="@+id/view_btn" 
                android:layout_width="wrap_content"  
                android:layout_height="wrap_content"
             android:text="@string/s_view_btn" 
             android:layout_gravity="bottom|right" />
</LinearLayout>
    
 ListView lv=new ListView(this);
 lv=(ListView) findViewById(R.id.lv);
 
 //1.准备数据容器
 List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
 
 //1.装载数据
 Map<String, Object> map = new HashMap<String, Object>();
 map.put("title", "G1");
 map.put("info", "google 1");
 map.put("img", R.drawable.i1);
 list.add(map);
 
 MyAdapter adapter = new MyAdapter(this);
 lv.setAdapter(adapter);
 
 ////////////////////////////////////////        
 public class MyAdapter extends BaseAdapter{
      private LayoutInflater mInflater;
             
      public MyAdapter(Context context){
           this.mInflater = LayoutInflater.from(context);
      }
      @Override
      public int getCount() {
           return mData.size();
      }
     
      @Override
      public Object getItem(int arg0) {
           return null;
      }
     
      @Override
      public long getItemId(int arg0) {
           return 0;
      }
     
      @Override
      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;
            } 
 }
 
 
  public final class ViewHolder{
  
       public ImageView img;
       public TextView title;
       public TextView info;
       public Button viewBtn;
   }

下面将对上述代码,做详细的解释,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了。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,456评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,370评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,337评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,583评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,596评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,572评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,936评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,595评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,850评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,601评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,685评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,371评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,951评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,934评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,167评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,636评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,411评论 2 342

推荐阅读更多精彩内容