实验要求

基于SQlite,ListView实现一个通信录,设计UI的同时实现以下功能:
1)录入用户姓名、电话;
2)通过姓名查找用户信息;
3)查看全部用户信息;
4)实现删除指定用户的信息;
4)实现更新指定用户的信息;

关于ListView刷新

在本实验中使用的适配器是BaseAdapter,刚开始没有在适配器定义List变量类型,而是直接声明一个全局变量results,进行数据的增删查改:

class MyBaseAdapter extends BaseAdapter{ private List<Info> results;//这是Adapter的数据,一定要有,刷新也是看个类的数据是否改变        @Override        public int getCount() {            return results.size();        }        //得到Item代表的对象        @Override        public Object getItem(int position) {            return results.get(position);        }        //得到Item的id        @Override        public long getItemId(int position) {            return position;        }        @Override        public View getView(int position, View convertView, ViewGroup parent) {            //加载ListView的Item布局            View view = View.inflate(MainActivity.this, R.layout.list_item, null);            TextView textView = view.findViewById(R.id.item);            textView.setText("name  :  "+ results.get(position).getName() + " tel   :  "+ results.get(position).getTel());            return view;        }    }

结果数据不能刷新,解决方法是:需要在适配器中声明变量,然后调用适配器的方法:notifyDataSetChanged() ,这样如果适配器中的变量变化时,这个方法就会被调用,然后进行刷新操作.

编码规范总结

  1. 边界问题

当能刷新ListView之后,出现一个边界问题: 当我删除了最后一条数据之后,listView还显示它.发现是清空List出现了问题:先前我是如果搜索到数据时才进行List的清空,殊不知当删除最后一条数据后,数据表已空,而这个条数据就没有被清空,留在ListView上.
改正: 当搜索数据时,先进行清空操作,然后再搜索数据,判断为空或者List.add().

