ListView的使用

由于手机屏幕空间有限,能够一次性展现在屏幕上的内容并不多,当我们需要展现大量数据时,就可以通过ListView来实现。

ListView允许用户通过手指上下滑动的方式将屏幕外的数据滚动到屏幕内,同时屏幕上原有的数据则会滚动出屏幕。

应用场景:QQ聊天记录 、 微博消息

ListView的简单用法

简单实现ListView

创建一个Activity,在其视图中添加ListView控件,并为其指定id,长宽match_parent

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <ListView
        android:id="@+id/main_listview"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

</LinearLayout>

然后修改Activity中的代码:

public class MainActivity extends AppCompatActivity {

    private ListView mListview;

    private String[] data = {"item1","item2","item3","item4","item5","item6","item7","item8",
            "item9,","item10","item11","item12","item13","item14","item15"};

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        // 绑定视图
        mListview = (ListView) findViewById(R.id.main_2a'z'zlistview);
        ArrayAdapter<String> adapter = new ArrayAdapter<String>(MainActivity.this, android.R.layout.simple_list_item_1, data);
        mListview.setAdapter(adapter);
    }
}

效果如图所示:

simple_listview.PNG

自定义ListView

在上一节中,我们每一行填充的View是系统自带的资源android.R.layout.simple_list_item_1,我们可以按住ctrl加鼠标左键进入查看,内容如下:

<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@android:id/text1"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:textAppearance="?android:attr/textAppearanceListItemSmall"
    android:gravity="center_vertical"
    android:paddingStart="?android:attr/listPreferredItemPaddingStart"
    android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
    android:minHeight="?android:attr/listPreferredItemHeightSmall" />

我们使用了系统提供的ArrayAdaper作为ListView的适配器,每行填充的视图就是上面的TextView。然后把名为data的String类型数组依此填充进去。

关于Adapter

ListView控件是为了交互和展示数据用的,ListView也只承担交互和展示作用,而数据来自哪里和ListView无关。所以我们要使ListView起作用,我们需要一个ListView和一个数据源

关键在于数据源,我们无法知道数据源是什么类型。它可能是数组,可能是对象集合,还可能是数据库表中查询出来的游标,如果ListView要为每一种数据源都进行适配操作的话,扩展性就会比较差。

Adapter适配器,它在ListView和数据源之间起到了一个桥梁的作用。ListView不直接和数据源打交道,而是借助Adapter作为桥梁来访问真正的数据源,

实际上我们可以自定义填充的View,我们也可以填充一个ViewGroup,例如:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:id="@+id/item_roadid"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:textSize="30sp"
        android:gravity="center"/>

    <TextView
        android:id="@+id/item_redtime"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:textSize="30sp"
        android:gravity="center"/>

    <TextView
        android:id="@+id/item_greentime"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:textSize="30sp"
        android:gravity="center"/>

    <TextView
        android:id="@+id/item_yellowtime"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:textSize="30sp"
        android:gravity="center"/>

</LinearLayout>

这个ViewGroup由四个TextView组成。

在上节中我们直接使用了ArrayAdapter来作为适配器,ArrayAdapter继承自BaseAdapter,默认情况下,我们可以使用它的构造方法引用单个TextView的布局作为item。但如果布局较复杂,我们就需要加入TextView外层的布局的layout资源 ,即下图第四种用法。当TextView被引用之后,将会被填充传进来的数组对象的toString()的值。

arrayadapter.PNG

而我们需要更复杂的item,不仅仅是一个TextView,比如一个ImageView,或者一个Checkbox,亦或是一个Button。ArrayAdapter通过getView()方法获得每个item的View,所以我们需要重写ArrayAdapter的getView()方法来返回我们自己需要的View。我们通过继承来完成重写。

重写ArrayAdapter

因为我们不再使用String数组作为数据源,而是以对象list的形式作为数据源,所以我们先构建一个所需的对象。

我以交通灯为例,这个对象包含roadId,redTime,greenTime,yellowTime四个属性,然后创建了它的构造函数和一些getter/setter。

public class LightInfo {

    private int roadId;

    private int redTime;

    private int greenTime;

    private int yellowTime;

    public LightInfo(int roadId, int redTime, int greenTime, int yellowTime) {
        this.roadId = roadId;
        this.redTime = redTime;
        this.greenTime = greenTime;
        this.yellowTime = yellowTime;
    }

    public int getRoadId() {
        return roadId;
    }

    public void setRoadId(int roadId) {
        this.roadId = roadId;
    }

    public int getRedTime() {
        return redTime;
    }

    public void setRedTime(int redTime) {
        this.redTime = redTime;
    }

    public int getGreenTime() {
        return greenTime;
    }

    public void setGreenTime(int greenTime) {
        this.greenTime = greenTime;
    }

    public int getYellowTime() {
        return yellowTime;
    }

    public void setYellowTime(int yellowTime) {
        this.yellowTime = yellowTime;
    }
}

然后重写适配器:

public class LightInfoAdapter extends ArrayAdapter<LightInfo> {

    private ArrayList list = new ArrayList();;

    public LightInfoAdapter(@NonNull Context context, int resource, @NonNull List<LightInfo> objects) {
        super(context, resource, objects);
    }

    @NonNull
    @Override
    public View getView(final int position, @Nullable View convertView, @NonNull ViewGroup parent) {
        View view = LayoutInflater.from(getContext()).inflate(R.layout.item_light_info, parent, false);
        LightInfo lightInfo = getItem(position);
        TextView roadId = (TextView) view.findViewById(R.id.item_roadid);
        TextView redTime = (TextView) view.findViewById(R.id.item_redtime);
        TextView greenTime = (TextView) view.findViewById(R.id.item_greentime);
        TextView yellowTime = (TextView) view.findViewById(R.id.item_yellowtime);
        roadId.setText(lightInfo.getRoadId()+"");
        redTime.setText(lightInfo.getRedTime()+"");
        greenTime.setText(lightInfo.getGreenTime()+"");
        yellowTime.setText(lightInfo.getYellowTime()+"");
        return view;
}

修改Activity中的代码

public class MainActivity extends AppCompatActivity {

    private ListView mListview;
    // 删除
    //private String[] data = {"item1","item2","item3","item4","item5","item6","item7","item8","item9,","item10","item11","item12","item13","item14","item15"};
    // 添加 
    private List<LightInfo> lightInfos = new ArrayList<>();;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        // 绑定视图
        mListview = (ListView) findViewById(R.id.main_2a'z'zlistview);
        // 删除
        //ArrayAdapter<String> adapter = new ArrayAdapter<String>(MainActivity.this, android.R.layout.simple_list_item_1, data);
        // 添加
        initData();
        LightInfoAdapter adapter = new LightInfoAdapter(this,R.layout.item_light_info,lightInfos);
        mListview.setAdapter(adapter);
    }
    // 添加死数据
    private void initData() {
        for (int i=0;i<4;i++) {
            lightInfos.add(new LightInfo(i,i,i,i));
        }
    }
}

效果如图:

diyListView.PNG
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,236评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,867评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,715评论 0 340
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,899评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,895评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,733评论 1 283
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,085评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,722评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,025评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,696评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,816评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,447评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,057评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,009评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,254评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,204评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,561评论 2 343

推荐阅读更多精彩内容