Android Adapter

Adapter

Adapter相当于一个数据源,可以给AdapterView提供数据,并根据数据创建对应的UI,可以通过调用AdapterView的setAdapter方法使得AdapterView将Adapter作为数据源。

常见的AdapterView的子类有ListView、GridView、Spinner和ExpandableListView等。

本文就以ListView为例讲解各种常见的Adapter的使用。

Adapter的分类与样式:

1、ListAdapter继承自Adapter接口,相比Adapter新增了areAllItemsEnabled和isEnabled两个方法。

2、SpinnerAdapter相比Adapter,SpinnerAdapter中新增了getDropDownView方法,该方法与Adapter接口中定义的getView方法类似,该方法主要是供AbsSpinner调用,用于生成Spinner下拉弹出区域的UI。

3、BaseAdapter

4、ArrayAdapter是最简单的Adapter,AdapterView会将ArrayAdapter中的数据项调用toString()方法,作为文本显示出来。Activity代码:

ListView listView = (ListView)findViewById(R.id.listView);
        String[] values = {"iPhone","小米","三星","华为","中兴","联想","黑莓","魅族"};
        //List<String> list = Arrays.asList(values);
        //Arrays.asList(values)返回的是一个只读的List,不能进行add和remove
        //new ArrayList<>(Arrays.asList(values))则是一个可写的List,可以进行add和remove
        List<String> list = new ArrayList<>(Arrays.asList(values));
        final ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, list);//this参数1:this,参数2:item的layout,参数3:list数据
        listView.setAdapter(adapter);
        //单击item之后,删除对应的item
        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                String item = adapter.getItem(position);
                adapter.remove(item);
                Toast.makeText(MainActivity.this, item, Toast.LENGTH_SHORT).show();
            }
        });

