Android零基础入门第44节:ListView数据动态更新

经过前面几期的学习,关于ListView的一些基本用法大概学的差不多了,但是你可能发现了,所有ListView里面要填充的数据都是静态的,但在实际开发中,这些数据往往都是动态变化的,比如数据内容发生改变、增加几行、或者删除几行,这就涉及到ListView数据的更新问题。

接下来通过一个简单的示例程序来学习ListView的数据更新。

继续使用WidgetSample工程,在app/main/res/layout/目录下创建updatedata_layout.xml文件,在其中填充如下代码片段:

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

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:gravity="center_horizontal">

        <Button
            android:id="@+id/add_btn"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="添加"/>
        <Button
            android:id="@+id/update_btn"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="更新"/>
        <Button
            android:id="@+id/delete_btn"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="删除"/>
        <Button
            android:id="@+id/clear_btn"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="清空"/>
    </LinearLayout>

    <TextView
        android:id="@+id/empty_tv"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:padding="15dp"
        android:textSize="15sp"
        android:text="暂无数据"/>

    <ListView
        android:id="@+id/listview"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
</LinearLayout>

由于当ListView没有数据时,整个页面一片白,非常难看,所以加了一个文本框,当列表没有数据时提示用户。然后添加了4个按钮来动态更新列表数据。

接着在res/layout/目录下新建一个updatedata_item.xml的列表项布局文件,其代码如下:

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

    <ImageView
        android:id="@+id/icon_img"
        android:layout_width="48dp"
        android:layout_height="48dp"
        android:padding="5dp"/>

    <TextView
        android:id="@+id/content_tv"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="18sp" />
</LinearLayout>

然后创建数据实体类UpdateData.java,主要用于显示在列表数据的实体,这里比较简单,包括一个图标ID和文本内容,代码如下:

package com.jinyu.cqkxzsxy.android.listviewsample.entity;

/**
 * @创建者 鑫鱻
 * @描述 Android零基础入门到精通系列教程,欢迎关注微信公众号ShareExpert
 */
public class UpdateData {
    private int imgId;
    private String content;

    public UpdateData() {}

    public UpdateData(int imgId, String content) {
        this.imgId = imgId;
        this.content = content;
    }

    public int getImgId() {
        return imgId;
    }

    public String getContent() {
        return content;
    }

    public void setImgId(int imgId) {
        this.imgId = imgId;
    }

    public void setContent(String content) {
        this.content = content;
    }
}

再创建MyUpdateAdapter类,继承BaseAdapter,再另外添加几个方法,便于操作ListView。

package com.jinyu.cqkxzsxy.android.listviewsample.adapter;

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.TextView;

import com.jinyu.cqkxzsxy.android.listviewsample.R;
import com.jinyu.cqkxzsxy.android.listviewsample.entity.UpdateData;

import java.util.LinkedList;
import java.util.List;

/**
 * @创建者 鑫鱻
 * @描述 Android零基础入门到精通系列教程,欢迎关注微信公众号ShareExpert
 */
public class MyUpdateAdapter extends BaseAdapter {
    private Context mContext;
    private List<UpdateData> mUpdateData;

    public MyUpdateAdapter() {}
    public MyUpdateAdapter( Context context, List<UpdateData> UpdateDatas) {
        this.mUpdateData = UpdateDatas;
        this.mContext = context;
    }

    /**
     * 添加列表项
     * @param position
     * @param UpdateData
     */
    public void add(int position, UpdateData UpdateData){
        if (null == mUpdateData) {
            mUpdateData = new LinkedList<>();
        }
        mUpdateData.add(position,UpdateData);
        notifyDataSetChanged();
    }

    /**
     * 更新列表内容
     * @param UpdateDatas
     */
    public void update(List<UpdateData> UpdateDatas){
        if (null == mUpdateData) {
            mUpdateData = new LinkedList<>();
        }
        mUpdateData.clear();
        mUpdateData.addAll(UpdateDatas);

        notifyDataSetChanged();
    }

    /**
     * 更新列表项
     * @param position
     * @param UpdateData
     */
    public void update(int position,UpdateData UpdateData){
        if(mUpdateData != null && position < mUpdateData.size()) {
            mUpdateData.set(position, UpdateData);
        }
        notifyDataSetChanged();
    }

    /**
     * 移除指定列表项
     * @param position
     */
    public void remove(int position) {
        if(mUpdateData != null && 0 != getCount()) {
            mUpdateData.remove(position);
        }
        notifyDataSetChanged();
    }