  1. 条件判断

下面代码的第一个if语句中,我是想当没有数据时,就提示没有数据,然后没了…就是有数据的情况,然后光顾着有数据的情况了.

SQLiteDatabase db = helper.getReadableDatabase();        Cursor cursor = null ;if( cursor == null ||  cursor.getCount() == 0 ){  //防止出现异常            Toast.makeText(this,"没有数据",Toast.LENGTH_SHORT).show();        }else{            cursor.moveToFirst();            Info info = new Info();           // newList.clear();// 每次查询结果前必须先清空之前的数据 ,边界情况没有考虑清楚----当最后一条数据删除之后,还会保留显示,应该在查询之前就清空            //baseAdapter.results.clear();            info.setName(cursor.getString(1));            info.setTel(cursor.getString(2));            newList.add(info);        }        while (cursor.moveToNext()){            newList.add(new Info(cursor.getString(1),cursor.getString(2)));        }        baseAdapter.results = newList; //保持同一片内存        baseAdapter.notifyDataSetChanged();//刷新        cursor.close();        db.close();

改正:

if( cursor == null ||  cursor.getCount() == 0 ){  //防止出现异常            Toast.makeText(this,"没有数据",Toast.LENGTH_SHORT).show();            if(cursor!=null) cursor.close();            db.close();            return;        }

return之前一定要记得关闭一些数据操作流.还有对初始值null也要进行判断:如果cursor为null,就不存在cursor.close()!

通过id删除数据,更新数据

点击ListView获取点击对应sqlite那一行的id, 我们知道position是listview布局中的位置,我们可以用position来获得我们想要的id:点击listview, 调用下面的函数:

resultList.setOnItemClickListener(new AdapterView.OnItemClickListener() {            @Override            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {                Info info = baseAdapter.results.get(position);                nameText.setText(info.getName());                telText.setText(info.getTel());                SQLiteDatabase db = helper.getReadableDatabase();                Cursor cursor = db.query("information",null,null,null,null,null,null);                cursor.moveToPosition(position);                Id  = cursor.getString(0); //获得点击Item的id                //关闭流                cursor.close();                db.close();            }        });

我表的设计是这样的:db.execSQL("CREATE table information(id INTEGER PRIMARY KEY AUTOINCREMENT,name VARCHAR(20),tel VARCHAR(20))"); cursor获得第一个列的值是cursor.getString(0)

Id 已作为全局变量进行使用, 方便后面的delete函数和update函数使用:

public int update(String name,String tel){        if(Id == null || Id.length()==0){            Toast.makeText(this,"请选中数据行,再进行更新!",Toast.LENGTH_SHORT).show();            return 0;        }                SQLiteDatabase db = helper.getWritableDatabase();        ContentValues contentValues = new ContentValues();        contentValues.put("name",name);        contentValues.put("tel",tel);        int number = db.update("information",contentValues,"id=?",new String[]{Id}); //根据id更新数据        db.close();        updateUI(); //刷新布局        return  number;    }public int delete(){        if(Id == null || Id.length()==0){            Toast.makeText(this,"请选中数据行,再进行删除!",Toast.LENGTH_SHORT).show();            return 0;        }        SQLiteDatabase db = helper.getWritableDatabase();        int num = db.delete("information","id = ? ",new String[]{Id});        db.close();        updateUI();//刷新布局        return num;    }

布局刷新

前面谈到ListView的刷新: 通过Adapter的方法notifyDataSetChanged() :baseAdapter.notifyDataSetChanged();//适配器数据如果发生变化就刷新 但光有这个还不算完.前提是Adapter数据得有变化,这个方法才起作用. 当你删除/更新一条数据后, 直接使用notifyDataSetChanged()是不能够刷新的,因为list 没有变化,所以需要重新"查询数据, 将查询的结果再添加到list中,这样list数据就会发生变化,这时再调用notifyDataSetChanged就起作用了":

public void updateUI(){        nameText.setText("");        telText.setText("");        Id="";        search("",""); //每次必须重新将数据进行刷新,重新查询,然后布局根据数据来刷新        baseAdapter.notifyDataSetChanged();//适配器数据如果发生变化就刷新    }

UI布局设计

main.xml

<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:app="http://schemas.android.com/apk/res-auto"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:paddingLeft="20dp"    android:paddingBottom="20dp"    android:paddingRight="20dp"    android:paddingTop="20dp"    android:orientation="vertical"    tools:context=".MainActivity">    <LinearLayout        android:id="@+id/L1"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:layout_alignParentTop="true"        android:layout_centerHorizontal="true"        android:layout_marginTop="30dp"        android:background="#ffffff">        <TextView            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:text="姓 名:"            android:textSize="30sp" />        <EditText            android:layout_width="match_parent"            android:layout_height="match_parent"            android:id="@+id/name"            android:maxLines="1"            android:hint="请输入姓名" />    LinearLayout>    <LinearLayout        android:id="@+id/L2"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:layout_below="@+id/L1"        android:background="#ffffff"        android:layout_marginTop="10dp">        <TextView            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:text="电话:"            android:textSize="30sp"            />        <EditText            android:layout_width="match_parent"            android:layout_height="match_parent"            android:id="@+id/tel"            android:maxLines="1"            android:hint="请输入电话"            />    LinearLayout>    <LinearLayout        android:id="@+id/L3"        android:layout_below="@+id/L2"        android:layout_marginTop="10dp"        android:layout_width="match_parent"        android:layout_height="wrap_content">        <Button            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_weight="1"            android:id="@+id/add_b"            android:text="添加"            />        <Button            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_weight="1"            android:id="@+id/search_b"            android:text="查询"/>        <Button            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_weight="1"            android:id="@+id/delete_b"            android:text="删除"/>        <Button            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_weight="1"            android:id="@+id/update_b"            android:text="更新"/>    LinearLayout>    <ListView        android:id="@+id/result_list"        android:layout_below="@id/L3"        android:layout_width="match_parent"        android:layout_height="wrap_content">    ListView>RelativeLayout>

List_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">    <TextView        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:id="@+id/item"        android:text="这是list_item"        android:textSize="30sp"/>LinearLayout>

源代码

package jzt.com.shiyan5;import android.content.ContentValues;import android.database.Cursor;import android.database.sqlite.SQLiteDatabase;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.view.View;import android.view.ViewGroup;import android.widget.AdapterView;import android.widget.BaseAdapter;import android.widget.Button;import android.widget.EditText;import android.widget.ListView;import android.widget.TextView;import android.widget.Toast;import java.util.ArrayList;import java.util.List;public class MainActivity extends AppCompatActivity implements View.OnClickListener{    private EditText nameText;    private EditText telText;    private ListView resultList;    private Button search_b;    private Button delete_b;    private Button update_b;    private Button add_b;    private String Id ="";    MyHelper helper;    MyBaseAdapter baseAdapter;    private List<Info> newList;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        //创建SQLite数据库        helper = new MyHelper(this);        init();    }    public void init(){        nameText = findViewById(R.id.name);        telText = findViewById(R.id.tel);        //初始化控件        resultList = findViewById(R.id.result_list);        //创建一个Adapter实例        baseAdapter = new MyBaseAdapter();        baseAdapter.results = new ArrayList<>();        //设置Adapter        resultList.setAdapter(baseAdapter);        search_b = findViewById(R.id.search_b);        delete_b = findViewById(R.id.delete_b);        update_b = findViewById(R.id.update_b);        add_b = findViewById(R.id.add_b);        search_b.setOnClickListener(this);        delete_b.setOnClickListener(this);        update_b.setOnClickListener(this);        add_b.setOnClickListener(this);        newList = new ArrayList<>();        resultList.setOnItemClickListener(new AdapterView.OnItemClickListener() {            @Override            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {                Info info = baseAdapter.results.get(position);                nameText.setText(info.getName());                telText.setText(info.getTel());                SQLiteDatabase db = helper.getReadableDatabase();                Cursor cursor = db.query("information",null,null,null,null,null,null);                cursor.moveToPosition(position);                Id  = cursor.getString(0); //获得点击Item的id                //关闭流                cursor.close();                db.close();            }        });    }    @Override    public void onClick(View v) {        switch (v.getId()){            case R.id.add_b:                insert(nameText.getText().toString().trim(),telText.getText().toString().trim());                break;            case R.id.search_b:                search(nameText.getText().toString().trim(),telText.getText().toString().trim());                break;            case R.id.delete_b:                int num1 = delete();                if (num1 == 1){                    Toast.makeText(this,"删除信息成功",Toast.LENGTH_SHORT).show();                }else if(num1 == 0){                    Toast.makeText(this,"删除信息失败",Toast.LENGTH_SHORT).show();                }                break;            case R.id.update_b:                int num = update(nameText.getText().toString().trim(),telText.getText().toString().trim());                if(num==0 || num==-1){                    Toast.makeText(this,"修改信息失败",Toast.LENGTH_SHORT).show();                }else if(num==1){                    Toast.makeText(this,"信息修改成功",Toast.LENGTH_SHORT).show();                }                break;        }    }    public void updateUI(){        nameText.setText("");        telText.setText("");        Id="";        search("",""); //每次必须重新将数据进行刷新,重新查询,然后布局根据数据来刷新        baseAdapter.notifyDataSetChanged();//适配器数据如果发生变化就刷新    }    public int update(String name,String tel){        if(Id == null || Id.length()==0){            Toast.makeText(this,"请选中数据行,再进行更新!",Toast.LENGTH_SHORT).show();            return 0;        }        SQLiteDatabase db = helper.getWritableDatabase();        ContentValues contentValues = new ContentValues();        contentValues.put("name",name);        contentValues.put("tel",tel);        int number = db.update("information",contentValues,"id=?",new String[]{Id}); //根据id更新数据        db.close();        updateUI(); //刷新布局        return  number;    }    public void insert(String name,String tel){        if(name.trim().length()==0||tel.trim().length()==0){            Toast.makeText(this,"姓名或者电话号码不能为空!",Toast.LENGTH_SHORT).show();            return;        }        name = name.trim();        tel = tel.trim();        SQLiteDatabase writableDatabase = helper.getWritableDatabase();        ContentValues contentValues = new ContentValues();        contentValues.put("name",name);        contentValues.put("tel",tel);        //第一个参数是数据库的表 第二个是如果是将要插入的行为空行时,这个列名设为null,第三个参数为contentvalues        writableDatabase.insert("information",null,contentValues);        Toast.makeText(this,"数据添加成功",Toast.LENGTH_SHORT).show();        updateUI();//将所填数据置空        writableDatabase.close();    }    public int delete(){        if(Id == null || Id.length()==0){            Toast.makeText(this,"请选中数据行,再进行删除!",Toast.LENGTH_SHORT).show();            return 0;        }        SQLiteDatabase db = helper.getWritableDatabase();        int num = db.delete("information","id = ? ",new String[]{Id});        db.close();        updateUI();//刷新布局        return num;    }    //根据名字搜索    public void search(String name,String tel){        SQLiteDatabase db = helper.getReadableDatabase();        Cursor cursor = null ;        //在查询之前就先将 数据进行清空        newList.clear();        baseAdapter.results.clear();        name = name.trim();        tel = tel.trim();        if(name.length()==0 && tel.length()==0){            cursor = db.query("information",null,null,null,null,null,null);        }else if(name.length()!=0 && tel.length()==0){            cursor = db.query("information", null, "name=?", new String[]{name }, null, null, null);        }else if(name.length()==0&&tel.length()!=0){            cursor = db.query("information",null,"tel=?",new String[]{tel},null,null,null);        }else if(name.length()!=0 && tel.length()!=0){            cursor = db.query("information",null,"name=? and tel=?",new String[]{name , tel},null,null,null);        }else if(name.length()==0 && tel.length() ==0){            cursor = db.query("information",null,null,null,null,null,null) ;        }        if( cursor == null ||  cursor.getCount() == 0 ){  //防止出现异常            Toast.makeText(this,"没有数据",Toast.LENGTH_SHORT).show();            if(cursor!=null) cursor.close();            db.close();            return;        }else{            cursor.moveToFirst();            Info info = new Info();           // newList.clear();// 每次查询结果前必须先清空之前的数据 ,边界情况没有考虑清楚----当最后一条数据删除之后,还会保留显示,应该在查询之前就清空            //baseAdapter.results.clear();            info.setName(cursor.getString(1));            info.setTel(cursor.getString(2));            newList.add(info);        }        while (cursor.moveToNext()){            newList.add(new Info(cursor.getString(1),cursor.getString(2)));        }        baseAdapter.results = newList; //保持同一片内存        baseAdapter.notifyDataSetChanged();//刷新        Toast.makeText(this,"为您查询到"+newList.size()+"条数据",Toast.LENGTH_SHORT).show();        cursor.close();        db.close();    }    class MyBaseAdapter extends BaseAdapter{        private List<Info> results;//这是Adapter的数据,一定要有,刷新也是看个类的数据是否改变        @Override        public int getCount() {            return results.size();        }        //得到Item代表的对象        @Override        public Object getItem(int position) {            return results.get(position);        }        //得到Item的id        @Override        public long getItemId(int position) {            return position;        }        @Override        public View getView(int position, View convertView, ViewGroup parent) {            //加载ListView的Item布局            View view = View.inflate(MainActivity.this, R.layout.list_item, null);            TextView textView = view.findViewById(R.id.item);            textView.setText("name  :  "+ results.get(position).getName() + " tel   :  "+ results.get(position).getTel());            return view;        }    }}

Info.java

package jzt.com.shiyan5;public class Info {    private  String  name;    private String tel;    public Info(){    }    public Info(String name,String tel){        this.name = name;        this.tel = tel;    }    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }    public String getTel() {        return tel;    }    public void setTel(String tel) {        this.tel = tel;    }}

更多相关文章

  1. Android实现登录功能,Android与服务器数据交互,使用tomcat、mysql
  2. Android(安卓)RecyclerView和ListView多布局实现
  3. 可左右两侧挤压傍边布局的Android抽屉
  4. 老罗的Android视频教程整理之常用布局
  5. android开发动态页面时常用的LayoutInflater实例化的三种方式
  6. Android中的布局方式(一)
  7. Android绘图机制(三) ViewGroup类的延伸
  8. Android(安卓)数据库SQLite更新升级问题
  9. Android数据加密之异或加密算法

随机推荐

  1. Android(安卓)layout xml总结(2)
  2. android WebView总结
  3. android 2D教程精华集合贴
  4. Android(安卓)体系结构介绍
  5. 【转】每个Android开发者都应该了解的资
  6. Android---Menu
  7. Android(安卓)之 shape和selector用法介
  8. android设置全屏以及解决设置全屏无效的
  9. Android---进程间通机制的简单理解
  10. Android(安卓)XML布局报错:android/view/V