5、SimpleAdaper:作用是方便地将数据与XML文件定义的各种View绑定起来,从而创建复杂的UI。可以加入图片和文字,值得一提的是在网络环境中获得image图片需要在SimpleAdapter中做一下改动

 ArrayList<Map<String,String>> data = (ArrayList<Map<String,String>>)msg.getData().getSerializable("res");//初始数据是Map类型的Arraylist
                if(data != null) {
                    allGoods = new ArrayList<Goods>();//Goods是ListView每一行要显示的一个对象,其实是一个产品信息,其中包括产品图片,名字和价格
                    for (Map<String, String> g : data) {//解析data,因为传来的是数组,所以封装对象的时候要循环遍历data数组,
                        String id = g.get("pid");//将data里的对应key值里的value,组成Goods对象里,形成Goods对象
                        String pname = g.get("pname");
                        String pprice = g.get("price");
                        String img = g.get("img");
                        Goods myGoods = new Goods(id, pname, pprice, img);
                        allGoods.add(myGoods);//将新的对象添加到allGoods数组对象里
                    }
                    List<Map<String,Object>> items = new ArrayList<Map<String,Object>>();//定义 List<Map<String,Object>> ,用于存放信息 r,放到SimpleAdapter
                    String url3 = getResources().getString(R.string.url3);//服务器地址,用于图片显示的
                    for (Goods gd : allGoods){//遍历 allGoods 取出产品数据 , 定义Map类型对象 ,用于存放一个产品信息,以键值对的形式
                        Map<String,Object> item = new HashMap<String,Object>();
                        item.put("goods_name",gd.getPname());
                        item.put("goods_price",gd.getPprice());
                        item.put("goods_img",imageLoader.loadImageSync(url3 + gd.getImg()));//图片的地址信息为服务器的路径
                        //例如 <string name="url3">http://192.168.191.1:8080/HomeWork</string> 。Homewo是我的服务器工程名。gd.getImg() 为/upload/gangbi.jpg . 在工程HomeWork下的upload文件夹下的gangbi。jsp图片
                        //图片本身存放在服务器里。
                        items.add(item);//将得到的item放到集合里
                    }
                    //SimpleAdapter 用于前台 ListView 显示集合型数据。需要5个参数。
                    SimpleAdapter adapter = new SimpleAdapter(GoodsListActivity.this,//第一个当前类名.第二个要显示的数据,第三个一产品数据显示的样式,第四个一个产品的键值名,第五个各键值的值要显示的位置
                            items,                                                    //第二个要显示的数据,数据类型必须List<Map<String,Object>>
                            R.layout.good_item_layout,                             //第三个一产品数据显示的样式
                            new String[]{"goods_name","goods_price","goods_img"},//第四个一个产品的键值名,与存放在Map中的键值对的key一样
                            new int[]{R.id.goods_name,R.id.goods_price,R.id.goods_img});//第五个各键值的值要显示的位置,与Map中的key对应
                    //显示item中的图片
                            adapter.setViewBinder(new SimpleAdapter.ViewBinder() {
                                @Override
                                public boolean setViewValue(View view, Object data, String textRepresentation) {
                                    if (view instanceof ImageView && data instanceof Bitmap) {
                                        ImageView iv = (ImageView) view;
                                        iv.setImageBitmap((Bitmap) data);
                                        return true;
                                    }
                            return false;
                        }
                    });
                    //ListView 显示Adapter内容
                    lv_data.setAdapter(adapter);
要注意的是在adapter中我们使用了
setViewBinder

方法,这是为了实现数据绑定。SimpleAdapter的定义

这是一个简单的适配器,可以将静态数据映射到XML文件中定义好的视图。你可以指定由Map组成的List(比如ArrayList)类型的数据。在ArrayList中的每个条目对应List中的一行。Maps包含每一行的数据。你可以指定一个XML布局以指定每一行的视图,根据Map中的数据映射关键字到指定的视图。绑定数据到视图分两个阶段,首先,如果设置了SimpleAdapter.ViewBinder,那么这个设置的ViewBinder的setViewValue(android.view.View, Object, String)将被调用。如果setViewValue的返回值是true,则表示绑定已经完成,将不再调用系统默认的绑定实现。如果返回值为false,视图将按以下顺序绑定数据:
  • 如果View实现了Checkable(例如CheckBox),期望绑定值是一个布尔类型。
  • TextView.期望绑定值是一个字符串类型,通过调用setViewText(TextView, String)绑定。
  • ImageView,期望绑定值是一个资源id或者一个字符串,通过调用setViewImage(ImageView, int) 或 setViewImage(ImageView, String)绑定数据。
所以要绑定图片要使用setViewValue。或者绑定其他操作 比如ListView中每一行有一个按钮,对按钮添加响应事件。

系统对每一个view调用binder的setViewValue(此例中是ImageView),我们首先检测这个view是不是一个ImageView,然后获取的数据是不是Bitmap.

if (view instanceof ImageView && data instanceof Bitmap) 

如果是的话就进行如下操作

 ImageView iv = (ImageView) view;
 iv.setImageBitmap((Bitmap) data);

这样就可以显示网络传来的图片了。

注意,还要在代码中添加如下代码,用于图片显示。需要导入universal-image-loader-1.9.2-with-sources.jar包。

//此段代码必须在onCreate方法第一行编写
        //用于调用img图片的调用  1.
        StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
        StrictMode.setThreadPolicy(policy);

        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_goods_list);
        //配置ImageLoader基本信息,必须在实例化ImageLoad之前配置
        //用于调用img图片的调用  2.
        DisplayImageOptions defaultOptions = new DisplayImageOptions.Builder()
                .cacheInMemory().cacheOnDisc().build();
        ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(
                getApplicationContext()).defaultDisplayImageOptions(defaultOptions)
                .threadPriority(Thread.NORM_PRIORITY - 2)
                .denyCacheImageMultipleSizesInMemory()
                .tasksProcessingOrder(QueueProcessingType.LIFO).build();

        imageLoader = ImageLoader.getInstance();
        //初始化配置
        imageLoader.init(config);

要是ListView中每一行有一个按钮的话可以用一下代码

 SimpleAdapter.ViewBinder binder = new SimpleAdapter.ViewBinder() {

            @Override
            public boolean setViewValue(View view, Object data, String textRepresentation) {
                if (view instanceof Button) {
                    final View button = view;
//                    button.setBackgroundDrawable(getResources().getDrawable(R.drawable.ic_launcher));
                    view.setOnClickListener(new OnClickListener() {
                        LinearLayout listItem = (LinearLayout) button.getParent();
                        TextView tv = (TextView) listItem.findViewById(R.id.text);

                        @Override
                        public void onClick(View v) {
                            Toast.makeText(AdapterDemoActivity.this, tv.getText(), Toast.LENGTH_SHORT).show();
                        }
                    });
                    return false;
                }
                return false;
            }
        };

getParent()函数取得parentView以找到这个view的兄弟view,就是那个listitme布局。比如这个例子中的实现就是点击Button后输出这个Button所在的ListItem中的TextView上的文字.

6、SimpleCursorAdapter,可以实现手机联系人输入姓弹出以这个姓为名的人的列表。详细可以参考,转发http://blog.csdn.net/iispring/article/details/50793455

7、自定义Adapter:

看下篇博客



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值