    /**
     * 清空列表数据
     */
    public void clear() {
        if(mUpdateData != null) {
            mUpdateData.clear();
        }
        notifyDataSetChanged();
    }

    @Override
    public int getCount() {
        return mUpdateData.size();
    }

    @Override
    public UpdateData getItem(int position) {
        return mUpdateData.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder holder = null;
        if(null == convertView){
            convertView = LayoutInflater.from(mContext).inflate(R.layout.updatedata_item, null);
            holder = new ViewHolder();
            holder.img_icon = (ImageView) convertView.findViewById(R.id.icon_img);
            holder.txt_content = (TextView) convertView.findViewById(R.id.content_tv);
            convertView.setTag(holder);
        }else{
            holder = (ViewHolder) convertView.getTag();
        }

        UpdateData UpdateData = getItem(position);
        holder.img_icon.setImageResource(UpdateData.getImgId());
        holder.txt_content.setText(UpdateData.getContent());
        return convertView;
    }

    private class ViewHolder{
        ImageView img_icon;
        TextView txt_content;
    }
}

接下来为ListView提供Adapter,使用自定义的BaseAdapter决定ListView所要显示的列表项,然后为4个按钮设置监听监听器。新建UpdateDataActivity.java文件,加载上面新建的布局文件,具体代码如下:

package com.jinyu.cqkxzsxy.android.listviewsample;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.ListView;

import com.jinyu.cqkxzsxy.android.listviewsample.adapter.MyUpdateAdapter;
import com.jinyu.cqkxzsxy.android.listviewsample.entity.UpdateData;

import java.util.LinkedList;
import java.util.List;

public class UpdateDataActivity extends AppCompatActivity implements View.OnClickListener {
    private ListView mListView = null; // 列表
    private Button mAddBtn = null; // 添加列表项按钮
    private Button mUpdateBtn = null; // 更新列表按钮
    private Button mDeleteBtn = null; // 删除列表项按钮
    private Button mClearBtn = null; // 清空列表数据
    private MyUpdateAdapter mAdapter = null;

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

        // 获取界面组件
        mListView = (ListView) findViewById(R.id.listview);
        mAddBtn = (Button) findViewById(R.id.add_btn);
        mUpdateBtn = (Button) findViewById(R.id.update_btn);
        mDeleteBtn = (Button) findViewById(R.id.delete_btn);
        mClearBtn = (Button) findViewById(R.id.clear_btn);

        // 添加列表控内容视图
        View emptyView = findViewById(R.id.empty_tv);
        mListView.setEmptyView(emptyView);

        // 初始化列表
        List<UpdateData> datas = new LinkedList<UpdateData>();
        mAdapter = new MyUpdateAdapter(this, datas);
        mListView.setAdapter(mAdapter);

        // 设置按钮点击事件监听器
        mAddBtn.setOnClickListener(this);
        mUpdateBtn.setOnClickListener(this);
        mDeleteBtn.setOnClickListener(this);
        mClearBtn.setOnClickListener(this);
    }

    @Override
    public void onClick(View view) {
        switch (view.getId()){
            case R.id.add_btn:
                addItem();
                break;
            case R.id.update_btn:
                updateData();
                break;
            case R.id.delete_btn:
                deleteItem();
                break;
            case R.id.clear_btn:
                clearData();
                break;
            default:
                break;
        }
    }

    /**
     * 添加列表项
     */
    private void addItem() {
        int position = getRandomPosition();
        mAdapter.add(position, new UpdateData(R.mipmap.ic_launcher, "随机添加" + position));
    }

    /**
     * 更新列表内容
     */
    private void updateData() {
        int position = getRandomPosition();
        mAdapter.update(position, new UpdateData(R.mipmap.ic_launcher, "更新" + getRandomNumber()));
    }

    /**
     * 删除列表项
     */
    private void deleteItem() {
        int position = getRandomPosition();
        mAdapter.remove(position);
    }

    /**
     * 清空列表数据
     */
    private void clearData(){
        mAdapter.clear();
    }

    /**
     * 获取列表随机位置
     * @return
     */
    private int getRandomPosition() {
        int count = mAdapter.getCount();
        return (int) (Math.random() * count);
    }

    /**
     * 获取100以内的随机数
     * @return
     */
    private double getRandomNumber(){
        return Math.random() * 100;
    }
}

修改启动的Activity,运行程序,可以看到下面左图所示界面效果。

