• Android(java)学习笔记129:对ListView等列表组件中数据进行增、删、改操作


    1. ListView介绍

    解决大量的相似的数据显示问题

    采用了MVC模式:

    M: model (数据模型)

    V:  view  (显示的视图)

    C: controller 控制器

    入门案例:

    acitivity_main.xml:

    <RelativeLayout 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"
        tools:context=".MainActivity" >
    
        <ListView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:id="@+id/lv" />
    
    </RelativeLayout>

    MainActivity.java:

    package com.itheima.listviewdemo;
    
    import android.app.Activity;
    import android.os.Bundle;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.BaseAdapter;
    import android.widget.ListView;
    import android.widget.TextView;
    
    public class MainActivity extends Activity {
        //listview的视图 V view
        private ListView lv;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            lv = (ListView) findViewById(R.id.lv);
            //设置数据适配器 数据控制器 adapter 相当于C controller
            lv.setAdapter(new MyAdapter());
            
        }
    
        private class MyAdapter extends BaseAdapter{ //控制器
    
            /**
             * 数据集合里面一共有多少条记录
             */
            @Override
            public int getCount() {
                return 5000000;
            }
            /**
             * 返回某个指定位置的view对象
             */
            @Override
            public View getView(int position, View convertView, ViewGroup parent) {
                TextView tv = new TextView(MainActivity.this);
                tv.setTextSize(25);
                tv.setText("我是第"+position+"个被生出来的");
                System.out.println("getview --positon:"+position); //M  model 数据模型, textview
                return tv;
            }
            @Override
            public Object getItem(int position) {
                return null;
            }
    
            @Override
            public long getItemId(int position) {
                return 0;
            }
        }
        
    }

    这里本来我们的MyAdapter是应该实现接口ListAdapter,但是实现接口ListAdapter要实现的方法太多,不太方便使用,于是必然衍生出更加方便的API接口,那这里就是BaseAdapter(还有其他的),我们追踪至源码,知道:BaseAdapter 是实现ListAdapter接口的。

    public abstract class BaseAdapter implements ListAdapter, SpinnerAdapter { ………………}

    通常默认实现类命名:

    (1)BaseXXX

    (2)BasicXXX

    (3)SimpleXXX

    (4)DefaultXXX

    2. 由于像GridView、ListView等这样的列表组件是采用MVC模式的,因此不能直接通过列表组件对象对数据进行增、删、改操作。但是我们可以换个思路解决这个问题:

    (1)首先我们直接对数据源中数据进行增、删、改操作

    (2)然后调用BaseAdapter.notifyDataSetChanged方法通知列表组件进行数据更新。在调用notifyDataSetChanged方法的时候,系统会立刻调用这个BaseAdapter.getView()方法来获取当前显示的列表项的View对象,这样就更新的列表组件中显示的数据。

    3. 下面通过一个案例来演示这个类似ListView列表组件数据修改的过程:

    案例的运行效果图如下:

    (1)首先还是布局文件,这里有主布局文件activity_main.xml,以及其他辅助的布局文件:

    activity_main.xml:

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical" >
    
        <Button
            android:id="@+id/add_id"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_marginLeft="25dp"
            android:layout_marginRight="25dp"
            android:layout_marginTop="5dp"
            android:text="添加数据" 
            android:textColor="#99ff0000">
        </Button>
    
        <Button
            android:id="@+id/delete_id"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_marginLeft="25dp"
            android:layout_marginRight="25dp"
            android:layout_marginTop="5dp"
            android:text="删除数据" 
            android:textColor="#99ff0000">
        </Button>
    
        <Button
            android:id="@+id/edit_id"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_marginLeft="25dp"
            android:layout_marginRight="25dp"
            android:layout_marginTop="5dp"
            android:text="修改数据" 
            android:textColor="#99ff0000">
        </Button>
    
        <Button
            android:id="@+id/query_id"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_marginLeft="25dp"
            android:layout_marginRight="25dp"
            android:layout_marginTop="5dp"
            android:text="查询数据" 
            android:textColor="#99ff0000">
        </Button>
    
        <ListView
            android:id="@+id/show_result"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content" >
        </ListView>
    
    </LinearLayout>

    主布局文件效果如下:

    input_add.xml:添加数据

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent" >
    
        <EditText
            android:id="@+id/input_add_string"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:singleLine="true" >
        </EditText>
    
    </LinearLayout>

    input_delete.xml:删除数据

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent" >
    
        <EditText
            android:id="@+id/input_delete_number"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:digits="0123456789"
            android:singleLine="true" >
        </EditText>
    
    </LinearLayout>

    input_edit.xml:修改数据

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:orientation="vertical" >
    
        <TextView
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:text="输入要修改的索引" >
        </TextView>
    
        <EditText
            android:id="@+id/input_edit_number"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:digits="0123456789"
            android:singleLine="true" >
        </EditText>
    
        <TextView
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:text="内容修改为" >
        </TextView>
    
        <EditText
            android:id="@+id/input_edit_string"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:singleLine="true" >
        </EditText>
    
    </LinearLayout>

    items.xml:列表子项目样式布局

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal" >
    
        <TextView
            android:id="@+id/viewspot"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:padding="6dip"
            android:textColor="#88000000"
            android:textSize="25dp" >
        </TextView>
    
        <ImageView
            android:id="@+id/add"
            android:layout_width="100dip"
            android:layout_height="wrap_content"
            android:padding="10dip"
            android:src="@drawable/right" >
        </ImageView>
    
    </LinearLayout>

    (2)主要的class文件,UpdateListViewActivity.java,如下:

    package com.himi.updatelistview;
    
    import java.util.ArrayList;
    import java.util.HashMap;
    
    import android.app.Activity;
    import android.app.AlertDialog;
    import android.content.Context;
    import android.content.DialogInterface;
    import android.os.Bundle;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.View.OnClickListener;
    import android.widget.Button;
    import android.widget.EditText;
    import android.widget.LinearLayout;
    import android.widget.ListView;
    import android.widget.SimpleAdapter;
    import android.widget.Toast;
      
    public class UpdateListViewActivity extends Activity {   
    
        private Button addBtn;   
        private Button deleteBtn;   
        private Button editBtn;   
        private Button queryBtn;   
        private ListView listview;   
        // 数组   
        private SimpleAdapter listItemAdapter;   
        private ArrayList<HashMap<String, Object>> listItem = null;   
      
        /** Called when the activity is first created. */  
        @Override  
        public void onCreate(Bundle savedInstanceState) {   
            super.onCreate(savedInstanceState);   
            setContentView(R.layout.activity_main);   
      
            // 获取控件   
            addBtn = (Button) findViewById(R.id.add_id);   
            deleteBtn = (Button) findViewById(R.id.delete_id);   
            editBtn = (Button) findViewById(R.id.edit_id);   
            queryBtn = (Button) findViewById(R.id.query_id);   
            listview = (ListView) findViewById(R.id.show_result);   
      
            // 初始化数据   
            init();   
      
            // 设置控件事件监听   
            addBtn.setOnClickListener(addClick);   
            deleteBtn.setOnClickListener(deleteClick);   
            editBtn.setOnClickListener(editClick);   
            queryBtn.setOnClickListener(queryClick);   
      
        }   
      
        // 添加事件响应   
        OnClickListener addClick = new OnClickListener() {   
      
            public void onClick(View v) {   
                // TODO Auto-generated method stub   
      
                // 加载输入框的布局文件   
                LayoutInflater inflater = (LayoutInflater) UpdateListViewActivity.this  
                        .getSystemService(Context.LAYOUT_INFLATER_SERVICE);   
                final LinearLayout layout = (LinearLayout) inflater.inflate(   
                        R.layout.input_add, null);   
      
                // 弹出的对话框   
      
                new AlertDialog.Builder(UpdateListViewActivity.this)   
                        /* 弹出窗口的最上头文字 */  
                        .setTitle("添加一条数据")   
                        /* 设置弹出窗口的图式 */  
                        .setIcon(android.R.drawable.ic_input_add)   
                        /* 设置弹出窗口的信息 */  
                        .setMessage("请输入添加的内容")   
                        .setView(layout)   
                        .setPositiveButton("确定",   
                                new DialogInterface.OnClickListener() {   
                                    public void onClick(   
                                            DialogInterface dialoginterface, int i) {   
      
                                        EditText inputStringr = (EditText) layout   
                                                .findViewById(R.id.input_add_string);   
      
                                        String str = inputStringr.getText()   
                                                .toString();   
      
                                        if (str == null || str.equals("")) {   
      
                                            Toast.makeText(getApplicationContext(),   
                                                    "添加的内容不能为空", Toast.LENGTH_SHORT)   
                                                    .show();   
                                        } else {   
                                            HashMap<String, Object> map = new HashMap<String, Object>();   
                                            map.put("viewspot", str);   
                                            map.put("add", R.drawable.right);   
                                            listItem.add(0, map);   
                                            // 如果在前面添加一条数据添加   
                                            // listItem.add(map);   
                                            listItemAdapter.notifyDataSetChanged();   
                                            Toast.makeText(   
                                                    UpdateListViewActivity.this,   
                                                    "添加的一条数据为:" + str + "",   
                                                    Toast.LENGTH_SHORT).show();   
      
                                        }   
      
                                    }   
                                })   
                        .setNegativeButton("取消",   
                                new DialogInterface.OnClickListener() { /* 设置跳出窗口的返回事件 */  
                                    public void onClick(   
                                            DialogInterface dialoginterface, int i) {   
                                        Toast.makeText(UpdateListViewActivity.this,   
                                                "取消了删除数据", Toast.LENGTH_SHORT)   
                                                .show();   
      
                                    }   
                                }).show();   
      
            }   
        };   
      
        // 删除事件响应   
        OnClickListener deleteClick = new OnClickListener() {   
      
            public void onClick(View v) {   
                // TODO Auto-generated method stub   
      
                /**  
                 * listItem.clear();清空所有数据  
                 *  
                 * */  
      
                /*  
                 * listItem.clear();  
                 * listItemAdapter.notifyDataSetChanged();  
                 */  
      
                // 加载输入框的布局文件   
                LayoutInflater inflater = (LayoutInflater) UpdateListViewActivity.this  
                        .getSystemService(Context.LAYOUT_INFLATER_SERVICE);   
                final LinearLayout layout = (LinearLayout) inflater.inflate(   
                        R.layout.input_delete, null);   
      
                // 弹出的对话框   
      
                new AlertDialog.Builder(UpdateListViewActivity.this)   
                        /* 弹出窗口的最上头文字 */  
                        .setTitle("删除一条数据")   
                        /* 设置弹出窗口的图式 */  
                        .setIcon(android.R.drawable.ic_input_delete)   
                        /* 设置弹出窗口的信息 */  
                        .setMessage("请输入删除的索引")   
                        .setView(layout)   
                        .setPositiveButton("确定",   
                                new DialogInterface.OnClickListener() {   
                                    public void onClick(   
                                            DialogInterface dialoginterface, int i) {   
      
                                        EditText inputNumber = (EditText) layout   
                                                .findViewById(R.id.input_delete_number);   
      
                                        String str = inputNumber.getText()   
                                                .toString();   
      
                                        if (str == null || str.equals("")) {   
      
                                            Toast.makeText(getApplicationContext(),   
                                                    "请输入一个数字", Toast.LENGTH_SHORT)   
                                                    .show();   
                                        } else {   
                                            int number = Integer.valueOf(str);   
      
                                            int size = listItem.size();   
      
                                            // 判断数字是否超出数组索引范围   
                                            if (number >= size) {   
                                                Toast.makeText(   
                                                        getApplicationContext(),   
                                                        "没有找到删除的数据索引",   
                                                        Toast.LENGTH_SHORT).show();   
      
                                            } else {   
      
                                                String value = listItem.get(number)   
                                                        .toString();   
                                                listItem.remove(number);   
                                                listItemAdapter   
                                                        .notifyDataSetChanged();   
                                                Toast.makeText(   
                                                        UpdateListViewActivity.this,   
                                                        "删除的数据为:" + value + "",   
                                                        Toast.LENGTH_SHORT).show();   
      
                                            }   
                                        }   
      
                                    }   
                                })   
                        .setNegativeButton("取消",   
                                new DialogInterface.OnClickListener() { /* 设置跳出窗口的返回事件 */  
                                    public void onClick(   
                                            DialogInterface dialoginterface, int i) {   
                                        Toast.makeText(UpdateListViewActivity.this,   
                                                "取消了删除数据", Toast.LENGTH_SHORT)   
                                                .show();   
      
                                    }   
                                }).show();   
      
            }   
        };   
        // 修改事件响应   
        OnClickListener editClick = new OnClickListener() {   
      
            public void onClick(View v) {   
                // TODO Auto-generated method stub   
                // 加载输入框的布局文件   
                LayoutInflater inflater = (LayoutInflater) UpdateListViewActivity.this  
                        .getSystemService(Context.LAYOUT_INFLATER_SERVICE);   
                final LinearLayout layout = (LinearLayout) inflater.inflate(   
                        R.layout.input_edit, null);   
      
                // 弹出的对话框   
      
                new AlertDialog.Builder(UpdateListViewActivity.this)   
                        /* 弹出窗口的最上头文字 */  
                        .setTitle("修改一条数据")   
                        /* 设置弹出窗口的图式 */  
                        .setIcon(android.R.drawable.ic_dialog_alert)   
                        /* 设置弹出窗口的信息 */  
                        .setMessage("请输入修改的索引及内容")   
                        .setView(layout)   
                        .setPositiveButton("确定",   
                                new DialogInterface.OnClickListener() {   
                                    public void onClick(   
                                            DialogInterface dialoginterface, int i) {   
      
                                        EditText inputEditNumber = (EditText) layout   
                                                .findViewById(R.id.input_edit_number);   
      
                                        String numberStr = inputEditNumber   
                                                .getText().toString();   
      
                                        EditText inputEditString = (EditText) layout   
                                                .findViewById(R.id.input_edit_string);   
      
                                        String editStr = inputEditString.getText()   
                                                .toString();   
      
                                        if (numberStr == null  
                                                || numberStr.equals("")) {   
      
                                            Toast.makeText(getApplicationContext(),   
                                                    "请输入要修改的索引", Toast.LENGTH_SHORT)   
                                                    .show();   
                                        } else {   
                                            int number = Integer.valueOf(numberStr);   
      
                                            int size = listItem.size();   
      
                                            // 判断数字是否超出数组索引范围   
                                            if (number >= size) {   
                                                Toast.makeText(   
                                                        getApplicationContext(),   
                                                        "没有找到修改的数据索引",   
                                                        Toast.LENGTH_SHORT).show();   
      
                                            } else {   
      
                                                HashMap<String, Object> map = new HashMap<String, Object>();   
                                                map.put("viewspot", editStr);   
                                                map.put("add", R.drawable.right);   
      
                                                listItem.set(number, map);   
                                                listItemAdapter   
                                                        .notifyDataSetChanged();   
      
                                                Toast.makeText(   
                                                        UpdateListViewActivity.this,   
                                                        "数据修改为:" + editStr + "",   
                                                        Toast.LENGTH_SHORT).show();   
      
                                            }   
                                        }   
      
                                    }   
                                })   
                        .setNegativeButton("取消",   
                                new DialogInterface.OnClickListener() { /* 设置跳出窗口的返回事件 */  
                                    public void onClick(   
                                            DialogInterface dialoginterface, int i) {   
                                        Toast.makeText(UpdateListViewActivity.this,   
                                                "取消了修改数据", Toast.LENGTH_SHORT)   
                                                .show();   
      
                                    }   
                                }).show();   
      
            }   
        };   
      
        // 查询事件响应   
        OnClickListener queryClick = new OnClickListener() {   
      
            public void onClick(View v) {   
                // TODO Auto-generated method stub   
                // 查询数据   
                listItemAdapter.notifyDataSetChanged();   
            }   
        };   
      
        // 初始化数据   
        private void init() {   
      
            listItem = new ArrayList<HashMap<String, Object>>();   
            for (int i = 0; i < 12; i++) {   
                HashMap<String, Object> map = new HashMap<String, Object>();   
                map.put("viewspot", "雪饮狂刀:" + i);   
                map.put("add", R.drawable.right);   
                listItem.add(map);   
            }   
            listItemAdapter = new SimpleAdapter(getApplicationContext(), listItem,// 数据源   
                    R.layout.items, new String[] { "viewspot", "add" }, new int[] {   
                            R.id.viewspot, R.id.add });   
            listview.setAdapter(listItemAdapter);   
      
        }  
        
    
    }  

     注意事项:

    ->1:Inflate()和findViewById()区分使用,以及两种之间的逻辑关系?

    findViewById()只能找出当前布局中的组件,即setConentView()的那个layout里的组件.

    如果你的Activity里用到别的layout,比如对话框layout,你还要设置这个layout上的其他组件的内容,你就必须用inflate()方法先将对话框的layout找出来,然后再用findViewById()找到它上面的其它组件

    ->2:对数据源的增删改查,这只是对数据的操作而已,手机上面的ListView列表视图组件必须刷新显示,需要调用到notifyDataSetChanged()方法,就可以实现对listview数据的更新。如果涉及到线程,则需要在UI的线程更新。

    ->3:DialogInterface.OnClickListener接口实现方法Onclick()

    public abstract void onClick (DialogInterface dialog, int which)  :对话框中的按钮按下时执行的方法.

    参数: dialog  发生按钮按下事件的对话框(当一个Activity有多个对话框时,利用这个参数确定特定的对话框

             which   按下的按钮(例如:BUTTON1) 或按下的条目位置

    对于which参数,如下:利用which参数按下的按钮(例如:BUTTON1) 或按下的条目位置

    AlertDialog.Builder builder = new AlertDialog.Builder(this);
      builder.setMessage("Are you sure you want to exit?")
    .setCancelable(false)
    .setPositiveButton("Yes",this)
    .setNegativeButton("No", this);
    AlertDialog alert = builder.create();
    alert.show();
    @Override
    public void onClick(DialogInterface dialog, int which) {
      // TODO Auto-generated method stub
      Log.e("---------------", which + "");
      switch (which) {
      case -1:
       Log.i("info", "你点击的YES~");
       AndProgressActivity.this.finish();
       break;
      case -2:
       Log.i("info", "你点击的NO~");
       dialog.cancel();
       break;
      default:
       break;
      }
    }
  • 相关阅读:
    Linux内存管理 —— 为buddy做准备:MMU, TLB, ZONE【转】
    Linux内存管理 —— 文件系统缓存和匿名页的交换【转】
    linux内存源码分析
    Linux中匿名页的反向映射【转】
    zram 简介【转】
    Linux Swap 与 Zram 详解【转】
    Linux中的mmap映射 [一]【转】
    Linux中的mmap映射 [二]【转】
    python测试开发django-rest-framework-95.文件上传接口开发
    Airtest IDE 自动化测试8
  • 原文地址:https://www.cnblogs.com/hebao0514/p/4749976.html
Copyright © 2020-2023  润新知