`
苗振忠
  • 浏览: 59530 次
  • 性别: Icon_minigender_1
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

Android中的Adapter 详解(三)

 
阅读更多

1.概念

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

Android中所有的Adapter一览:

由图可以看到在Android中与Adapter有关的所有接口、类的完整层级图。在我们使用过程中可以根据自己的需求实现接口或者继承类进行一定的扩展。比较常用的有 BaseAdapter,SimpleAdapter,ArrayAdapter,SimpleCursorAdapter等。

  • 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"};  
             ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,android.R.layout.simple_expandable_list_item_1,strs);  
             setListAdapter(adapter);  
         }  
     }  

实例二:

    public class MyListView extends Activity {  
          
            private ListView listView;  
            //private List<String> data = new ArrayList<String>();  
            @Override  
            public void onCreate(Bundle savedInstanceState){  
                super.onCreate(savedInstanceState);  
                   
                listView = new ListView(this);  
                listView.setAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_expandable_list_item_1,getData()));  
                setContentView(listView);  
            }  
               
            private List<String> getData(){  
                   
                List<String> data = new ArrayList<String>();  
                data.add("测试数据1");  
                data.add("测试数据2");  
                data.add("测试数据3");  
                data.add("测试数据4");  
                   
                return data;  
            }  
        } 

面代码使用了ArrayAdapter(Contextcontext, int textViewResourceId,List<T> objects)来装配数据,要装配这些数据就需要一个连接ListView视图对象和数组数据的适配器来两者的适配工作,ArrayAdapter的构造需要三个参数,依次为this,布局文件(注意这里的布局文件描述的是列表的每一行的布局,android.R.layout.simple_list_item_1是系统定义好的布局文件只显示一行文字,数据源(一个List集合)。同时用setAdapter()完成适配的最后工作。效果图如下:

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

实例一:

simple.xml

    <?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>  
    
    public class SimpleAdapterActivity extends ListActivity {  
         @Override  
         public void onCreate(Bundle savedInstanceState) {  
             super.onCreate(savedInstanceState);  
               
             SimpleAdapter adapter = new SimpleAdapter(this, getData(), R.layout.simple, new String[] { "title",  "img" }, new int[] { R.id.title, R.id.img });  
             setListAdapter(adapter);  
         }  
           
         private List<Map<String, Object>> getData() {  
             //map.put(参数名字,参数值)  
             List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();  
             Map<String, Object> map = new HashMap<String, Object>();  
             map.put("title", "摩托罗拉");  
             map.put("img", R.drawable.icon);  
             list.add(map);  
               
             map = new HashMap<String, Object>();  
             map.put("title", "诺基亚");  
             map.put("img", R.drawable.icon);  
             list.add(map);  
               
             map = new HashMap<String, Object>();  
             map.put("title", "三星");  
             map.put("img", R.drawable.icon);  
             list.add(map);  
             return list;  
             }    
           
     }  

实例二:
  下面的程序是实现一个带有图片的类表。首先需要定义好一个用来显示每一个列内容的xml,vlist.xml

    <?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>  
         </LinearLayout>  
    
    public class MyListView3 extends ListActivity {  
            // private List<String> data = new ArrayList<String>();  
            @Override  
            public void onCreate(Bundle savedInstanceState) {  
                super.onCreate(savedInstanceState);  
           
                SimpleAdapter adapter = new SimpleAdapter(this,getData(),R.layout.vlist,  
                        new String[]{"title","info","img"},  
                        new int[]{R.id.title,R.id.info,R.id.img});  
                setListAdapter(adapter);  
            }  
           
            private List<Map<String, Object>> getData() {  
                List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();  
           
                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);  
           
                map = new HashMap<String, Object>();  
                map.put("title", "G2");  
                map.put("info", "google 2");  
                map.put("img", R.drawable.i2);  
                list.add(map);  
           
                map = new HashMap<String, Object>();  
                map.put("title", "G3");  
                map.put("info", "google 3");  
                map.put("img", R.drawable.i3);  
                list.add(map);  
                   
                return list;  
            }  
        }  

使用simpleAdapter的数据用一般都是HashMap构成的List,list的每一节对应ListView的每一行。HashMap的每个键值数据映射到布局文件中对应id的组件上。因为系统没有对应的布局文件可用,我们可以自己定义一个布局vlist.xml。下面做适配,new一个SimpleAdapter参数一次是:this,布局文件(vlist.xml),HashMap的 title 和 info,img。布局文件的组件id,title,info,img。布局文件的各组件分别映射到HashMap的各元素上,完成适配。

运行效果如下图:

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文件中加入权限

                  <uses-permission android:name="android.permission.READ_CONTACTS"></uses-permission> 

效果如下:

4)BaseAdapter

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

vlist2.xml

    <?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>  
    
    /** 
         * @author  
         * 
         */  
        public class MyListView4 extends ListActivity {  
           
           
            private List<Map<String, Object>> mData;  
               
            @Override  
            public void onCreate(Bundle savedInstanceState) {  
                super.onCreate(savedInstanceState);  
                mData = getData();  
                MyAdapter adapter = new MyAdapter(this);  
                setListAdapter(adapter);  
            }  
           
            private List<Map<String, Object>> getData() {  
                List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();  
           
                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);  
           
                map = new HashMap<String, Object>();  
                map.put("title", "G2");  
                map.put("info", "google 2");  
                map.put("img", R.drawable.i2);  
                list.add(map);  
           
                map = new HashMap<String, Object>();  
                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();  
                   
            }  
               
               
               
            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  
                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了。

效果如下:

分享到:
评论

相关推荐

    android开发Adapter详解

    ### Android开发Adapter详解 #### 一、Adapter概念与作用 在Android开发中,Adapter是一种用于连接数据源和视图组件的重要桥梁。它主要用于处理数据集合与列表视图之间的交互,确保视图能够正确且高效地展示数据。...

    android adapter详解

    Android Adapter 详解 Android Adapter 是 Android 开发中一个重要的组件,负责将数据绑定到用户界面中。今天,我们将深入探讨 Android Adapter 的原理和实现方式。 什么是 Android Adapter? Android Adapter 是...

    Android Adapter详解(2)

    这篇博客“Android Adapter详解(2)”可能会深入探讨Adapter的工作原理、如何使用以及一些常见问题的解决方法。由于没有直接提供博客的具体内容,我将根据常规的Adapter知识进行详细解释。 Adapter是Android中用于将...

    Android adapter详解

    适配器(Adapter)在Android开发中是一个非常重要的概念,它主要用于处理数据源和UI组件之间的数据流动和转换。适配器作为数据和UI之间的桥梁,能够把后端数据适配到前端的显示界面,使之能够按照一定的格式显示出来...

    Android之Adapter用法总结

    **Adapter** 是 Android 开发中连接后端数据和前端视图的一个关键组件。它作为数据和用户界面(UI)之间的桥梁,在Android开发中扮演着极其重要的角色。尤其是在常见的视图组件如 `ListView`, `GridView` 等地方,...

    Android listview与adapter详解及实例代码

    在Android中,Adapter是连接数据源和视图控件(如ListView)的关键。 常见的Adapter类型有ArrayAdapter、SimpleAdapter、SimpleCursorAdapter以及BaseAdapter等。ArrayAdapter适用于绑定数组数据,SimpleAdapter...

    Android Adapter里面嵌套ListView实例详解

    Android Adapter里面嵌套ListView实例详解是Android开发中的一种常见设计,即在一个ListView中嵌套另一个ListView。这种设计可以实现复杂的列表显示,但是需要特殊处理以确保正确显示。 Android Adapter里面嵌套...

    Android各种控件详解

    在Android应用开发中,构建用户界面是至关重要的一步,它涉及到与用户交互的各种控件。以下是对Android中常见控件的详细解释: 1. **文本框(TextView)**:TextView用于展示静态文本,可以在Activity中直接创建...

    android优化技术详解

    Android 优化技术详解 Android 优化技术是指通过合理的编程和设计来提高 Android 应用程序的性能、内存和用户体验的一系列技术。下面是 Android 优化技术的详细解释: UI 布局优化 Android 的 UI 界面布局的优化...

    Android ViewPager使用详解

    **Android ViewPager 使用详解** ViewPager是Android开发中一个非常重要的组件,它允许用户通过左右滑动来切换不同的页面,常用于实现应用的滑动导航或展示多个相似内容的页面。在本篇文章中,我们将深入探讨...

    android Adapter教程

    #### 三、Adapter 应用案例详解 1. **ArrayAdapter 示例** ```java public class ArrayAdapterActivity extends ListActivity { @Override public void onCreate(Bundle savedInstanceState) { super....

    Android中Listview详解

    在Android开发中,ListView是一个非常重要的组件,常用于展示大量数据的列表形式。它可以根据数据的长度自动调整显示,提供良好的用户体验。以下是对ListView组件及其使用的详细解释。 首先,ListView的构成包含三...

    android核心技术与实例详解光盘源代码3

    在本资源中,我们聚焦于Android开发的核心技术和实例解析,主要涵盖了光盘源代码的第13至第18章。这些章节深入探讨了Android应用开发的关键方面,为开发者提供了丰富的学习材料。以下是对各章节内容的详细解读: 第...

    4、Android View详解第三部分.pptx

    【Android View详解第三部分】 在Android开发中,View是一个核心概念,它代表用户界面上的可视化元素。在本部分的讲解中,我们将深入探讨几个重要的View组件:TabHost、ScrollView、ListView、ListActivity、...

    Android 蓝牙API详解

    **Android蓝牙API详解** 在Android平台上,蓝牙技术是设备间通信的重要途径,广泛应用于数据传输、设备配对、物联网(IoT)等场景。Android提供了丰富的蓝牙API,使得开发者能够轻松实现蓝牙功能,包括经典蓝牙...

    《Android应用开发详解》配套光盘之源代码

    1. **UI设计**:Android应用的用户界面是与用户交互的窗口,源代码中包含了各种布局管理器(如LinearLayout、RelativeLayout、GridLayout、ConstraintLayout)的使用示例,以及自定义View和Adapter的实现,这些都是...

    Android 应用开发详解的源码(中)

    在本资源中,"Android 应用开发详解的源码(中)" 提供了针对初学者的Android应用开发实例,涵盖了从第七到第十二部分的知识点。这些源码旨在帮助学习者深入理解Android应用程序的设计与实现。以下是这些知识点的详细...

    Android_布局详解【图文】

    Android布局详解【图文】 在Android应用开发中,布局(Layout)是构建用户界面的基础,它决定了各个组件在屏幕上的排列方式和位置。本篇将详细讲解Android中的五种主要布局:线性布局(Linear Layout)、相对布局...

    Android项目开发详解 翟大昆版

    在翟大昆版的《Android项目开发详解》代码中,读者可以找到实际项目案例,了解如何将理论知识应用于实践中。通过分析和运行这些代码,开发者不仅可以掌握基本的界面设计和Activity管理,还能了解如何组织项目结构,...

Global site tag (gtag.js) - Google Analytics