1. ListView 显示原理

ListView显示数据原理实际就是MVC设计模式,如下图所示:

 

  • Model(模型) – 数据集合,用来存储数据组织
  • View(视图) – ListView,负责数据显示
  • Controller(控制器) - 负责管理Model,并设置要显示的哪个具体数据.

 

2. ListView 控件继承关系

java.lang.Object   ↳android.view.View    ↳android.view.ViewGroup     ↳android.widget.AdapterView      ↳android.widget.AbsListView       ↳android.widget.ListView

3. ListView 控件的属性

属性 说明
android:footerDividersEnabled 是否在 footerView(表尾) 前绘制一个分隔条,默认为 true
android:headerDividersEnabled 是否在 headerView(表头) 前绘制一个分隔条,默认为 true
android:divider 设置分隔条,可以用颜色分割,也可以用 drawable 资源分割
android:dividerHeight 设置分隔条的高度
android:entries ListView 要显示的数据资源

 

表头表尾分割线的设置: 

只能在 Java 中写代码进行设置了,可供我们调用的方法如下

方法 说明
addHeaderView(View v) 添加headView(表头),括号中的参数是一个View对象
addFooterView(View v) 添加footerView(表尾),括号中的参数是一个View对象
addHeaderView(headView, null, false) 和前面的区别:设置Header是否可以被选中
addFooterView(View,view,false) 和前面的区别:设置 Footer 是否可以被选中

 

4. Adapter 继承关系

 

 

几个常用类的使用准则 :

说明
BaseAdapter 抽象类,用得最多的 Adapter
ArrayAdapter 支持泛型操作,最简单的 Adapter,只能展现一行文字
SimpleAdapter 同样具有良好扩展性的 Adapter,可以自定义多种效果
SimpleCursorAdapter 用于显示简单文本类型的 ListView,不推荐使用 XXXXX

 

5. ArrayAdapter 构造函数的第二个参数

 

这其实是我们要给 ListView 设置的模板,有好几种

  1. simple_list_item_1

    单独一行的文本框

  2. simple_list_item_2

    两个文本框组成

  3. simple_list_item_checked

    每项都是由一个已选中的列表项

  4. simple_list_item_multiple_choice

    都带有一个复选框

  5. simple_list_item_single_choice

    都带有一个单选钮

6. 自定义类继承 BaseAdapter

常用的需要覆盖的方法:

方法 说明
View getView(int position, View convertView, ViewGroup parent) 获取显示数据集中指定位置的数据的视图
int getCount() 数据集中有多少项目
Object getItem(int position) 获取与数据集中指定位置关联的数据项
long getItemId(int position) 获取与列表中指定位置关联的行 ID

 

7. ListView 实现动态增删改查

动态增加数据,要么要删除一些数据,要么要更改一些数据,这时候,我们的 ListView 就要同步更改才对

来源: https://www.twle.cn/l/yufei/android/android-basic-listview-add.html

 

7.1 activity_main.xml 添加一个 ListView

<?xml version="1.0" encoding="utf-8" ?>        

7.2 在 res/layout 目录下新建一个列表项的布局 listview_item.xml

<?xml version="1.0" encoding="utf-8"?>        

7.3 在 MainActivity.java 同一目录下新建一个 Bean 类 TalkBean.java

package cn.twle.android.listviewcrud;public class TalkBean {    private int avatar_id;    private String say;    public TalkBean() {}    public TalkBean(int avatar_id, String say) {        this.avatar_id = avatar_id;        this.say = say;    }    public int getAvatarId() {        return avatar_id;    }    public String getSay() {        return say;    }    public void setAvatarId(int avatarId) {        this.avatar_id = avatarId;    }    public void setSay(String say) {        this.say = say;    }}

 

7.4 在 MainActivity.java 目录下新建一个 Adapter 文件 TalkAdapter.java

