一.Adapter的概述

  • ArrayAdapter
  • SimpleAdapter
  • SimpleCursorAdapter
  • BaseAdapter及自定义Adapter
  • Adapter控件

1.Adapter适配器

  • Adapter对象在Adapter控件和数据源之间扮演桥梁的角色。提供访问数据源的入口,把从数据源拿到的数据项逐项加载到Adapter控件中。

2.四种Adapter适配器

  • ArrayAdapter
  • SimpleAdapter
  • SimpleCursorAdapter
  • 自定义的Adapter(继承自BaseAdapter)

二.AutoCompleteTextView控件

1.AutoCompleteTextView概述

  • AutoCompleteTextView类继承自EditText类
  • 与EditText控件是一样的
  • 当用户输入了不事先为该控件定义的一组字符串集中相关的信息时,才会出现下拉选项,供用户选择

2.例子一

Android Adapter机制 安卓开发adapter_控件

public class MainActivity extends Activity {

    private AutoCompleteTextView autoCompleteTextView;

    String[] contents = new String[]{"China","China1",
            "china2","USA","USA1","USA2","唱歌","china",
            "cd","ch","chi","chin"};


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initView();
    }

    private void initView() {
        autoCompleteTextView=(AutoCompleteTextView) findViewById(R.id.autoCompleteTextView1);

        ArrayAdapter<String> arrayAdapter=new ArrayAdapter<String>(MainActivity.this,android.R.layout.simple_list_item_1,contents);  

        autoCompleteTextView.setAdapter(arrayAdapter);

        autoCompleteTextView.setThreshold(2);//输入一个字母就开始自动提示,这里是设置输出第几个才提示

    }



}

三.Spinner控件

1.Spinner控件概述

  • Spinner下拉列表,外观是一个一行的列表框,用户单击控件,下拉出选项列表供用户选择
  • Spinner每次只显示用户选中的元素
  • 为Spinner加载数据的两种方式
  • 方式1:在XML文件中先定义好要加载的数据资源,然后使用ArrayAdapter.createFromResource()把资源加载进来
  • 方式2:直接在Java代码中使用ArrayAdapter对象,把List<T>中的数据资源加载到Spinner中
  • 事件监听——onItemSelectedListener
  • 使用setOnItemSelectedListener()方法设置监听,传入一个实现了Spinner.onItemSelectedListener接口的匿名内部类对象,同时实现接口的onItemSelected方法,通过传入的position参数完成匹配

2.例子一

Android Adapter机制 安卓开发adapter_控件_02

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string-array name = "corse_array">
        <item>Android应用开发</item>
        <item>Java程序设计</item>
        <item>Java Web应用开发</item>
        <item>Html5应用开发</item>
        <item>软件项目管理</item>
    </string-array>

</resources>
public class MainActivity extends Activity {

    private Spinner spinner;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initView();
    }

    private void initView() {

        spinner=(Spinner) findViewById(R.id.spinner1);

        //将可选内容与ArrayAdapter连接起来

        final ArrayAdapter<CharSequence> adapter1=ArrayAdapter.createFromResource(MainActivity.this,R.array.corse_array,android.R.layout.simple_spinner_item);

        //设置下拉列表的风格
        adapter1.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);

        spinner.setAdapter(adapter1);

        spinner.setPrompt("请选择课程");//标题

        spinner.setSelection(0,true);//设置默认

        spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {

            @Override
            public void onItemSelected(AdapterView<?> arg0, View arg1,
                    int position, long arg3) {
                // TODO Auto-generated method stub
                String choice = getResources().getStringArray(R.array.corse_array)[position];
                Toast.makeText(MainActivity.this,
                        "你选的是"+choice, Toast.LENGTH_SHORT).show();
            }

            @Override
            public void onNothingSelected(AdapterView<?> arg0) {
                // TODO Auto-generated method stub

            }
        });

    }



}

四.ListView控件

1.ListView控件概述

  • 以列表形式展示内容,并根据数据的长度自适应显示
  • 继承ListActivity或在Activity布局中加入ListView控件
  • 采用MVC模式将前端显示不后端数据分离
  • 提供数据的List或数组相当于Model
  • ListView相当于视图View
  • Adapter对象相当于Control
  • 指定Adapter对象,通过Adapter获取要显示的数据

2.为ListView填充数据

  • 使用Adapter对象给ListView填充数据
  • ArrayAdapter:适用于列表项只含有文本信息的情况
  • SimpleAdapter:适用于每一个列表项中含有不同的子控件,比如图片+文本+按钮的
  • SimpleCursorAdapter:专门用来把一个Cursor中的数据映射到列表中,Cursor中的每一条数据映射为列表中的一项
  • 自定义Adapter:继承BaseAdapter,完全自定义数据适配方式,灵活性最强

