AdapterView与Adapter

一、概述

AdapterView不仅仅是UI,同时还将数据关联到UI上,例如在手机中经常使用的ListView就是AdapterView。

他的实现过程就类似于MVC框架(MVC框架,实现原理:数据模型M(Model)存放数据,处理业务逻辑,利用控制器C(Controller)将数据显示在视图V(View)上。)。他的使用不像其他控件一样,拖拽到界面上就能用,而是需要通过适配器将某些样式的数据或控件添加到其上而使用。

(1)将前端显示和后端数据分离

(2)内容不能通过ListView.add的形式添加列表项,需指定一个Adapter对象,通过它获得显示数据

(3)ListView相当于MVC框架中的V(视图)

(4)Adapter相当于MVC框架中的C(控制器)

(5)数据源相当于MVC框架中的M(模型)

(6)超出屏幕显示之后,自动加上滚动条 

二、AdapterView

 AdapterView继承了ViewGroup,它的本质是容器

AdapterView 可以包含多个 “列表项”,并将多个“列表项”以合适的形式显示出来

AdapterView显示的多个“列表项”由Adapter提供

AdapterView与Adapter

 

分类

(1)ListView:列表

(2)Spinner:下拉列表,给用户提供选择

(3)Gallery:缩略图,已经被水平的ScrollView和ViewPicker取代,但也还算常用,是一个可以把子项以中心锁定,水平滚动的列表

(4)GridView:网格图,以表格形式显示资源,可以左右滑动的

ScrollView  如果一个页面内容以及超出了屏幕,可以使用ScrollView,里面只能放一个布局或者控件

事件

(1)用户单击列表项事件

◆为列表加载setOnItemClieckListener监听,重写onItemClick(发生单击事件的列表对象ListView,被单击控件对象view,

在列表中的位置position,被单击列表项的行ID)方法。

(2)用户长按事件

◆为列表加载setOnItemLongClieckListener监听,重写onItemLongClick(发生单击事件的列表对象ListView,被单击控件对象view,

在列表中的位置position,被单击列表项的行ID)方法。

三、Adapter(C)

把数据源中数据以某种样式(xml文件)显示在视图中。

Adapter的类关系图

AdapterView与Adapter

 

分类

Adapter常用的实现类

1、ArrrayAdapter:简单、易用,通常用于数组或List集合的多个值包装成多个列表项

2、SimpleAdapter:功能有点强,可用于将List集合的多个对象包装成多个列表项

3、SimpleCursorAdapter:与SimpleAdapter基本相似,只是用于包装Cursor提供的数据

4、BaseAdapter:通常用于被扩展。扩展BaseAdapter可以对各列表项进行最大限度的定制

      实现BaseAdapter

扩展BaseAdapter可以取得对Adapter最大的控制权:程序要创建多少个列表项,每个列表项的组件都由开发者来决定。

比较*

扩展该对象需要重写如下4个方法:

1、getCount():该方法的返回控制该Adapter将会包含多少个列表项

2、getItem(int position):该方法的返回值决定第position处的列表项的内容

3、getItemId(int position):该方法的返回值决定第position处的列表项的ID

4、getView(it position,View convertView,viewGroup parent):该方法的返回值决定第position处的列表项组件

//数组适配器ArrayAdapter

   1、先获得一个ListView 对象  布局里面写一个ListView控件,Activity里面findViewById返回一个ListView对象

   2、获得一个数组或者集合的数据类型,元素为单一的数据

   3、适配器:子item布局、布局里面控件的ID

//例子

ListView 与ArrayAdapter

private ListView lv;

 String[] datas = {"Android","Ios","Java","Php",".Net"};

lv = (ListView) findViewById(R.id.lv);

        //数组适配器   朱能放一个数据

        //参数1  上下文对象

        //参数2 布局

        //参数3 控件ID

        //参数4 数据源  数组  集合

//        ArrayAdapter<String>  adapter = new ArrayAdapter<String>

//        (this, R.layout.lv_textview, R.id.tv, datas);

        //布局也可以使用系统自带

        ArrayAdapter<String>  adapter = new ArrayAdapter<String>

        (this, android.R.layout.activity_list_item, android.R.id.text1, datas);

        //关联adapterView和Adater

        lv.setAdapter(adapter);

AdapterView的属性

AdapterView与Adapter

 

listView的属性

