精华内容
参与话题
问答
  • Android之Adapter用法总结

    万次阅读 多人点赞 2013-03-11 10:23:03
    Android之Adapter用法总结 1.概念  Adapter是连接后端数据和前端显示的适配器接口,是数据和UI(View)之间一个重要的纽带。在常见的View(List View,Grid View)等地方都需要用到Adapter。如下图直观的表达了...

    AndroidAdapter用法总结

    1.概念

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


    Android中所有的Adapter一览:


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

    • 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;
            }
        }

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



    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;
            }
        }

      使用Impleader的数据用一般都是Hash Map构成的Listlist的每一节对应Listie的每一行。Hash Map的每个键值数据映射到布局文件中对应id的组件上。因为系统没有对应的布局文件可用,我们可以自己定义一个布局alist.XML。下面做适配,new一个Impleader参数一次是:this,布局文件(alist.XML),Hash Map的 title 和 infoIgM。布局文件的组件idtitleinfoIgM。布局文件的各组件分别映射到Hash Map的各元素上,完成适配。

    运行效果如下图:


    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>


    /**
    002     * @author 
    003     *
    004     */
    005    public class MyListView4 extends ListActivity {
    006     
    007     
    008        private List<Map<String, Object>> mData;
    009         
    010        @Override
    011        public void onCreate(Bundle savedInstanceState) {
    012            super.onCreate(savedInstanceState);
    013            mData = getData();
    014            MyAdapter adapter = new MyAdapter(this);
    015            setListAdapter(adapter);
    016        }
    017     
    018        private List<Map<String, Object>> getData() {
    019            List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
    020     
    021            Map<String, Object> map = new HashMap<String, Object>();
    022            map.put("title", "G1");
    023            map.put("info", "google 1");
    024            map.put("img", R.drawable.i1);
    025            list.add(map);
    026     
    027            map = new HashMap<String, Object>();
    028            map.put("title", "G2");
    029            map.put("info", "google 2");
    030            map.put("img", R.drawable.i2);
    031            list.add(map);
    032     
    033            map = new HashMap<String, Object>();
    034            map.put("title", "G3");
    035            map.put("info", "google 3");
    036            map.put("img", R.drawable.i3);
    037            list.add(map);
    038             
    039            return list;
    040        }
    041         
    042        // ListView 中某项被选中后的逻辑
    043        @Override
    044        protected void onListItemClick(ListView l, View v, int position, long id) {
    045             
    046            Log.v("MyListView4-click", (String)mData.get(position).get("title"));
    047        }
    048         
    049        /**
    050         * listview中点击按键弹出对话框
    051         */
    052        public void showInfo(){
    053            new AlertDialog.Builder(this)
    054            .setTitle("我的listview")
    055            .setMessage("介绍...")
    056            .setPositiveButton("确定", new DialogInterface.OnClickListener() {
    057                @Override
    058                public void onClick(DialogInterface dialog, int which) {
    059                }
    060            })
    061            .show();
    062             
    063        }
    064         /** Listie有大量的数据需要加载的时候,会占据大量内存,影响性能,这时候   就需要按需填充并重新使用view来减少对象的创建
    065          *最快的方式是定义一个Pewholder,将convextag设置为Pewholder,不为空时重新使用即可
    066          */

    067        public final class ViewHolder{
    068            public ImageView img;
    069            public TextView title;
    070            public TextView info;
    071            public Button viewBtn;
    072        }
    073         
    074         
    075        public class MyAdapter extends BaseAdapter{
    076     
    077            private LayoutInflater mInflater;
    078             
    079             
    080            public MyAdapter(Context context){
    081                this.mInflater = LayoutInflater.from(context);
    082            }
    083            @Override
    084            public int getCount() {
    085                // TODO Auto-generated method stub
    086                return mData.size();
    087            }
    088     
    089            @Override
    090            public Object getItem(int arg0) {
    091                // TODO Auto-generated method stub
    092                return null;
    093            }
    094     
    095            @Override
    096            public long getItemId(int arg0) {
    097                // TODO Auto-generated method stub
    098                return 0;
    099            }
    100     
    101            @Override
    102            public View getView(int position, View convertView, ViewGroup parent) {
    103                 
    104                ViewHolder holder = null;
    105                if (convertView == null) {
    106                     
    107                    holder=new ViewHolder(); 
    108                     
    109                    convertView = mInflater.inflate(R.layout.vlist2, null);
    110                    holder.img = (ImageView)convertView.findViewById(R.id.img);
    111                    holder.title = (TextView)convertView.findViewById(R.id.title);
    112                    holder.info = (TextView)convertView.findViewById(R.id.info);
    113                    holder.viewBtn = (Button)convertView.findViewById(R.id.view_btn);
    114                    convertView.setTag(holder);
    115                     
    116                }else {
    117                     
    118                    holder = (ViewHolder)convertView.getTag();
    119                }
    120                 
    121                 
    122                holder.img.setBackgroundResource((Integer)mData.get(position).get("img"));
    123                holder.title.setText((String)mData.get(position).get("title"));
    124                holder.info.setText((String)mData.get(position).get("info"));
    125                 
    126                holder.viewBtn.setOnClickListener(new View.OnClickListener() {
    127                     
    128                    @Override
    129                    public void onClick(View v) {
    130                        showInfo();                
    131                    }
    132                });
    133                 
    134                 
    135                return convertView;
    136            }
    137             
    138        }     
    139    }
    复制代码

      

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

    效果如下:



    展开全文
  • Adapter详解

    千次阅读 2013-07-01 01:08:18
    Adapter是适配器,许多UI组件需要搭配Adapter来显示界面,例如Spinner与ListView,另外当我们需要动态的添加数据给UI组件时就需要Adapter了。 我们来介绍几个常见的Adapter: ArrayAdapter(comman) SimpleAdapter ...


    动态添加数据适配器adapter

    Adapter是适配器,许多UI组件需要搭配Adapter来显示界面,例如Spinner与ListView,另外当我们需要动态的添加数据给UI组件时就需要Adapter了。

    我们来介绍几个常见的Adapter:


    ArrayAdapter<T>(comman)
    SimpleAdapter extends Baseadapter(comman)
    ******************************************************************************

    这两个适配器非常常见,也非常有用,通常传输的数据可以是ArrayList<>封装的数据。

    示例如下:ArrayAdapter

    private String[] string={"china","america","japan"};
    List list=new ArrayList<String>();
    for(int i=0;i<string.length;i++)
    {
    list.add(string[i]);
    }
    ArrayAdapter<String> adapter=new ArrayAdapter<String>(this,R.layout.simple_spinner_item,list);
    首先我们定义封装数据,然后再定义Adapter,最后调用setAdapter()方法。

    ArrayAdapter有三个参数,第一个参数为Activity.this,第三个参数为动态添加给adapter的数据
    对于第二个数据:
    R.layout.simple_spinner_item:意思是将数据传给一个简单地TextView组件

    示例:SimpleAdapter

    public class SimpleAdapter extends Activity{
    private String[] names =new String[]{"nick","lebron","kobe","kevin"};
    private int[] imgsIds[] =new Int[] {R.drawable.1,R.drawable.2,R.drawable.3,R.drawable.4};
    @Override
    public void onCreate(Bundle savedInsatnceState)
    {
    super.onCreate(savedInsatnceState);
    setTitle("simpleadapter");
    setContentView(R.layout.main);
    List<Map><String,Object> list=new ArrayList<Map><String,Object>();//创建动态数组ArrayList
    for(int i=0;i<names.length;i++){
    Map<String,Object> map=new HashMap=<String,Object>;
    map.put("name",names[i]);
    map.put("headerImg",imgsIds[i]);
    list.add(map);
    }
    SimpleAdapter adapter=new SimpleAdaper(this,list,R.layout.main,new String[]{"name","headerImg"},new int[]{R.id.name,R.id.headerImg});
    ListView list=(ListView)findViewById(R.id.mylist);
    list.setAdaper(adapter);
    }
    }



    接下来我们介绍另一个常用的Adapter:BaseAdapter
    BaseAdapter implements SpinnerAdapter implements ListViewAdapter(可用于ListView和Spinner)

    示例:

    public MyListView extensds Activity{
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
    super.onCreate(savedInsatnceState);
    mDate=getDate();
    MyAdapter myadapter=new MyAdapter(this);
    ListView list=(ListView)findById(R.id.myList);
    setAdapter(myadapter);
    }
     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数据
                map = new HashMap<String, Object>();
                map.put("title", "G2");
                map.put("info", "google 2");
                map.put("img", R.drawable.i2);
                list.add(map);
         //添加第三个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; //返回List数据
    	}
    @verride
    protected void onListItemClicked(ListView 1,View v,int position,long id){
    Log.v("MyListView4_click",(String)mData.get(position).get("title"));
    	}
    public void showInfo(){
    	new AlertDiolog.Builder(this)
    	.setTitle("MyListView")
    	.setMessage(Introduce)
    	.setPositiveButton("Ensure",new DialogInterface.OnClickListener()
    	{@Override
    	public void onClick(DialogInterface dialog,int which){}	}).show();
    	}
    }
    private final class ViewHolder{
    public ImageView img;
    public TextView title;
    public TextView info;
    public Button viewBu;	
    }
    public class MyAdapter extens BaseAdapter{
    private LayoutInlfater myInflater;
    public MyAdapter(Context context){
    this.myInflater=LayoutInflater.from(context);
    }
    @Override
    public int getCount(){
    	return mDate.size();}
    @Override
    public long getItemId(int position){
    	return null;}
    @Override 
    public Object getItmeId(int position){
    	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.list,null)
    //inflate函数有两个参数--解析界面布局
    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.viewBu=(TextView)convertView.indViewById(R.id.viewBu);
    convertView.setTag(holder);
    	}else{holder=(ViewHolder)convertViewgetTag();}
    holder.img.setBackgroundResounce((Integer)mDate.get(position).get("img"));
    holder.title.setText((String)mdata.get(position).get("title"));
    holder.info.setText((String)mData.get(position).get("info"));
    holder.viewBu.setOnClickListener(new View.OnClickListener(){
    	@Override
    	public void onClick(View v){
    	showInfo();	}	
    	});
    
    return convertView;
    }
    }
    }

    getView()方法有三个参数,int position表示第几行,第几个Item;convertView 表示解析过来的布局,getCount表示列表项的个数。


    在使用ExpandabListView组件时,我们必须使用这个Adapter:

    ExpandableAdapter:(用于ExpandableListView):

    public class ExpandableListViewTest extends Activity
    {
    	@Override
    	public void onCreate(Bundle savedInstanceState)
    	{
    		super.onCreate(savedInstanceState);
    		setContentView(R.layout.main);
    		//创建一个BaseExpandableListAdapter对象
    		ExpandableListAdapter adapter = new BaseExpandableListAdapter()
    		{
    			int[] logos = new int[]
    			{
    				R.drawable.p,
    				R.drawable.z,
    				R.drawable.t
    			};
     			private String[] armTypes = new String[]
    				{ "神族兵种", "虫族兵种", "人族兵种"};
    			private String[][] arms = new String[][]
    			{
    				{ "狂战士", "龙骑士", "黑暗圣堂", "电兵" },
    				{ "小狗", "刺蛇", "飞龙", "自爆飞机" },
    				{ "机枪兵", "护士MM" , "幽灵" }
    			};
    			//获取指定组位置、指定子列表项处的子列表项数据
    			@Override
    			public Object getChild(int groupPosition, int childPosition)
    			{
    				return arms[groupPosition][childPosition];
    			}
    			@Override
    			public long getChildId(int groupPosition, int childPosition)
    			{
    				return childPosition;
    			}
    			@Override
    			public int getChildrenCount(int groupPosition)
    			{
    				return arms[groupPosition].length;
    			}
    			private TextView getTextView()
    			{
    				AbsListView.LayoutParams lp = new AbsListView.LayoutParams(
    						ViewGroup.LayoutParams.FILL_PARENT, 64);
    				TextView textView = new TextView(ExpandableListViewTest.this);
    				textView.setLayoutParams(lp);
    				textView.setGravity(Gravity.CENTER_VERTICAL | Gravity.LEFT);
    				textView.setPadding(36, 0, 0, 0);
    				textView.setTextSize(20);
    				return textView;
    			}
    			//该方法决定每个子选项的外观
    			@Override
    			public View getChildView(int groupPosition, int childPosition,
    					boolean isLastChild, View convertView, ViewGroup parent)
    			{
    				TextView textView = getTextView();			
    				textView.setText(getChild(groupPosition, childPosition).toString());
    				return textView;
    			}
    			//获取指定组位置处的组数据
    			@Override
    			public Object getGroup(int groupPosition)
    			{
    				return armTypes[groupPosition];
    			}
    			@Override
    			public int getGroupCount()
    			{
    				return armTypes.length;
    			}
    			@Override
    			public long getGroupId(int groupPosition)
    			{
    				return groupPosition;
    			}
    			//该方法决定每个组选项的外观
    			@Override
    			public View getGroupView(int groupPosition, boolean isExpanded,
    					View convertView, ViewGroup parent)
    			{
    				LinearLayout ll = new LinearLayout(ExpandableListViewTest.this);
    				ll.setOrientation(0);
    				ImageView logo = new ImageView(ExpandableListViewTest.this);
    				logo.setImageResource(logos[groupPosition]);
    				ll.addView(logo);
    				TextView textView = getTextView();
    				textView.setText(getGroup(groupPosition).toString());				
    				ll.addView(textView);			
    				return ll;
    			}
    			@Override
    			public boolean isChildSelectable(int groupPosition, int childPosition)
    			{
    				return true;
    			}
    			@Override
    			public boolean hasStableIds()
    			{
    				return true;
    			}
    		};
    		ExpandableListView expandListView = (ExpandableListView)
    			findViewById(R.id.list);
    		expandListView.setAdapter(adapter);
    	}
    }


    在使用下拉列表的Spinner时候,还有时用到SpinnerAdapter:

    下面一个示例是关于SpinnerAdapter:

    	private class SpinAdapter implements SpinnerAdapter{
    
    		@Override
    		public int getCount() {
    			return headIconIds.length;
    		}
    
    		@Override
    		public Object getItem(int pos) {
    			return null;
    		}
    
    		@Override
    		public long getItemId(int pos) {
    			return 0;
    		}
    
    		@Override
    		public int getItemViewType(int pos) {
    			return 0;
    		}
    
    		@Override
    		public View getView(int position, View convertView, ViewGroup parent) {
    			convertView = getLayoutInflater().inflate(R.layout.head_image_spinner_layout, null);
    			ImageView hicon = (ImageView)convertView.findViewById(R.id.headericon);
    			hicon.setImageResource(headIconIds[position]);
    			TextView hnote = (TextView)convertView.findViewById(R.id.headernote);
    			hnote.setText(context.getString(R.string.header)+position);
    			hnote.setTextColor(Color.BLACK);
    			return convertView;
    		}
    
    		@Override
    		public int getViewTypeCount() {
    			return 0;
    		}
    
    		@Override
    		public boolean hasStableIds() {
    			return false;
    		}
    
    		@Override
    		public boolean isEmpty() {
    			return false;
    		}
    
    		@Override
    		public void registerDataSetObserver(DataSetObserver arg0) {
    			
    		}
    
    		@Override
    		public void unregisterDataSetObserver(DataSetObserver arg0) {
    			
    		}
    
    		@Override
    		public View getDropDownView(int position, View convertView, ViewGroup parent) {
    			return getView(position, convertView, parent);
    		}
    		
    	}


    还有一些Adapter,例如:

    SimpleCursorAdapter(用于来自数据库的数据)

    关键代码如下:
    Cursor cur = getContentResolver().query(People.CONTENT_URI, null, null, null, null);
             startManagingCursor(cur);
    //来自系统通讯录数据库的Cursor数据
    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);

    展开全文
  • 首先,我们常用的Adapter有四种,分别是BaseAdapter、SimpleAdapter、ArrayAdapter、SimpleCursorAdapter四种。  BaseAdapter:基础数据适配器,它的主要用途是将一组数据传到例如ListView等UI显示组件,继承...

    首先,我们常用的Adapter有四种,分别是BaseAdapter、SimpleAdapter、ArrayAdapter、SimpleCursorAdapter四种。

                 BaseAdapter:基础数据适配器,它的主要用途是将一组数据传到例如ListView等UI显示组件,继承自接口类Adapter,由于是基础类型,所以自由度高, 可以修改的地方多。

                SimpleAdapter:简单适配器,系统自定义了一些方法,可以重写这些方法。

                ArrayAdapter:数据和UI一对一,传入数据源和布局文件,完成显示。

                SimpleCursorAdapter:指向性适配器,指向数据库,可以方便地把数据库的内容以列表的形式展示出来

               下面我们来介绍一下这四种Adapter的用法:

              1.ArrayAdapter:

          简单的ArrayAdapter,这样的列表的每一行都只有一行文字。
    
          // 当然listview 也可以是在layout里写好,然后findViewById()获取出来,这样的话后面就不需setContentView(listview);    
          
      	ListView listview = new ListView(this);
        	ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,android.R.layout.simple_expandable_list_item_1);
        	adapter.add("string1");
        	adapter.add("haha");
        	adapter.add("heihei");    	
        	listview.setAdapter(adapter);
        	setContentView(listview);  
    
    
    
          2.BaseAdapter:
    
    
    1. publicclass MyListViewBase extends Activity {  
    2.        
    3.     private ListView lv;  
    4.     //定义一个动态数组      
    5.     ArrayList<HashMap<String, Object>>listItem;/** Called when the activity is first created. */  
    6.        
    7.     @Override  
    8.     publicvoid onCreate(Bundle savedInstanceState) {  
    9.         super.onCreate(savedInstanceState);  
    10.         setContentView(R.layout.main);  
    11.    
    12.         lv = (ListView) findViewById(R.id.lv);  
    13.         MyAdapter mAdapter = new MyAdapter(this);//得到一个MyAdapter对象  
    14.         lv.setAdapter(mAdapter);//为ListView绑定Adapter  
    15.         /**为ListView添加点击事件*/  
    16.         lv.setOnItemClickListener(new OnItemClickListener() {  
    17.             @Override  
    18.             publicvoid onItemClick(AdapterView<?> arg0, View arg1, int arg2,long arg3) {  
    19.                 Log.v("MyListViewBase", "你点击了ListView条目" + arg2);//在LogCat中输出信息                  
    20.             }  
    21.         });  
    22.     }  
    23.     /**添加一个得到数据的方法,方便使用*/  
    24.     private ArrayList<HashMap<String, Object>> getDate(){  
    25.         ArrayList<HashMap<String, Object>> listItem = new ArrayList<HashMap<String,Object>>();  
    26.         /**为动态数组添加数据*/      
    27.         for(int i=0;i<30;i++)   
    28.          {   
    29.              HashMap<String, Object> map = new HashMap<String, Object>();   
    30.              map.put("ItemTitle", "第"+i+"行");   
    31.              map.put("ItemText", "这是第"+i+"行");   
    32.              listItem.add(map);   
    33.          }  
    34.         return listItem;  
    35.     } 

     

    1.     /** 新建一个类继承BaseAdapter,实现视图与数据的绑定 
    2.      */  
    3.     privateclass MyAdapter extends BaseAdapter {  
    4.         private LayoutInflater mInflater;//得到一个LayoutInfalter对象用来导入布局   
    5.            
    6.         /**构造函数*/  
    7.         public MyAdapter(Context context) {  
    8.             this.mInflater = LayoutInflater.from(context);  
    9.         }  
    10.    
    11.         @Override  
    12.         publicint getCount() {  
    13.             return getDate().size();//返回数组的长度          
    14.         }  
    15.    
    16.         @Override  
    17.         public Object getItem(int position) {  
    18.             returnnull;  
    19.         }  
    20.    
    21.         @Override  
    22.         publiclong getItemId(int position) {  
    23.             return 0;  
    24.         }  
    25.            
    26.         /**书中详细解释该方法*/          
    27.         @Override  
    28.         public View getView(finalint position, View convertView, ViewGroup parent) {  
    29.              ViewHolder holder;  
    30.             //观察convertView随ListView滚动情况              
    31.              Log.v("MyListViewBase", "getView " + position + " " + convertView);  
    32.             if (convertView == null) {  
    33.                      convertView = mInflater.inflate(R.layout.item,null);  
    34.                      holder = new ViewHolder();  
    35.                     /**得到各个控件的对象*/                      
    36.                     holder.title = (TextView) convertView.findViewById(R.id.ItemTitle);  
    37.                     holder.text = (TextView) convertView.findViewById(R.id.ItemText);  
    38.                     holder.bt = (Button) convertView.findViewById(R.id.ItemButton);  
    39.                     convertView.setTag(holder);//绑定ViewHolder对象                     
    40.             }  
    41.             else{  
    42.                     holder = (ViewHolder)convertView.getTag();//取出ViewHolder对象                    
    43.             }  
    44.             /**设置TextView显示的内容,即我们存放在动态数组中的数据*/              
    45.             holder.title.setText(getDate().get(position).get("ItemTitle").toString());  
    46.             holder.text.setText(getDate().get(position).get("ItemText").toString());  
    47.                
    48.             /**为Button添加点击事件*/               
    49.             holder.bt.setOnClickListener(new OnClickListener() {  
    50.                 @Override  
    51.                 publicvoid onClick(View v) {  
    52.                     Log.v("MyListViewBase", "你点击了按钮" + position);//打印Button的点击信息                      
    53.                 }  
    54.             });  
    55.                
    56.             return convertView;  
    57.         }  
    58.        
    59.     }  
    60.        
    61.     /**存放控件*/  
    62.     publicfinalclass ViewHolder{  
    63.         public TextView title;  
    64.         public TextView text;  
    65.         public Button   bt;  
    66.     }  
    67. }  

    还需要注意的是,Button会抢夺ListView的焦点,需要将Button设置为没有焦点。设置非常简单,只需要在xml的Button标签下加入一行:Android:focusable=“false”代码就

    可以了。在LogCat观察点击后输出的信息,运行效果如图所示:

    
    
    



    
    

      3.SimpleAdapter

             ListView可以使用最基本的ArrayAdapter填充,但是每一行只能填充文本。我们的聊天内容除了文本,还希望有个头像(当然后期还可以再添聊天时间、用户名之类的~),首相想到的是使用SimpleAdapter。

            这是第一个Demo的代码:

    1. public class TryChatPopActivity extends Activity {  
    2.     ListView itemlist = null;  
    3.     List<Map<String, Object>> list;  
    4.   
    5.     public void onCreate(Bundle savedInstanceState) {  
    6.             super.onCreate(savedInstanceState);  
    7.             setContentView(R.layout.main);  
    8.             itemlist = (ListView) findViewById(R.id.chatlist);  
    9.             refreshListItems();  
    10.     }  
    11.     private void refreshListItems() {  
    12.             list = buildListForSimpleAdapter();  
    13.             //实例适配器  
    14.             SimpleAdapter chat = new SimpleAdapter(this, list, R.layout.chata,  
    15.                             new String[] {"chatportrait","chatinfo"}, new int[] {R.id.imgPortraitA,R.id.txvInfo});  
    16.             itemlist.setAdapter(chat);  
    17.             itemlist.setSelection(0);  
    18.     }  
    19.       
    20.     //用来实例化列表容器的函数  
    21.     private List<Map<String, Object>> buildListForSimpleAdapter() {  
    22.             List<Map<String, Object>> list = new ArrayList<Map<String, Object>>(2);  
    23.             ImageView  imgA=(ImageView)findViewById(R.id.imgPortraitA);  
    24.             //向列表容器中添加数据(每列中包括一个头像和聊天信息)  
    25.             Map<String, Object> map = new HashMap<String, Object>();  
    26.             map.put("chatportrait",imgA);  
    27.             map.put("chatinfo", "嗨~");  
    28.             list.add(map);  
    29.               
    30.             map = new HashMap<String, Object>();  
    31.             map.put("chatportrait",imgA);  
    32.             map.put("chatinfo", "嗨~\n你好!");  
    33.             list.add(map);  
    34.   
    35.             map = new HashMap<String, Object>();  
    36.             map.put("chatportrait",imgA);  
    37.             map.put("chatinfo", "嗨~\n你好!\n我是小魏~");  
    38.             list.add(map);  
    39.               
    40.             return list;  
    41.     }  

           其中 chata 布局文件如下:

    1. <?xml version="1.0" encoding="utf-8"?>  
    2. <LinearLayout  
    3.   xmlns:android="http://schemas.android.com/apk/res/android"  
    4.   android:layout_width="fill_parent"  
    5.   android:layout_height="wrap_content"  
    6.   android:orientation="horizontal"  
    7.   android:paddingTop="5px"  
    8.   >  
    9.   <ImageView  
    10.       android:layout_width="42px"  
    11.       android:layout_height="42px"  
    12.       android:layout_gravity="bottom"  
    13.       android:id="@+id/imgPortraitA"  
    14.       android:background="@drawable/portraita"  
    15.   />  
    16.   <TextView android:id="@+id/txvInfo"   
    17.        android:layout_width="wrap_content"   
    18.        android:layout_height="wrap_content"  
    19.        android:paddingTop="5px"  
    20.        android:paddingBottom="5px"  
    21.        android:paddingLeft="5px"  
    22.        android:textColor="@android:color/black"   
    23.        android:textSize="18dip"       
    24.        android:background="@drawable/chatbg"></TextView>  
    25. </LinearLayout> 

            这里最关键是尝试定义和使用SimpleAdapter适配器:

            SimpleAdapter chat = new SimpleAdapter(this, list, R.layout.chata,  new String[] {"chatportrait","chatinfo"}, new int[] {R.id.imgPortraitA,R.id.txvInfo});


           其中第一个参数是context,即当前的Activity;第二个参数是要去填充ListView每一行内容的list;第三个参数resource是ListView每一行填充的布局文件。

         

          比较麻烦的是第四个和第五个参数,SimpleAdapter构造函数中第四个参数String[] from表示名字数组,因为在ArrayList存放的都是Map<String,Object>的item,from中的名字就是为了索引ArrayList中的Object。

          第五个参数在构造函数中表示为int[] to,是索引layout中的id,对应前面每项的布局格式。 


    4.  SimpleCursorAdapter

     1     packagecom.example.simplecursoradapter;

     2

     3     import android.app.Activity;

     4     import android.content.Intent;

     5     import android.database.Cursor;

     6     import android.database.CursorWrapper;

     7     import android.graphics.Color;

     8     import android.net.Uri;

     9     import android.os.Bundle;

    10    importandroid.provider.Contacts.People;

    11    importandroid.telephony.PhoneNumberUtils;

    12    import android.util.Log;

    13    import android.view.View;

    14    importandroid.widget.AdapterView;

    15    import android.widget.LinearLayout;

    16    importandroid.widget.ListAdapter;

    17    importandroid.widget.ListView;

    18    importandroid.widget.SimpleCursorAdapter;

    19

    20

    21   publicclassMainActivity extendsActivity {

    22   privatestatic final StringTAG = "MainActivity";

    23   ListViewlistView;

    24   ListAdapteradapter;

    25

    26     @Override

    27     publicvoid onCreate(BundlesavedInstanceState) {

    28         super.onCreate(savedInstanceState);

    29

    30         LinearLayout linearLayout =new LinearLayout(this);

    31         linearLayout.setOrientation(LinearLayout.VERTICAL);

    32

    33         LinearLayout.LayoutParams param =newLinearLayout.LayoutParams(

    34                 LinearLayout.LayoutParams.FILL_PARENT,

    35                 LinearLayout.LayoutParams.WRAP_CONTENT);

    36

    37         listView = newListView(this);

    38         linearLayout.addView(listView, param);

    39         this.setContentView(linearLayout);

    40

    41         // 从数据库获取联系人姓名和电话号码

    42         Cursor cur = this.getContentResolver().query(People.CONTENT_URI,null,

    43                 null,nullnull);

    44         adapter = newSimpleCursorAdapter(this,

    45                android.R.layout.simple_list_item_2, cur,new String[] {

    46                         People.NAME,People.NUMBER },new int[] {

    47                         android.R.id.text1,android.R.id.text2 });

    48         this.startManagingCursor(cur);

    49         listView.setAdapter(adapter);

    50

    51         listView.setOnItemClickListener(newAdapterView.OnItemClickListener() {

    52

    53             publicvoid onItemClick(AdapterView<?> arg0, View arg1,

    54                     intposition, long arg3){

    55

    56                 // names=((CursorWrapper)listView.getItemAtPosition(position)).getColumnNames();

    57                 // 从指针的封装类中获得选中项的电话号码并拨号

    58                 CursorWrapper wrapper = (CursorWrapper) listView

    59                         .getItemAtPosition(position);

    60                 intcolumnIndex = wrapper.getColumnIndex(People.NUMBER);

    61                 if(!wrapper.isNull(columnIndex)) {

    62                     String number = wrapper.getString(columnIndex);

    63                     Log.d(TAG,"number=" + number);

    64                     //判断电话号码的有效性

    65                     if (PhoneNumberUtils.isGlobalPhoneNumber(number)) {

    66                         Intent intent =new Intent(Intent.ACTION_DIAL,Uri

    67                                .parse("tel://" + number));

    68                         startActivity(intent);

    69                     }

    70                 }

    71             }

    72         });

    73     }

    74 }

            不要忘记添加权限:

         <intent-filter>           

              <actionandroid:name="android.Intent.Action.CALL_BUTTON"/>

     

              <categoryandroid:name="android.Intent.Category.DEFAULT"/>       

        </intent-filter>

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



    展开全文
  • BaseAdapter是最基础的Adapter类,也是最实用最常用的一个类,但是相比于ArrayAdapter之类的,对初学者来说却比较难理解。所以在这里介绍一下BaseAdapter。 Adapter 是什么? An Adapter object acts as a bridge ...

    BaseAdapter是最基础的Adapter类,也是最实用最常用的一个类,但是相比于ArrayAdapter之类的,对初学者来说却比较难理解。所以在这里介绍一下BaseAdapter。
    案例查看: >>Android 案例: 控件GridView的使用-手机管家九宫格<<

    Adapter 是什么?

    An Adapter object acts as a bridge between an AdapterView and the underlying data for that view. The Adapter provides access to the data items. The Adapter is also responsible for making a View for each item in the data set.
    翻译过来,简单理解就是adapter是view和数据的桥梁。在一个ListView或者GridView中,你不可能手动给每一个格子都新建一个view,所以这时候就需要Adapter的帮忙,它会帮你自动绘制view并且填充数据。

    BaseAdapter是什么

    从英文就可以知道了,最基础的Adapter,也就是说,它可以做所有的事情。所以为什么说最实用最常用,原因就在于它的全能性,不会像ArrayAdapter等的封装好的类有那么多局限性,但是这样的话,使用起来自然会更加麻烦一点。但是这篇文章就会告诉你怎么熟练使用它。

    BaseAdapter怎么用

    在ListView、GridView或者其他的view中,使用setAdapter方法传入我们的baseAdapter就可以用了。

    gridView.setAdapter(baseAdapter);
    

    问题就出在这个mBaseAdapter要怎么写了。重点终于来了。
    可以新建一个java文件MyBaseAdapter,继承自BaseAdapter,并且实现它的4个基础方法。

    public class MyBaseAdapter extends BaseAdapter {
        @Override
        public int getCount() {
            return 0;
        }
        @Override
        public Object getItem(int position) {
            return null;
        }
        @Override
        public long getItemId(int position) {
            return 0;
        }
        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            return null;
        }
    }
    

    默认实现这4个方法后,接下来我们就要重写这4个方法了。那么具体这4个方法有什么用呢?我们在后面再讲。
    MyBaseAdapter这个类写好后,我们就新建一个mBaseAdapter,在setAdapter方法的时候传进去就好了。

    MyBaseAdapter baseAdapter= new MyBaseAdapter();
    

    这样的三步法就可以实现BaseAdapter的使用了。
    但是,这当然没完。因为现在你还没告诉你的BaseAdapter你要叫它干什么呢。所以接下来我们就要修改MyBaseAdapter了。

    BaseAdapter方法详解

    学会BaseAdapter其实只需要掌握四个方法:
    getCount, getItem, getItemId, getView

    getCount : 要绑定的条目的数目,比如格子的数量
    getItem : 根据一个索引(位置)获得该位置的对象
    getItemId : 获取条目的id
    getView : 获取该条目要显示的界面
    可以简单的理解为,adapter先从getCount里确定数量,然后循环执行getView方法将条目一个一个绘制出来,所以必须重写的是getCountgetView方法。而getItemgetItemId是调用某些函数才会触发的方法,如果不需要使用可以暂时不修改。

    接下来用一个简单的demo来展示一下BaseAdapter。

    首先在MyBaseAdapter中添加super()方法,用来将数据源传入MyBaseAdapter中。其中this.data = data;的意思是将传入的形参赋值给我们的私有变量以供使用。mContext是在后面要调用到,这里先不解释。

    private String[] data;
    private Context mContext;
    public MyBaseAdapter(Context mContext, String[] data) {//用于数据的桥梁可以传入
        super();
        this.mContext = mContext;
        this.data = data;
    }
    

    然后就可以将getCount的返回值修改为我们的数据源的长度,要显示几个条目,我们就传入多长的数据源就可以了。

    public int getCount() {//该方法如果返回0的话就不调用下面getView(.....)方法如果大于0掉用该方法
        return data.length;
    }
    

    接着将getView的方法改为显示出我们数据源的字符串。

    	/**
    	 * @param position 表示当前索引
    	 * @param convertView 缓存区   就是这个convertView其实就是最关键的部分 
    	 * 					     原理上讲 当ListView滑动的过程中 会有item被滑出屏幕 而不再被使用 这时候Android会
    	 * 					     回收这个条目的view 这个view也就是这里的convertView
    	 *      			     也就是为了不浪费内存重新调用第一个地址      就是被划上去的那个View  
    	 *      			    当item1被移除屏幕的时候 我们会重新new一个View给新显示的item_new 
    	 *      			   而如果使用了这个convertView 我们其实可以复用它 这样就省去了new View的大量开销
    	 * @param parent 每个ItemView里面的容器  返回的View直接添加到容器中来
    	 * @return View 就是每个ItemView要显示的内容
    	 */
    public View getView(int position, View convertView, ViewGroup parent) {
        TextView textView = new TextView(mContext);
        textView.setText(data[position]);
        return textView;
    }
    

    这里为每一个条目新建一个TextView用来显示字符串,新建的时候就需要传入一个Context,就用到了我们之前的mContext。
    这样我们就可以使用MyBaseAdapter来显示一个字符串数组了。不过还需要在前面修改一下,在新建mBaseAdapter的时候要传入context和数据源。

    String[] strings = {"a","b","c"}; 
    MyBaseAdapter mBaseAdapter = new MyBaseAdapter(getApplicationContext(),strings);
    

    接下来贴一下完整的代码吧。ListView的新建我就不讲了。

    • MainActivity部分
    import android.support.v7.app.AppCompatActivity;
    import android.os.Bundle;
    import android.widget.ListView;
    public class MainActivity extends AppCompatActivity {
        private ListView listView;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            listView = (ListView) findViewById(R.id.listView);
            String[] strings = {"a","b","c"};
            MyBaseAdapter mBaseAdapter = new MyBaseAdapter(getApplicationContext(),strings);
            listView.setAdapter(mBaseAdapter);
        }
    }
    
    • MyBaseAdapter部分
    import android.content.Context;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.BaseAdapter;
    import android.widget.TextView;
    public class MyBaseAdapter extends BaseAdapter {
          private String[] data;
          private Context mContext;
          public MyBaseAdapter(Context mContext, String[] data) {
              super();
              this.mContext = mContext;
              this.data = data;
          }
          @Override
          public int getCount() {
              return data.length;
          }
          @Override
          public Object getItem(int position) {
              return null;
          }
          @Override
          public long getItemId(int position) {
              return 0;
          }
          @Override
          public View getView(int position, View convertView, ViewGroup parent) {
              TextView textView = new TextView(mContext);
              textView.setText(data[position]);
              return textView;
          }
    }
    

    BaseAdapter进阶使用

    当然一个TextView显然满足不了我们的需要,这也完全不能显示BaseAdapter的全能性。那接下来,就来展示一下如何用BaseAdapter显示一个自定义布局。

    • 首先新建一个layout,我命名为item,这个就是我们每个条目要展示的布局
    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
          xmlns:app="http://schemas.android.com/apk/res-auto"
          android:orientation="horizontal" android:layout_width="match_parent"
          android:layout_height="match_parent">
          <ImageView
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              app:srcCompat="@mipmap/ic_launcher"
              android:id="@+id/imageView" />
          <Button
              android:text="Button"
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:id="@+id/button" />
          <TextView
              android:text="TextView"
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:id="@+id/textView" />
    </LinearLayout>
    
    • 接下来修改getView方法,让它显示我们这个item布局
    public View getView(int position, View convertView, ViewGroup parent) {
          LayoutInflater inflater = LayoutInflater.from(mContext);
          View view = inflater.inflate(R.layout.item,null);
          final TextView textView = (TextView) view.findViewById(R.id.textView);
          Button button = (Button) view.findViewById(R.id.button);
          ImageView imageView = (ImageView) view.findViewById(R.id.imageView);
          imageView.setImageResource(R.mipmap.ic_launcher);
          button.setOnClickListener(new View.OnClickListener() {
              @Override
              public void onClick(View v) {
                  textView.append("!");
              }
          });
          textView.setText(data[position]);
          return view;
    }
    

    主要讲解一下前两句。LayoutInflater是用来加载布局的,用LayoutInflater的inflate方法就可以将你的item布局绘制出来。其中getView方法中的三个参数,position是指现在是第几个条目;convertView是旧视图,就是绘制好了的视图;parent是父级视图,也就是ListView之类的。
    用inflate方法绘制好后的view最后return返回给getView方法就可以了。

    BaseAdapter的优化使用

      上面的convertView是旧视图是什么意思呢?就是listview如果超出了屏幕,滑动的时候会隐藏掉一部分,这时候就将隐藏掉的部分保存到convertView中。那么如果是我们之前的写法,每次返回的时候就没有使用convertView,重新创建了一个View,这样子浪费了系统资源。那要怎么利用convertView优化呢?
    

    同样我们还是对getView进行进一步修改。

    • 首先定义一个类ViewHolder,用来标记我们的控件
    static class ViewHolder{
          TextView textView;
          ImageView imageView;
          Button button;
    }
    
    • 接下来使用ViewHolder优化
      在getView方法中,Adapter先从xml中用inflate方法创建view对象,然后在这个view找到每一个控件。这里的findViewById操作是一个树查找过程,也是一个耗时的操作,所以这里也需要优化,就是使用viewHolder,把每一个控件都放在Holder中,当第一次创建convertView对象时,把这些控件找出来。然后用convertView的setTag将viewHolder设置到Tag中,以便系统第二次绘制ListView时从Tag中取出。当第二次重用convertView时,只需从convertView中getTag取出来就可以。
    public View getView(int position, View convertView, ViewGroup parent) {
          LayoutInflater inflater = LayoutInflater.from(mContext);
          ViewHolder holder = null;
          if (convertView == null) {
              convertView = inflater.inflate(R.layout.item, null);
              holder = new ViewHolder();
              holder.button = (Button) convertView.findViewById(R.id.button);
              holder.textView = (TextView) convertView.findViewById(R.id.textView);
              holder.imageView = (ImageView) convertView.findViewById(R.id.imageView);
              convertView.setTag(holder);
          }    else {
              holder = (ViewHolder) convertView.getTag();
          }
          holder.imageView.setImageResource(R.mipmap.ic_launcher);
          holder.button.setOnClickListener(new View.OnClickListener() {
              @Override
              public void onClick(View v) {
                  Log.d("click","button");
              }
          });
          holder.textView.setText(data[position]);
          return convertView;
    }
    

    先判断convertView是否为空,是的话就创建ViewHolder,不是的话就取出ViewHolder,这样就可以实现复用convertView了。

    总结

    在继承BaseAdapter类时要实现一下方法

    1. BaseAdapter 默认提供了四个方法:
           --- getCount() 必须 告诉列表默认显示多少条数据
           --- getView(int position, View convertView, ViewGroup parent) 必须 告诉列表每项怎么显示
           --- getItem(int position) 可选 
           --- getItemId(int position) 可选 
    
    1. 细节:
            getCount() 只有在setAdapter()与notifyDataSetChanged();调用时才调用 
            getView(int position, View convertView, ViewGroup parent) 只有getCount() 不为0的时候才调用 
            每个View都可以携带一个对象 这样对象就可以不用作为全局变量了 只要有View就有对象
            子项里面有需要绑定的子控件可以创建一个ViewHolder类来封装
            MyAdapter adapter = new MyAdapter();//该方法用来绑定的
           ListView对象.setAdapter(adapter);    //绑定的时候多次调用
    

    重点

    1. 每一个View 都可以获取Context. —>v.getContext();
    2. FILL_PARENT(安卓2.3版本以前的写法)==MATCH_PARENT
    3. 通过布局文件直接转换成View LayoutInflater.from(mContext).inflate(R.layout.xxx,root);
    展开全文
  • Android中的Adapter 详解(一)

    万次阅读 2012-05-11 16:34:02
    Adapter介绍 Android是完全遵循MVC模式设计的框架,Activity是Controller,layout是View 因为layout五花八门,很多数据都不能直接绑定上去,所以Android引入了Adapter这个机制作为复杂数据的展示的转换载体,所以...
  • 三种adapter的区别和用法

    千次阅读 2017-03-22 16:25:38
    Android提供的三种adapter主要有ArrayAdapter,SimpleAdapter,SimoleCuisorAdapter是简单的字符串适配器,simpleAdapter是可以自定义子View布局的,可以有图片,SimpleCursor主要用语数据库,前两个的数据来源一般都...
  • 设计模式(五)适配器模式Adapter(结构型)

    万次阅读 多人点赞 2012-05-02 16:02:58
    设计模式(五)适配器模式Adapter(结构型) 1. 概述: 接口的改变,是一个需要程序员们必须(虽然很不情愿)接受和处理的普遍问题。程序提供者们修改他们的代码;系统库被修正;各种程序语言以及相关库的发展和...
  • 安卓中的三种Adapter适配器

    万次阅读 2019-04-14 15:43:53
    安卓中的三种Adapter适配器 适配器是一个非常重要的知识点,Adapter是用来帮助填出数据的中间桥梁。适配器将各种数据以合适的形式显示在View中给用户看。 一、ArrayAdapter(数组适配器) 有一定的局限性,只能显示...
  • adapter是数据与ui之间的桥梁,它把后台数据与前端ui连接到一起,是一个展示数据的载体。 常用的adapter: BaseAdapter : 基础适配器,对于spinner listview gridview 都是通用的,它是一个抽象类,继承后要实现的...
  • 相信很多人都用过Adapter,但是Adapter嵌套Adapter确很少使用,主要是这样的需求也不多,最近要做一个说明书类的应用,左边实现目录的嵌套,点击一级目录弹出二级目录,一级目录为一个Adapter,二级目录又是一个...
  • android Adapter原理解析

    千次阅读 2016-09-29 15:03:18
    1、先看一下Adapter的继承关系: 2、Adapter的实现原理其实就是一个观察者模式的应用。先上一幅简图: 3、首先看观察者抽象类:DataSetObserver,它有两个方法onChange()和onInvalidated(),源码: public ...
  • Android进阶(十四)Android Adapter详解

    万次阅读 2015-06-15 09:21:43
    因为layout五花八门,很多数据都不能直接绑定上去,所以Android引入了Adapter这个机制作为复杂数据展示的转换载体,所以各种Adapter只不过是转换的方式和能力不一样而已。 Adapter是将数据绑定到UI界面上的桥接类。...
  • Android Adapter的使用

    千次阅读 2019-01-21 11:36:13
    ArrayAdapter  public class MainActivity extends Activity { private ListView lv;//控件引用声明 private List&lt;String&gt;...//数据源集合引用声明 ... adapter;//适配器声明 ...
  • Android Adapter接口的实现类总结

    千次阅读 2016-10-12 13:03:06
    首先,我们先要了解什么是Adapter,其实我们一般都可以从翻译中知道一点,这个单词的翻译是“适配器”。也就是说,我们可以通过Adapter把对应的数据放到对应的容器中。这就是Adapter的作用。
  • Android Adapter回调接口

    千次阅读 2015-04-17 14:58:13
    Andoird中当activity中需要处理adapter中listview的item点击事件,这时候需要用到回调接口,Adapter中定义的接口相当与发布,在activity中实现相当于是响应。  这样activity中便可以获取adapter中的数据: ①回调...
  • ArrayAdapter<String> adapter = new ArrayAdapter(this, android.R.layout.simple_list_item_1, contactList); mListView.setAdapter(adapter); readContacts(); } private void readContacts() { Cursor ...
  • android adapter

    千次阅读 2014-04-27 12:40:33
    Adapter是将数据绑定到UI界面上的桥接类。Adapter负责创建显示每个项目的子View和提供对下层数据的访问。   支持Adapter绑定的UI控件必须...一些Android提供的Adapter介绍   在多数情况下,你不需要白手
  • android adapter设置高度

    2015-04-17 03:49:20
    我的item.xml文件里是1个LinearLayout (a),里面9个LinearLayout(b) main.xml里面一个gridview,一行一个item,我想的是每个b按比例显示大小(就是等高)。怎么实现(不能固定死呀,要每个手机上显示b的高度都一样)...
  • 首先准备工具类 /** * Created by Administrator on 2018/11/23. */ public class Instance { public static ImageLoader imageLoader = ImageLoader.getInstance(); public static DisplayImageOptions user...
  • adpater显示的数据集合为list,但是这个list中有一些item我不想显示,怎么做?
  • Android Adapter操作Activity

    千次阅读 2015-02-05 22:10:52
    有时Activity中嵌套的几个Adapter,想在Adapter中的getView中设置Button的点击事件时,调用Activity的方法,如setResult,但是因为Adapter与Activity不是同一个类,所以操作有点麻烦 可以先把方法在Activity...
  • Android Adapter,UI界面更新

    千次阅读 2017-04-20 19:29:04
    1:广播处理器 MusicPlayerActivity: ArrayList musics = new MusicBiz(MusicPlayerActivity.this).getLocalMusics(); app.setMusics(musics);// 更新共享的播放列表... adapter.changeDataSet(musics);// 更新界面
  • Android Adapter以及getView()方法的理解

    千次阅读 2015-08-05 20:03:48
    Android Adapter基本理解: 我的理解是: 1、一个有许多getter的类(就是getView(),getCount()....这些方法) 2、有多少个get方法?都是什么? 这些getter是特定的,你可以复写他们,全部的方法如下 ...
  • 1. context.finish();2.如果上面的方法不管用,把context强转成activity,然后用activity.finish();
  • Android adapter传数据到Activity

    千次阅读 2017-04-08 17:12:35
    不想费事在Activity再拿网络请求的数据,就在adapter写了个回调。可以在adapter通过回调的方式把数据传递到Activity中。  1、 adapter if(bean != null){ holder.city_name.setText(bean.get(position)....
  • 在开发工程中会遇到activity 与adapter 分开写,两个文件,但是需要调用activity中的方法,解决方法如下: public class FormAdapter extends BaseAdapter{ private TestActivity mContext; public ...
  • 今天调试接口,获取了数据,解析成list,然后调用 notifyDataSetChanged 这个方法刷新适配器 结果没反应 通过debug 和分析代码 发现 notifyDataSetChanged这个方法根据内存地址判断数据有没有更新 ...
  • 记录自己的bug . ...adapter = new Adapter(...data_list); listView.setAdapter(adapter) ... adapter 里面  Listdata_list = new ArrayList(); 构造器中 拿到外部的数据源引用。
  • public class SearchAutoAdapter extends BaseAdapter { private OnClickListener mOnClickListener; public SearchAutoAdapter(Context context, int maxMatch, OnClickListener onClickListener) { ...
  • 在一个项目中,用了ListView,然后再每一个Item中需要动态AddView,这样如果同一个position多次调用则会多调用几次AddView出现界面错乱的问题。

空空如也

1 2 3 4 5 ... 20
收藏数 287,151
精华内容 114,860
关键字:

adapter