3.响应用户事件

(1).响应用户单击事件

  • setOnItemClickListener()绑定
//AdapterView.OnItemClickListener接口,实现onItemClick方法,在其中进行单击事件处理
list.setOnItemClickListener(new AdapterView.OnItemClickListener(){……}})
parent:发生单击动作的ListView对象
view:在ListView中被单击的View
position:点击项在ListView中的位置
id:点击项的行id

(2).响应用户长按事件

  • setOnItemLongClickListener()绑定
//AdapterView.OnItemLongClickListener接口,实现onItemLongClick方法,在其中进行长按事件处理
list.setOnLongItemClickListener(new AdapterView.OnItemLongClickListener(){……})
parent:发生单击动作的ListView对象
view:在ListView中被长按的View
position:被长按的列表项在ListView中的位置
id:被长按的列表项的行id

4.例子-ArrayAdapter

Android Adapter机制 安卓开发adapter_Android Adapter机制_03

public class MainActivity extends Activity {

    private ListView listView;

    private List<String> stringlist;

    private ArrayAdapter<String> adapter;   
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initView();
    }

    private void initView() {

        listView=(ListView) findViewById(R.id.listView1);

        stringlist=new ArrayList<String>();

        for(int i=1;i<=50;i++){
            stringlist.add("ListView 这个第"+i+"个文本");
        }

        adapter=new ArrayAdapter<String>(this,R.layout.array_adapter_item,stringlist);

        listView.setAdapter(adapter);

        listView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
            @Override
            public boolean onItemLongClick(AdapterView<?> parent, View view, int position,
                    long id) {
                final int pos=position;
                new AlertDialog.Builder(MainActivity.this)
                .setTitle("是否要删除?")
                .setPositiveButton("确定",new OnClickListener() {

                    @Override
                    public void onClick(DialogInterface arg0, int arg1) {
                        stringlist.remove(pos);
                        adapter.notifyDataSetChanged();

                    }
                })
                .setNegativeButton("取消",null)
                .setIcon(R.drawable.ic_launcher)
                .create()
                .show();

                return true;
            }
        });

        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position,
                    long id) {



            }
        });
    }





}

5.例子-SimpleAdapter

Android Adapter机制 安卓开发adapter_控件_04

public class MainActivity extends Activity {

    private List<Map<String,Object>> stringlist;

    private ListView listView;

    private SimpleAdapter adapter;  
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initView();
    }

    private void initView() {

        listView=(ListView) findViewById(R.id.listView1);

        stringlist=new ArrayList<Map<String,Object>>();

        for(int i=1;i<=50;i++){
            Map<String,Object> map=new HashMap<String, Object>();
            map.put("img",R.drawable.ic_launcher);
            map.put("text","我的名字叫"+i);
            map.put("cbx", i);
            map.put("btn", i);
            stringlist.add(map);
        }

        adapter=new SimpleAdapter(MainActivity.this,stringlist,R.layout.simple_list_item,new String[] {"img","text","cbx","btn"}, 
                new int[]{R.id.simple_image,R.id.simple_text,R.id.simple_cbx,R.id.simple_btn});//R.layout.simple_list_item自己写的 对于ListView每一个控件的风格

        listView.setAdapter(adapter);

    }

}

Android Adapter机制 安卓开发adapter_Android Adapter机制_05

  • SimpleAdapter的弊端
  • 附带事件的组件(Button、CheckBox)无法将数据映射在ListView上
  • 继承BaseAdapter,自定义适配器实现事件监听
  • 丰富每一个Item的显示效果
  • 如交替背景色、便捷的事件监听

6.自定义Adapter

(1).自定义Adapter步骤

  • 继承自BaseAdapter
  • 实现方法
  • 构造方法(类似SimpleAdapter)
  • getCount
  • getItem
  • getItemId
  • getView
  • 添加事件监听

(2).例子一

Android Adapter机制 安卓开发adapter_android_06

public class MyAdapter extends BaseAdapter {//自定义Adapter要继承BaseAdapter

    public List<Map<String,Object>> lists;//好友集合列表

    public Context context;//上下文对象

    public LayoutInflater layoutInflater;//视图容器