然后点击添加按钮,在列表中随机添加一些列表项,可以看到列表数据动态更新,如上图右侧所示。

然后再点击更新按钮,可以随机更新列表数据,如下图左侧所示。

再点击删除按钮,可以看到将会从列表中删除随机列表项,如上图右侧所示。

点击清空按钮,可以将列表所有数据全部清空,显示启动时的页面。

从以上几个操作,可以看到动态更新时离不开每次调用notifyDataSetChanged()方法,这个方法的主要作用就是当适配器里面的内容发生改变时需要强制调用getView()方法来刷新每个Item的内容。

今天就先到这里,如果有问题欢迎留言一起探讨,也欢迎加入Android零基础入门技术讨论微信群,共同成长!

此文章版权为微信公众号分享达人秀(ShareExpert)——鑫鱻所有,若需转载请联系作者授权,特此声明!

往期总结分享:

Android零基础入门第1节:Android的前世今生

Android零基础入门第2节:Android 系统架构和应用组件那些事

Android零基础入门第3节:带你一起来聊一聊Android开发环境

Android零基础入门第4节:正确安装和配置JDK, 高富帅养成第一招

Android零基础入门第5节:善用ADT Bundle, 轻松邂逅女神

Android零基础入门第6节:配置优化SDK Manager, 正式约会女神

Android零基础入门第7节:搞定Android模拟器,开启甜蜜之旅

Android零基础入门第8节:HelloWorld,我的第一趟旅程出发点

Android零基础入门第9节:Android应用实战,不懂代码也可以开发

Android零基础入门第10节:开发IDE大升级,终于迎来了Android Studio

Android零基础入门第11节:简单几步带你飞,运行Android Studio工程

Android零基础入门第12节:熟悉Android Studio界面,开始装逼卖萌

Android零基础入门第13节:Android Studio配置优化,打造开发利器

Android零基础入门第14节:使用高速Genymotion,跨入火箭时代

Android零基础入门第15节:掌握Android Studio项目结构,扬帆起航

Android零基础入门第16节:Android用户界面开发概述

Android零基础入门第17节:TextView属性和方法大全

Android零基础入门第18节:EditText的属性和使用方法

Android零基础入门第19节:Button使用详解

Android零基础入门第20节:CheckBox和RadioButton使用大全

Android零基础入门第21节:ToggleButton和Switch使用大全

Android零基础入门第22节:ImageView的属性和方法大全

Android零基础入门第23节:ImageButton和ZoomButton使用大全

Android零基础入门第24节:自定义View简单使用,打造属于你的控件

Android零基础入门第25节:简单且最常用的LinearLayout线性布局

Android零基础入门第26节:两种对齐方式,layout_gravity和gravity大不同

Android零基础入门第27节:正确使用padding和margin

Android零基础入门第28节:轻松掌握RelativeLayout相对布局

Android零基础入门第29节:善用TableLayout表格布局

Android零基础入门第30节:两分钟掌握FrameLayout帧布局

Android零基础入门第31节:少用的AbsoluteLayout绝对布局

Android零基础入门第32节:新推出的GridLayout网格布局

Android零基础入门第33节:Android事件处理概述

Android零基础入门第34节:Android中基于监听的事件处理

Android零基础入门第35节:Android中基于回调的事件处理

Android零基础入门第36节:Android系统事件的处理

Android零基础入门第37节:初识ListView

Android零基础入门第38节:初识Adapter

Android零基础入门第39节:ListActivity和自定义列表项

Android零基础入门第40节:自定义ArrayAdapter

Android零基础入门第41节:使用SimpleAdapter

Android零基础入门第42节:自定义BaseAdapter

Android零基础入门第43节:ListView优化和列表首尾使用

时间: 2024-10-04 06:47:02

Android零基础入门第44节:ListView数据动态更新的相关文章

Android零基础入门第64节:揭开RecyclerView庐山真面目

大家还记得之前在第38期~第50期都在学习列表控件吗,其中用了8期讲ListView的使用,相信都已经掌握好了吧.那么本期一起来学习Android 5.X新增的一个列表组件,那就是RecyclerView的使用. 一.RecyclerView概述 从前面的学习我们知道,ListView的功能非常强大,几乎绝大部分应用程序都会使用到,虽然也学会一些方法技巧来提升ListView的效率,但其性能还是不是很完美. 另外ListView的可扩展性相对来说比较弱,以前要实现每个列表项的高度不同的界面,或者

Android零基础入门第61节:滚动视图ScrollView

