Adapter详解

Adapter是适配器。它的作用是封装好item然后将数据提供给ListView去显示。
Adapter原理分析:
这里写图片描述
ListView显示的时候,首先会去调用适配器,适配器去数据源读取数据并根据item布局组织成一个item view对象返回在ListView中显示。

ArrayAdapter

ArrayAdapter是最简单的适配器,用于为ListView提供承载简单数据的item界面。它的数据源必须是数组或简单List集合。它加载的item布局中必须包括至少一个TextView控件,数据源中的数据将逐条显示在每一个itemview的TextView控件中。只能用于显示文本数据。
我们用ArrayAdapter来显示国乒七虎将的名字效果如下:
这里写图片描述
代码如下:
activity_main.xml

<ListView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/lvFriends"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    >
</ListView>

item.xml

<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="100dp"
    android:textSize="30sp"
    >
</TextView>

MainActivity.java

public class MainActivity extends AppCompatActivity {
    private ListView lv;
    private ArrayAdapter<String> adapter;
    private void setupView(){
        //获取ListView实例
        lv=(ListView) findViewById(R.id.lvFriends);
        //获取数据
        String[] heros={"马龙","张继科","许昕","樊振东","方博","闫安","周雨"};
        //获得适配器实例
        adapter=new ArrayAdapter<String>(this,R.layout.item,heros);
        //为ListView控件设置适配器
        lv.setAdapter(adapter);
    }
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        setupView();
    }
}

SimpleAdapter

SimpleAdapter是一种简单的通用适配器,它的数据源必须是由结构相同的Map集合构成的List集合,每个Map中的数据将被显示在Item中,所以必须为item中的每个控件指定该控件对应显示的值是Map对象中哪个key对应的值。也即需要为Map对象中的key与Item界面中的控件id建立对应关系。
SimpleAdapter的构造方法:
SimpleAdapter(Context context,List<Map<String,Object>> data,int layoutRes,String[] from,int[] to )

-data :必须是由结构相同的Map集合构成的List集合
-layoutRes :item的布局资源id
-from :map集合的key构成的数组
-to :item布局中的控件id构成的数组

我们通过一个例子来说明下它的用法:列表左边显示照片,右边显示姓名
这里写图片描述
代码如下:
activity_main.xml

<ListView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/lv"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    >

</ListView>

item.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal"
    >
    <ImageView
        android:id="@+id/ivPhoto"
        android:layout_width="80dp"
        android:layout_height="80dp"
        />
    <TextView
        android:id="@+id/tvName"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1.0"
        android:layout_gravity="center"
        />
</LinearLayout>

DataSource.java

public class DataSource {

    public static List<HashMap<String,Object>> getData(){
        List<HashMap<String,Object>> lists=new ArrayList<HashMap<String,Object>>();
        HashMap<String,Object> item=new HashMap<String,Object>();
            item.put("photo",R.mipmap.w5);
            item.put("name","福原爱1");
        lists.add(item);
        item=new HashMap<String,Object>();
            item.put("photo",R.mipmap.w1);
            item.put("name","福原爱2");
        lists.add(item);
        item=new HashMap<String,Object>();
        item.put("photo",R.mipmap.w3);
        item.put("name","福原爱3");
        lists.add(item);
        item=new HashMap<String,Object>();
        item.put("photo",R.mipmap.w2);
        item.put("name","福原爱4");
        lists.add(item);
        item=new HashMap<String,Object>();
        item.put("photo",R.mipmap.w4);
        item.put("name","福原爱5");
        lists.add(item);
        return lists;
    }
}

MainActivity.java

public class MainActivity extends AppCompatActivity {
    private ListView lv;
    private SimpleAdapter adapter;
    private void setupView(){
        lv=(ListView) findViewById(R.id.lv);
        //获取数据源
        List<HashMap<String,Object>> list=DataSource.getData();
        //from与to的顺序要保持一致
        String[] from={"photo","name"};
        int[] to={R.id.ivPhoto,R.id.tvName};
        adapter=new SimpleAdapter(this,list,R.layout.item,from,to);
        lv.setAdapter(adapter);
    }
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        setupView();
    }
}

自定义Adapter

在Android中,除了使用通用适配器之外,我们还可以通过继承Adapter接口的实现类BaseAdapter的方式来自定义适配器。BaseAdapter中有四个抽象方法必须被实现。其中与列表项显示相关的方法有两个:getCount()方法和getView(int position,View convertView,ViewGroup parent)。其中getCount方法返回数据集长度。而getView方法的作用主要是根据参数position,从数据集中获取指定位置的数据,并将之加载在item界面上返回给ListView。有一些复杂的列表项必须通过自定义Adapter来实现。
这里写图片描述
在这个程序中,我们对是否加载到最后当前页最后一条做了判断,如果加载到最后一条就继续加载,对列表项单击事件做了处理,在dailog显示学生信息。
代码如下:
activity_main.xml

<ListView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/lv"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    >
</ListView>

stu_item.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/llItem"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal"
    >
    <ImageView
        android:layout_width="80dp"
        android:layout_height="80dp"
        android:src="@mipmap/ic_launcher"
        />
    <TableLayout
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1.0">
        <TableRow>
            <TextView
                android:id="@+id/tvId"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1.0"/>
            <TextView
                android:id="@+id/tvName"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1.0"/>
        </TableRow>
        <TableRow>
            <TextView
                android:id="@+id/tvSex"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1.0"/>
            <TextView
                android:id="@+id/tvAge"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1.0"/>
        </TableRow>
    </TableLayout>