AdapterView与Adapter

 

适配器更新数据

加载数据在子线程(主线程不能经历耗时操作)

原因

//View只能在主线程中刷新和绘制

AdapterView与Adapter

Handler 线程与线程之间的通信

Handler  handler = new Handler(){

        //handler接收子线程发送的消息

        @Override

        public void handleMessage(Message msg) {

            super.handleMessage(msg);

            Log.i("msg", "handler调用");

            switch (msg.what) {

            case 0:

                adapter.notifyDataSetChanged();//刷新适配器

                break;

            default:

                break;

            }

        }

    };

    class MyThread extends Thread{

        @Override

        public void run() {

            try {

                Thread.sleep(3000);

            } catch (InterruptedException e) {

                e.printStackTrace();

            }

            list.add("C++");

            handler.sendEmptyMessage(0);//handler发送一个消息

        }

    }

//SimpleApadter

package com.bwf.a18_adapterview;

import java.util.ArrayList;

import java.util.HashMap;

import java.util.List;

import java.util.Map;

import android.app.Activity;

import android.os.Bundle;

import android.util.Log;

import android.view.View;

import android.widget.AdapterView;

import android.widget.AdapterView.OnItemClickListener;

import android.widget.ListView;

import android.widget.SimpleAdapter;

import android.widget.TextView;

public class SimpleAdapterActivity extends Activity{

    private ListView lv = null;

    private SimpleAdapter adapter;

    //数据源

    private List<Map<String, Object>>  datas = new ArrayList<Map<String,Object>>();

    @Override

    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.listview);

//        lv = (ListView)findViewById(R.id.lv);

        lv = (ListView) findViewById(R.id.lv);

        //获得数据源

        //第一列

        Map<String , Object> map1 = new HashMap<String, Object>();

        map1.put("project", "Android");

        map1.put("score", "100");

        map1.put("img", R.drawable.iamge1);

        //第二列

        Map<String , Object> map2 = new HashMap<String, Object>();

        map2.put("project", "Java");

        map2.put("score", "70");

        map2.put("img", R.drawable.image2);

        //第三列

        Map<String , Object> map3 = new HashMap<String, Object>();

        map3.put("project", "C++");

        map3.put("score", "90");

        map3.put("img", R.drawable.image3);

        //第四列

        Map<String , Object> map4 = new HashMap<String, Object>();

        map4.put("project", "PHP");

        map4.put("score", "69");

        map4.put("img", R.drawable.iamge4);

        //把每列数据添加到数据源的集合中

        datas.add(map1);

        datas.add(map2);

        datas.add(map3);

        datas.add(map4);

        //简单适配器

        //1 上下文对象

        //2 数据源

        //3 item的layout

        //4 字符串数组  map 的key

        //5 整数数组  控件id

        adapter = new SimpleAdapter(this, datas, R.layout.simple_item, 

                new String[]{"img" , "project" , "score"}, new int[]{R.id.simple_img,R.id.simple_tv,R.id.simple_btn});

        lv.setAdapter(adapter);//绑定适配器

        //设置每个item的监听

        lv.setOnItemClickListener(new OnItemClickListener() {

            //position  点击的item位置 从0开始 

            //view  每个item的view对象

            @Override

            public void onItemClick(AdapterView<?> parent, View view,

                    int position, long id) {

                //获得Item的每个子View

                TextView tv = (TextView) view.findViewById(R.id.simple_tv);

//                TextView tv = (TextView) view.getChildAt(1);

                Log.i("msg", tv.getText().toString());

            }

        });

    }

}

08-30 16:38:57.548: E/AndroidRuntime(25872): android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.

只有主线程可以创建一个view和修改一个view    

总结:

    1、AdapterView与Adapter的组成,原理

          MVC:  V:ListView  C: Adapter  M:模型  数据源  业务逻辑和数据处理

    2、ArrayAdapter+ListView  

             1、特点:只能放一个TextView的内容

             2、可以使用系统自带的布局

   3、ListView的属性和方法

   4、SimpleAapter+ListView

         1、可以放多个控件(CheckBOx、TextView、ImageView)

   5、Handler 做线程之间的通信 

   6、Adapter刷新数据notifyDataSetChanged  必须在主线程中刷新View

上一篇:URL和URI的区别


下一篇:Flutter ScrollView或ListView的子View是否露出显示