所谓高级控件就是指不能拖过来直接用的控件,咱们须要在对它们进行管理和控制以后才能使用,与之一块儿使用的还有一些对应的控制器、相关数据集等。这一篇里咱们先简单介绍一下高级控件中的AdapterView控件,固然咱们也须要先要知道与之对应的控制器——适配器Adapter,以及数据源DataSource,和三者之间的关系。
java
咱们都应该听过或者了解MVC框架吧,MVC全名是Model View Controller,是模型(model)-视图(view)-控制器(controller)的缩写,一种软件设计典范,用于组织代码用一种业务逻辑和数据显示分离的方法,这个方法的假设前提是若是业务逻辑被汇集到一个部件里面,并且界面和用户围绕数据的交互能被改进和个性化定制而不须要从新编写业务逻辑MVC被独特的发展起来用于映射传统的输入、处理和输出功能在一个逻辑的图形化用户界面的结构中。MVC的结构图以下:android
到此为止,咱们已经明白了这个框架的原理,简单的来讲就是利用控制器(C)将数据集(M)与视图(V)对应起来。好吧,咱们用这个思想说说Adapter、AdapterView和DataSource之间的关系:
app
Adapter——C(控制器)框架
AdapterView——V(视图)less
DataSource——M(数据集)ide
明白了这个关系,咱们就能够进入今天的主讲内容了:布局
(1)Adapter类及其相关类和接口;
测试
(2)AdapterView控件之一ListView;this
1.ArrayAdapter类的使用spa
经过ArrayAdapter咱们只能绑定数据到TextView控件中,其余的很少说,直接看下面的代码,注意的地方我都标记了注释:
(1)MainActivity.java
package com.example.arrayadapter; import android.app.Activity; import android.os.Bundle; import android.widget.ArrayAdapter; import android.widget.ListView; public class MainActivity extends Activity { //声明视图ListView控件 private ListView lv; //声明适配器(控制器)ArrayAdapter private ArrayAdapter<String> aAdapter; //声明并定义数据源 private String datas[]={ "Wireless & networks","Call settings","Sound","Display","Location & security", "Applications","Accounts & sync","Privacy","CD card & phone storage","Search","Language & keyboard", "Voice input & output","Accessibility","Date & Time","About phone"}; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //实现适配器,包括三个参数 aAdapter=new ArrayAdapter<String>(this, R.layout.cell,datas); lv=(ListView)findViewById(R.id.listView1); //经过Adapter的setAdapter方法绑定数据于视图 lv.setAdapter(aAdapter); } }
(2)activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#000000" tools:context=".MainActivity" > <ListView android:id="@+id/listView1" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_weight="1" > </ListView> </LinearLayout>
(3)引入的资源文件cell.xml
<?xml version="1.0" encoding="utf-8"?> <TextView xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="50dip" android:gravity="center_vertical" android:id="@+id/tv" android:textColor="#ffffff"></TextView>
(4)实现效果以下:
2.SimpleAdapter类的使用
相对于ArrayAdapter而言SimpleAdapter的实现的功能更全面一些,不只可也实现TextView的绑定,还能够在引用的资源文件(cell.xml)中使用布局,从而绑定ImageView等其余一些控件,接下来咱们就来完善上面这个布局:
(1)MainActivity.java
package com.example.arrayadapter; 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.widget.ListView; import android.widget.SimpleAdapter; public class MainActivity extends Activity { //声明视图ListView控件 private ListView lv; //声明适配器(控制器)SimpleAdapter private SimpleAdapter sAdapter; //声明List和Map存放数据 private List<Map<String,Object>> lists; private Map<String ,Object> maps; //声明并定义数据源 private String datas[]={ "Wireless & networks","Call settings","Sound","Display","Location & security", "Applications","Accounts & sync","Privacy","CD card & phone storage","Search", "Language & keyboard","Voice input & output","Accessibility","Date & Time","About phone"}; private int p_w_picpath[]={ R.drawable.ic_settings_wireless,R.drawable.ic_settings_call,R.drawable.ic_settings_sound, R.drawable.ic_settings_display,R.drawable.ic_settings_location,R.drawable.ic_settings_applications, R.drawable.ic_settings_sync,R.drawable.ic_bt_config,R.drawable.ic_settings_sim, R.drawable.ic_power_system,R.drawable.ic_settings_language,R.drawable.ic_settings_voice_calls, R.drawable.ic_settings_accessibility,R.drawable.ic_settings_date_time,R.drawable.ic_settings_about}; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); lv=(ListView)findViewById(R.id.listView1); lists=new ArrayList<Map<String,Object>>(); //经过for循环添加数据 for(int i=0;i<p_w_picpath.length;i++){ maps=new HashMap<String,Object>(); maps.put("data", datas[i]); maps.put("p_w_picpath", p_w_picpath[i]); lists.add(maps); } //实现SimpleAdapter适配器,有5个参数 sAdapter=new SimpleAdapter(this, lists, R.layout.cell, new String[]{"data","p_w_picpath"}, new int[]{R.id.tv,R.id.iv}); //经过Adapter的setAdapter方法绑定数据于视图 lv.setAdapter(sAdapter); } }
(2)activity_main.java同上
(3)资源文件cell.java
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="horizontal" tools:context=".MainActivity" > <ImageView android:layout_width="50dip" android:layout_height="50dip" android:id="@+id/iv"/> <TextView android:layout_width="fill_parent" android:layout_height="50dip" android:gravity="center_vertical" android:id="@+id/tv" android:textColor="#ffffff"></TextView> </LinearLayout>
(4)测试结果图:
3.自定义的Adapter——BaseAdapter的使用:
若是系统提供的适配器不能知足开发人员的要求,咱们也能够经过BaseAdapter来自定义知足须要的适配器,这里为了说明状况咱们就用BaseAdapter自定义的适配器(下面咱们叫MyAdapter)来完成和上面相同的功能。
(1)MyAdapter.java(新建的类,实现自定义的适配器)
package myAdapter; import android.content.Context; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.TextView; import com.example.arrayadapter.R; public class MyAdapter extends BaseAdapter{ private Context context; private String data[]; private int p_w_picpath[]; public MyAdapter(Context context,String[] data,int[] p_w_picpath){ this.context=context; this.data=data; this.p_w_picpath=p_w_picpath; } //重写一下四个方法,并修改返回值 @Override public int getCount() { return this.data.length; } @Override public Object getItem(int position) { return data[position]; } @Override public long getItemId(int position) { return position; } //这个重写的方法是最重要的,用于加载视图 @Override public View getView(int position, View convertView, ViewGroup parent) { LayoutInflater lif=(LayoutInflater) context.getSystemService(context.LAYOUT_INFLATER_SERVICE); LinearLayout layout=(LinearLayout) lif.inflate(R.layout.cell, null); TextView tv=(TextView)layout.findViewById(R.id.tv); ImageView iv=(ImageView)layout.findViewById(R.id.iv); tv.setText(data[position]); iv.setBackgroundResource(p_w_picpath[position]); return layout; } }
(2)MainActivity.java
package com.example.arrayadapter; import myAdapter.MyAdapter; import android.app.Activity; import android.os.Bundle; import android.widget.ListView; public class MainActivity extends Activity { //声明视图ListView控件 private ListView lv; //声明适配器(控制器)MyAdapter private MyAdapter mAdapter; //声明并定义数据源 private String datas[]={ "Wireless & networks","Call settings","Sound","Display","Location & security", "Applications","Accounts & sync","Privacy","CD card & phone storage","Search", "Language & keyboard","Voice input & output","Accessibility","Date & Time","About phone"}; private int p_w_picpath[]={ R.drawable.ic_settings_wireless,R.drawable.ic_settings_call,R.drawable.ic_settings_sound, R.drawable.ic_settings_display,R.drawable.ic_settings_location,R.drawable.ic_settings_applications, R.drawable.ic_settings_sync,R.drawable.ic_bt_config,R.drawable.ic_settings_sim, R.drawable.ic_power_system,R.drawable.ic_settings_language,R.drawable.ic_settings_voice_calls, R.drawable.ic_settings_accessibility,R.drawable.ic_settings_date_time,R.drawable.ic_settings_about}; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); lv=(ListView)findViewById(R.id.listView1); //实现MyAdapter适配器 mAdapter=new MyAdapter(this,datas,p_w_picpath); //经过Adapter的setAdapter方法绑定数据于视图 lv.setAdapter(mAdapter); } }
(3)运行效果:
(4)最后补充一个问题——ListView的缓冲
让咱们来看一下MyAdapter.java代码:
public View getView(int position, View convertView, ViewGroup parent) { ViewHolder holder; if (convertView == null) { convertView = LayoutInflater.from(context). inflate(R.layout.cell,null); holder = new ViewHolder(); holder.tv = (TextView) convertView.findViewById(R.id.tv); holder.iv = (ImageView) convertView.findViewById(R.id.iv); convertView.setTag(holder); } else { holder = (ViewHolder) convertView.getTag(); } holder.tv.setText(data[position]); holder.iv.setBackgroundResource(p_w_picpath[position]); return convertView; } private static class ViewHolder { TextView tv; ImageView iv; }