    public MyAdapter(Context context,List<Map<String,Object>> lists) {
               this.context=context;
               layoutInflater=LayoutInflater.from(context);
               this.lists=lists;
    }
    @Override
    public int getCount() {
        // TODO Auto-generated method stub
        return lists.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) {

        final int pos=position;
        ViewHolder holder=null;

        if(convertView==null){

            holder=new ViewHolder();
            //获取list_item布局文件的视图
            convertView=layoutInflater.inflate(R.layout.friend_list_item,null);
            //获取控件
            holder.image=(ImageView) convertView.findViewById(R.id.iv_friend);
            holder.name=(TextView) convertView.findViewById(R.id.tv_friend_name);
            holder.msg=(TextView) convertView.findViewById(R.id.tv_friend_msg);
            holder.detail=(Button) convertView.findViewById(R.id.btn_friend_detail);
            //设置控件集到convertView
            convertView.setTag(holder);

        }else{

            holder=(ViewHolder) convertView.getTag();
        }

        holder.image.setImageResource((Integer)lists.get(position).get("image"));
        holder.name.setText((String) lists.get(position).get("name"));
        holder.msg.setText((String) lists.get(position).get("msg"));
        holder.detail.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View arg0) {
                // TODO Auto-generated method stub
                new AlertDialog.Builder(context)
                    .setIcon((Integer) lists.get(pos).get("image"))
                    .setTitle((String) lists.get(pos).get("name"))
                    .setMessage((String) lists.get(pos).get("info"))
                    .setPositiveButton("确定", null)
                    .create()
                    .show();
            }
        });
        return convertView;
    }

    public class ViewHolder{
            public ImageView image;//图片
            public TextView name;    //名字
            public TextView msg; //长段话
            public Button detail;//按钮
    }

}
public class MainActivity extends Activity {

    private List<Map<String,Object>> stringlist;

    private ListView listView;

    private MyAdapter adapter;  

    private Integer[] imgeIDs = {R.drawable.baigujing,R.drawable.sunwukong,
            R.drawable.shaseng,R.drawable.shaseng,R.drawable.guanyin,
            R.drawable.baigujing,R.drawable.baigujing};

    private String[] friendNames = {"女儿国王", "孙悟空",   
            "猪八戒", "沙僧", "观音姐姐", "白骨精","东海龙女"}; 

    private String[] msgs = {"御弟哥哥,你好哇","师傅,小心妖怪","师傅,咱歇一歇",
            "师傅,请喝水","你太墨迹了","吃你的肉可以长生?","你想干啥?"};

    private String[] infos = {"相见难,别亦难,怎诉这胸中语万千","孙悟空是我的大徒弟!","猪八戒就是一头懒猪!",
            "沙悟净是个听话的好徒儿!","救苦救难观世音菩萨","白骨精,一直想吃我的肉,可惜你没后台!","小龙女,你在干啥?"};

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initView();
    }

    private void initView() {

        listView=(ListView) findViewById(R.id.friendlist);

        stringlist=getStringlist();

        adapter=new MyAdapter(this,stringlist);

        listView.setAdapter(adapter);

         listView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
             @Override
             public boolean onItemLongClick(AdapterView<?> parent, View view, int position,
                     long id) {
                 final int pos=position;
                 new AlertDialog.Builder(MainActivity.this)
                 .setTitle("是否要删除?")
                 .setPositiveButton("确定",new OnClickListener() {

                     @Override
                     public void onClick(DialogInterface arg0, int arg1) {
                         stringlist.remove(pos);
                         adapter.notifyDataSetChanged();

                     }
                 })
                 .setNegativeButton("取消",null)
                 .setIcon(R.drawable.ic_launcher)
                 .create()
                 .show();

                 return true;
             }
         });

         listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
             @Override
             public void onItemClick(AdapterView<?> parent, View view, int position,
                     long id) {



             }
         });
     }


    private List<Map<String, Object>> getStringlist() {
        stringlist=new ArrayList<Map<String,Object>>();

        for(int i=0;i<friendNames.length;i++){
            Map<String,Object> map=new HashMap<String, Object>();
            map.put("image", imgeIDs[i]);  //图片资源 
            map.put("name", friendNames[i]);  //好友名称  
            map.put("msg", msgs[i]); //最新消息
            map.put("info", infos[i]);
            stringlist.add(map);
        }
        return stringlist;
    }





}

7.ListView缓存原理及优化

  • 有多少行数据就需要绘制多少行Item,findViewById执行多次,极大地消耗了系统资源
  • 当启动Activity呈现第一屏ListView的时候,convertView为零
  • convertView相当于一个缓存,开始为0,当有条目变为不可见,它缓存了它的数据,后面再出来的条目只需要更新数据就可以了,这样大大节省了系统资料的开销
  • 利用convertView实现缓存
条目不可见时,缓存数据,新的条目使用已经实例化的组件
ViewHolder
setTag(holder)为每个View绑定一个存放控件的ViewHolder对象
getTag()避免了findViewById对控件的层层查询,而是快速定位到控件

END!!!!!!!!!!!