</LinearLayout>

Student.java

public class Student {
    private int id;
    private String name;
    private String sex;
    private int age;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public int getId() {

        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public Student(int id, String name, String sex, int age) {
        this.id = id;
        this.name = name;
        this.sex = sex;
        this.age = age;
    }

    public Student() {
    }

    @Override
    public String toString() {
        return "Student{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", sex='" + sex + '\'' +
                ", age=" + age +
                '}';
    }
}

StudentData.java

public class StudentData {
    public static List<Student> getData(int page){
        int item=(page-1)*10+1;
        List<Student> list=new ArrayList<>();
        for(int i=item;i<item+10;i++){
            Student stu=new Student(i,"同学"+i,"男",18);
            list.add(stu);
        }
        return list;
    }
}

StudentAdapter.java

public class StudentAdapter extends BaseAdapter {
    private List<Student> stus;
    //用于将资源文件实例化成视图树
    private LayoutInflater inflater;
    private boolean isIdle;

    public void setIdle(boolean idle) {
        isIdle = idle;
    }

    public StudentAdapter(Context context, List<Student> list){
        if (list.size()>0){
            stus=list;
        }else{
            stus=new ArrayList<Student>();
        }
        //实例化inflater
        inflater=LayoutInflater.from(context);
        isIdle=true;
    }
    public void addData(List<Student> stu){
        if(stu!=null){
            stus.addAll(stu);//追加数据
            notifyDataSetChanged();
        }
    }
    @Override
    public int getCount() {
        return stus.size();
    }

    @Override
    public Object getItem(int i) {
        return stus.get(i);
    }

    @Override
    public long getItemId(int i) {
        return stus.get(i).getId();
    }

    @Override
    public View getView(int i, View v, ViewGroup viewGroup) {
        ViewHolder holder=null;
        //加载或重用item view
        if(v==null){
            v=inflater.inflate(R.layout.stu_item,null);
            holder=new ViewHolder();
            holder.tvId= (TextView) v.findViewById(R.id.tvId);
            holder.tvName= (TextView) v.findViewById(R.id.tvName);
            holder.tvSex= (TextView) v.findViewById(R.id.tvSex);
            holder.tvAge= (TextView) v.findViewById(R.id.tvAge);
            v.setTag(holder);
        }else{
            holder=(ViewHolder) v.getTag();
        }
        if(isIdle) {//停止滑动,加载数据。懒加载模式提高程序的运行效率
            //从数据源取出指定位置的数据
            Student s = stus.get(i);
            //将数据写在item View
            holder.tvId.setText("" + s.getId());
            holder.tvName.setText(s.getName());
            holder.tvSex.setText(s.getSex());
            holder.tvAge.setText("" + s.getAge());
        }
        //将item view对象返回
        return v;
    }
}
class ViewHolder{
    TextView tvId;
    TextView tvName;
    TextView tvSex;
    TextView tvAge;
}

MainActivity.java

public class MainActivity extends AppCompatActivity {
    StudentAdapter adapter;
    private ListView listView;
    private AlertDialog dialog;
    private int page=1;
    private void addListener(){
        //添加滚动事件监听器
        listView.setOnScrollListener(new AbsListView.OnScrollListener() {
            boolean isLastRow = false;//是否是最后一条
            @Override
            public void onScrollStateChanged(AbsListView absListView, int i) {
                switch (i){//当屏幕停止滚动时为0;;
                    case AbsListView.OnScrollListener.SCROLL_STATE_IDLE:
                        adapter.setIdle(true);
                        adapter.notifyDataSetChanged();//重新加载数据
                        break;
                     //由于用户的操作,屏幕产生惯性滑动时为2
                    case  AbsListView.OnScrollListener.SCROLL_STATE_FLING:
                        adapter.setIdle(false);
                        break;
                        //当屏幕滚动且用户使用的触碰或手指还在屏幕上时为1
                    case AbsListView.OnScrollListener.SCROLL_STATE_TOUCH_SCROLL:
                        adapter.setIdle(false);
                        break;
                }
                if(isLastRow&&i== AbsListView.OnScrollListener.SCROLL_STATE_IDLE){
                    //表明已经加载到最后一条
                    List<Student> list=StudentData.getData(++page);
                    adapter.addData(list);
                    isLastRow=false;
                }
            }

            @Override
            public void onScroll(AbsListView absListView, int i, int i1, int i2) {
                //滚动时一直回调,直到停止滚动时才停止回调。单击时回调一次。
                //firstVisibleItem:当前能看见的第一个列表项ID(从0开始)
                //visibleItemCount:当前能看见的列表项个数(小半个也算)
                //totalItemCount:列表项总数
                Log.i("data","i:"+i+",i1"+i1+",i2"+i2);
                if(i+i1==i2){
                    isLastRow=true;
                }
            }
        });
    }
    private void setupView(){
        listView=(ListView) findViewById(R.id.lv);
         adapter=new StudentAdapter(this, StudentData.getData(page));
        listView.setAdapter(adapter);
        dialog=new AlertDialog.Builder(this).setIcon(android.R.drawable.ic_dialog_info)
                .setTitle("学生详情").setPositiveButton("确定",null).create();
        //item view单击事件的监听器
        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
                Log.i("msg","position:"+i+" id:"+l);
                Student s= (Student) adapter.getItem(i);
               dialog.setMessage(s.toString());
                dialog.show();
            }
        });
    }
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        setupView();
        addListener();
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值