package cn.twle.android.listviewcrud;import android.widget.BaseAdapter;import android.widget.ImageView;import android.widget.TextView;import android.content.Context;import android.view.View;import android.view.ViewGroup;import android.view.LayoutInflater;import java.util.LinkedList;public class TalkAdapter extends BaseAdapter {    private Context mContext;    private LinkedList mData;    public TalkAdapter() {}    public TalkAdapter(LinkedList mData, Context mContext) {        this.mData = mData;        this.mContext = mContext;    }    @Override    public int getCount() {        return mData.size();    }    @Override    public Object getItem(int position) {        return null;    }    @Override    public long getItemId(int position) {        return position;    }    @Override    public View getView(int position, View convertView, ViewGroup parent) {        ViewHolder holder = null;        if(convertView == null){            convertView = LayoutInflater.from(mContext).inflate(R.layout.listview_item,parent,false);            holder = new ViewHolder();            holder.avatar = (ImageView) convertView.findViewById(R.id.avatar);            holder.say = (TextView) convertView.findViewById(R.id.say);            convertView.setTag(holder);        }else{            holder = (ViewHolder) convertView.getTag();        }        holder.avatar.setImageResource(mData.get(position).getAvatarId());        holder.say.setText(mData.get(position).getSay());        return convertView;    }    private class ViewHolder{        ImageView avatar;        TextView  say;    }}

7.5 在 res/layout 目录下新建一个 listview_empty.xml

用于在ListView 没有数据的时候,显示说明

需要在 activity_main.xml 包含 listview_empty.xml

<?xml version="1.0" encoding="utf-8"?>      

 

7.5 MainActivity.java

调用 setEmptyView(View) ,但没有数据的时候显示

import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.widget.ListView;import android.widget.Toast;import android.widget.AdapterView;import android.view.View;import java.util.LinkedList;import java.util.List;public class MainActivity extends AppCompatActivity {    private ListView listview;    private TalkAdapter talkAdapter = null;    private List mData = null;    private int flag = 0;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        listview = (ListView) findViewById(R.id.listview);        View listview_empty = findViewById(R.id.talk_empty);          listview.setEmptyView(listview_empty);  // 但没有 数据时,显示                // 准备数据源        mData = new LinkedList();        // 将数据源添加到 适配器 中        talkAdapter = new TalkAdapter((LinkedList) mData,MainActivity.this);        // 将适配器数据 添加到 ListView        listview.setAdapter(talkAdapter);    }}

 

 

 

 

如果数据量一多,就特别卡顿,有时候会导致卡死,是什么原因造成的呢?

是因为 getView() 方法,界面上有多少列就会调用多少次 getView() ,每次都是新 inflate 一个 View,都要进行这个 XML 的解析,这样会 很浪费资源

所以我们要对 Adapter 进行优化,有两个目标:

  1. 复用 convertView

因为界面上有多少个 Item,就要调用 getView() 多少次;

每次都要加载一次 xml

其实这个 convertView 是系统提供给我们的可供服用的 View ,既然可复用,那么只要做一下判断就好

@Overridepublic View getView(int position, View convertView, ViewGroup parent) {    if(convertView == null){        convertView = LayoutInflater.from(mContext).inflate(R.layout.list_item,parent,false);    }.....

 

2. 用 ViewHolder 重用组件,不用每次都 `findViewById()

 

上面的优化只做到了 XML 文件只加载一次,但 convertView.findViewById 还是调用了多次

其实我们的 ListView 中的每一项都是一模一样的布局,能否只调用一次就好?

答案是肯定的,但需要自己定义一个 ViewHolder 类来对这一部分进行性能优化

ViewHolder 其实就是一个静态类

static class ViewHolder{    ImageView img_icon;    TextView txt_aName;    TextView txt_aSpeak;}

 

 

 

更多相关文章

  1. 一句话锁定MySQL数据占用元凶
  2. onCharacteristicChanged 回调问题
  3. Android(安卓)首页Fragment切换常用姿势
  4. Handler 总结
  5. Android(安卓)TextView显示html富文本格式以及Edittext获取带htm
  6. permission大全及场景的用法
  7. Android(安卓)display架构分析(一)
  8. Android(安卓)如何修改自动同步数据的默认开关 M
  9. android登录界面

随机推荐

  1. Android的电话功能介绍
  2. Design Pattern in Android(安卓)Sdk Sou
  3. Android(安卓)Dialog详解
  4. android实现动态更换应用图标
  5. Lifecycle LiveData LiveData LiveData
  6. Android常用布局有5种
  7. android Activity中设置setResult 没有触
  8. Android(安卓)AIDL 详解
  9. Android(安卓)Activity
  10. Android下用OpenGL画的一个旋转的圆形