原文:Android零基础入门第61节:滚动视图ScrollView 前面几期学习了ProgressBar系列组件.ViewAnimator系列组件.Picker系列组件和时间日期系列组件,接下来几期继续来学习常见的其他组件. 一.ScrollView概述 从前面的学习有的同学可能已经发现,当拥有很多内容时屏幕显示不完,显示不全的部分完全看不见.但是在实际项目里面,很多内容都不止一个屏幕宽度或高度,那怎么办呢?那就需要本节学习的ScrollView来完成. 在默认情况下,ScrollView只是

Android零基础入门第60节:日历视图CalendarView和定时器Chronometer

原文:Android零基础入门第60节:日历视图CalendarView和定时器Chronometer 上一期学习了AnalogClock.DigitalClock和TextClock时钟组件,本期继续来学习日历视图CalendarView和定时器Chronometer. 一.CalendarView 日历视图(CalendarView)可用于显示和选择日期,用户既可选择一个日期,也可通过触 摸来滚动日历.如果希望监控该组件的日期改变,则可调用CalendarView的 setOnDateCha

Android零基础入门第62节:搜索框组件SearchView

原文:Android零基础入门第62节:搜索框组件SearchView 一.SearchView概述 SearchView是搜索框组件,它可以让用户在文本框内输入文字,并允许通过监听器监控用户输入,当用户输入完成后提交搜索时,也可通过监听器执行实际的搜索. SearchView默认是展示一个search的icon,点击icon展开搜索框,也可以自己设定图标.用SearchView时可指定如下表所示的常见XML属性及相关方法. 如果为SearchView增加一个配套的ListView,则可以为Se

Android零基础入门第58节:数值选择器NumberPicker

原文:Android零基础入门第58节:数值选择器NumberPicker 上一期学习了日期选择器DatePicker和时间选择器TimePicker,是不是感觉非常简单,本期继续来学习数值选择器NumberPicker . 一.NumberPicker概述 NumberPicker 是用于选择一组预定义好数字的组件,用户既可以通过键盘输入数值,也可以通过滚动来选择数值. NumberPicker的常用方法如下: setMinValue(int minVal):设置该组件支持的最小值. setM

Android零基础入门第66节:RecyclerView点击事件处理

前面两期学习了RecyclerView的简单使用,并为其item添加了分割线.在实际运用中,无论是List还是Grid效果,基本都会伴随着一些点击操作,那么本期就来一起学习RecyclerView的点击事件. 在介绍RecyclerView开篇的时候简单提到过,要实现一些控制点击.长压事件需要自己完成,不像之前学的ListView有自带ClickListener和LongClickListener,但其实更加灵活多样,可以对点击方式按照自己的方式来实现. 仍然在上一期的代码基础来进行修改,既然R

Android零基础入门第57节:日期选择器DatePicker和时间选择器TimePicker

在实际开发中,经常会遇见一些时间选择器.日期选择器.数字选择器等需求,那么从本期开始来学习Android中常用选择器,今天学习的是DatePicker和TimePicker. 一.DatePicker DatePicker是一个比较简单的组件,从FrameLayout派生而来,供用户选择日期.其在FrameLayout的基础上提供了一些方法来获取当前用户所选择的日期,如果程序需要获取用户选择的日期则可通过为DatePicker添加 OnDateChangedListener 进行监听来实现. 使

Android零基础入门第55节:ImageSwitcher和TextSwitcher使用

上一期我们了解了ViewAnimator组件和ViewSwitcher组件的使用,你都掌握了吗?本期一起来学习ViewSwitcher的两个子组件ImageSwitcher和TextSwitcher. 一.ImageSwitcher ImageSwitcher和ImageSwitcher继承了 ViewSwitcher,因此它具有与ViewSwitcher相同的特征:可以在切换View组件时使用动画效果.ImageSwitcher继承了 ViewSwitcher,并重写了 ViewSwitche

Android零基础入门第47节:自动完成文本框AutoCompleteTextView

上一期学习的Spinner的使用,掌握的怎么样?本期一起来学习AutoCompleteTextView的使用. 一.认识AutoCompleteTextView AutoCompleteTextView是自动完成文本框,从EditText派生而出,实际上它也是一个文本编辑框,但它比普通编辑框多了一个功能:当用户输入一定字符之后,自动完成文本框会显示一个下拉菜单,供用户从中选择,当用户选择某个菜单项之后,AutoCompleteTextView按用户选择自动填写该文本框. AutoComplete