listview和sqlist实现学生列表增删改查

实现界面和代码

     总项目结构

        listview和sqlist实现学生列表增删改查_第1张图片

   student实体类

   

public class student implements Serializable{
    private int id;
    private String name;
    private String sex;
    private int age;

    student(int i,String n,String s,int a){
        id=i;name=n;sex=s;age=a;
    }
    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}
 MySQLiteAccess  (需要继承SQLiteOpenHelper)
package com.example.databasetest;

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
public class MySQLiteAccess extends SQLiteOpenHelper{

    /**
     *
     * @param context :上下文
     * @param name:数据库名称
     * @param factory
     * @param version:版本号
     */
    public MySQLiteAccess(Context context,int version) {
        super(context, "stuAdmin.db", null, version);
    }

    /**
     * 数据库文件创建成功后调用
     * SQL操作的语句
     * @param db
     */
    @Override
    public void onCreate(SQLiteDatabase db) {
        System.out.println("数据库创建");
        db.execSQL("create table student(\n"+
        "id integer,\n"+
        "name text,\n"+
        "sex text,\n"+
        "age integer\n"+
        ");");
    }

    /**
     * 在更新数据库后调用方法
     * @param db
     * @param oldVersion 旧版本
     * @param newVersion 新版本
     */
    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        System.out.println("数据库更新");
    }
}

     DBOperate   (里面定义对数据库的各操作)

package com.example.databasetest;


import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;

import java.util.ArrayList;
import java.util.List;


public class DBOperate {
    private MySQLiteAccess mySQLiteAccess;
    private SQLiteDatabase database;

    public void test(Context context){
        mySQLiteAccess=new MySQLiteAccess(context,3);
        database=mySQLiteAccess.getReadableDatabase();
    }
    public void insert(student s){
        database.execSQL("insert into student values(?,?,?,?)",new Object[] {s.getId(),s.getName(),s.getSex(),s.getAge()});
        System.out.println("插入数据成功");
    }
    public void delete(int id){
        Integer I=new Integer(id);
        database.execSQL("delete from student where id=?",new Object[]{I});
    }
    public List searchByName(String key){
       List listByName=new ArrayList();
        key="%"+key+"%";
        Cursor cursor=database.rawQuery("select * from student where name like?",new String[]{key});
        while(cursor.moveToNext()){
            int id=cursor.getInt(cursor.getColumnIndex("id"));
            String name=cursor.getString(cursor.getColumnIndex("name"));
            String sex=cursor.getString(cursor.getColumnIndex("sex"));
            int age=cursor.getInt(cursor.getColumnIndex("age"));
            listByName.add(new student(id,name,sex,age));
        }
        return listByName;
    }

    public List queryAll(){
        List stus=new ArrayList();
        Cursor cursor=database.rawQuery("select * from student",null);
        while(cursor.moveToNext()){
            int id=cursor.getInt(cursor.getColumnIndex("id"));
            String name=cursor.getString(cursor.getColumnIndex("name"));
            String sex=cursor.getString(cursor.getColumnIndex("sex"));
            int age=cursor.getInt(cursor.getColumnIndex("age"));
            stus.add(new student(id,name,sex,age));
        }
        return stus;
    }

    public void update(student stu) {
        database.execSQL("update student set name=?,sex=?,age=? where id=?"
                ,new Object[] { stu.getName(), stu.getSex(), stu.getAge(),stu.getId() });
    }

    public List searchByAll(String key){
        List listByAll=new ArrayList();
        key="%"+key+"%";
        Cursor cursor=database.rawQuery("select * from student where id like? or name like? or sex like? or age like?"
                ,new String[]{key,key,key,key});
        while(cursor.moveToNext()){
            int id=cursor.getInt(cursor.getColumnIndex("id"));
            String name=cursor.getString(cursor.getColumnIndex("name"));
            String sex=cursor.getString(cursor.getColumnIndex("sex"));
            int age=cursor.getInt(cursor.getColumnIndex("age"));
            listByAll.add(new student(id,name,sex,age));
        }
        return listByAll;
    }
}

    MyAdapter   (自定义适配器,继承BaseAdapter)

package com.example.databasetest;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.TextView;

import java.util.List;

public class MyAdapter extends BaseAdapter{

    private List list;//数据源
    private LayoutInflater inflater;//布局加载器
    DBOperate dbOperate=new DBOperate();

    //有参的构造函数,为数据源,上下文对象复制,同时实例化布局加载器
    public MyAdapter(List list,Context context) {
        this.list=list;
        inflater=LayoutInflater.from(context);
        dbOperate.test(context);  //初始化一下数据库,不然后面delete用的时候database是空的
    }

    //有多少条数据,需要创建多少个item布局
    @Override
    public int getCount() {
        return list.size();
    }

    //返回position对应位置的数据
    @Override
    public Object getItem(int position) {
        return list.get(position);
    }

    //返回position对应位置item的id
    @Override
    public long getItemId(int position) {
        return position;
    }

    /**
     * 具体定义加载item布局,并将数据显示到item布局上的方法。
     * @param position
     * @param convertView
     * @param parent
     * @return
     */
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        //加载stulist布局 将xml布局加载到内存中,形成一个view
        final View view=inflater.inflate(R.layout.stulist,null);
        //实例化stulist布局上的控件
        TextView tv_stuID= (TextView) view.findViewById(R.id.tv_stuID);
        TextView tv_stuName= (TextView) view.findViewById(R.id.tv_stuName);
        TextView tv_stuSex= (TextView) view.findViewById(R.id.tv_stuSex);
        TextView tv_stuAge= (TextView) view.findViewById(R.id.tv_stuAge);
        Button btn_del=(Button) view.findViewById(R.id.btn_del);
        Button btn_alert=(Button) view.findViewById(R.id.btn_alert);
        //往控件上显示数据
        //获取position对应位置的数据
        final student oneStu= (student) getItem(position);

        //不转String就会android.content.res.Resources$NotFoundException: String resource ID #0x1
        tv_stuID.setText(String.valueOf(oneStu.getId()));
        tv_stuName.setText(oneStu.getName());
        tv_stuSex.setText(oneStu.getSex());
        tv_stuAge.setText(String.valueOf(oneStu.getAge()));

        //设置按钮的点击事件
        btn_del.setOnClickListener(new View.OnClickListener(){

            @Override
            public void onClick(View v) {
                dbOperate.delete(oneStu.getId());
                list.remove(oneStu);
                MyAdapter.this.notifyDataSetChanged();
            }
        });
        btn_alert.setOnClickListener(new View.OnClickListener(){

            @Override
            public void onClick(View v) {
                Context context=view.getContext();
                Intent intent=new Intent();
                intent.setClass(context,UpdateDialog.class);
                intent.putExtra("altStu",oneStu);
                ((Activity)context).startActivity(intent);
            }
        });
        return view;
    }
}

    stulist.xml     (对应listView里一行的布局)



    
    
    
    
    

 

     activity_main.xml

     listview和sqlist实现学生列表增删改查_第2张图片

     




    
    
        
        

   MainActivity

package com.example.databasetest;
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import java.util.ArrayList;
import java.util.List;

public class MainActivity extends AppCompatActivity implements View.OnClickListener {
    private ListView lv_stulist;
    private EditText et_id;
    private EditText et_name;
    private EditText et_sex;
    private EditText et_age;
    private EditText et_search;
    private Button btn_add;
    private Button btn_search;
    private Listlist=new ArrayList();
    DBOperate dbOperate=new DBOperate();
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        lv_stulist=(ListView)findViewById(R.id.lv_stulist);
        et_id=(EditText)findViewById(R.id.et_id);
        et_name=(EditText)findViewById(R.id.et_name);
        et_sex=(EditText)findViewById(R.id.et_sex);
        et_age=(EditText)findViewById(R.id.et_age);
        et_search=(EditText)findViewById(R.id.et_search);
        btn_add=(Button)findViewById(R.id.btn_add);
        btn_search=(Button)findViewById(R.id.btn_search);
        btn_add.setOnClickListener(this);
        btn_search.setOnClickListener(this);
        dbOperate.test(this);
        list=dbOperate.queryAll();
        if(!list.isEmpty()){
            showList(list);
        }
    }

    private void showList(List stus){
        /*List> stuMap=new ArrayList>();
        for(student s:stus){
            Map m=new HashMap();
            m.put("id",s.getId());
            m.put("name",s.getName());
            m.put("sex",s.getSex());
            m.put("age",s.getAge());
            stuMap.add(m);
        }
        String[] key={"id","name","sex","age"};
        int[] value={R.id.tv_stuID,R.id.tv_stuName,R.id.tv_stuSex,R.id.tv_stuAge};*/
//        SimpleAdapter simpleAdapter=new SimpleAdapter(this,stuMap,R.layout.stulist,key,value);
//        lv_stulist.setAdapter(simpleAdapter);
        MyAdapter myAdapter=new MyAdapter(stus,this);
        lv_stulist.setAdapter(myAdapter);
    }
    @Override
    public void onClick(View v) {
        if(v.getId()==R.id.btn_add){
            int id=Integer.parseInt(et_id.getText().toString());
            String name=et_name.getText().toString();
            String sex=et_sex.getText().toString();
            int age=Integer.parseInt(et_age.getText().toString());
            dbOperate.insert(new student(id,name,sex,age));
            list=dbOperate.queryAll();
            if(!list.isEmpty()){
                showList(list);
            }
        }else if(v.getId()==R.id.btn_search){
            String search=et_search.getText().toString();
            if(search.isEmpty())return;
            Intent intent=new Intent();
            intent.setClass(this,SearchActivity.class);
            intent.putExtra("searchKey",search);
            startActivity(intent);
        }
    }
}

   activity_update_dialog.xml   (修改界面布局)




    
    
        
        
    
    
        
        
    
    
        
        
    
    

    UpdateDialog     (修改界面,本来想做弹出框样式,由于一些问题没解决,就这样丑陋的实现了)

package com.example.databasetest;

import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;

public class UpdateDialog extends AppCompatActivity implements View.OnClickListener {

    private EditText et_alName;
    private EditText et_alSex;
    private EditText et_alAge;
    private Button btn_submit;
    private student altStu=null;
    DBOperate dbOperate=new DBOperate();
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_update_dialog);
        et_alName=(EditText)findViewById(R.id.et_alName);
        et_alSex=(EditText)findViewById(R.id.et_alSex);
        et_alAge=(EditText)findViewById(R.id.et_alAge);
        btn_submit=(Button)findViewById(R.id.btn_submit);
        btn_submit.setOnClickListener(this);
        initEditText();
        dbOperate.test(this);
    }

    private void initEditText(){
        Bundle bundle=getIntent().getExtras();
        altStu=(student)bundle.get("altStu");
        if(altStu!=null){
            et_alName.setText(altStu.getName());
            et_alSex.setText(altStu.getSex());
            et_alAge.setText(String.valueOf(altStu.getAge()));
        }
    }
    @Override
    public void onClick(View v) {
        Intent intent=new Intent();
        String name=et_alName.getText().toString();
        String sex=et_alSex.getText().toString();
        int age=Integer.parseInt(et_alAge.getText().toString());
        if(altStu!=null){
            altStu.setName(name);
            altStu.setSex(sex);
            altStu.setAge(age);
            dbOperate.update(altStu);
        }
        intent.setClass(this,MainActivity.class);
        startActivity(intent);
        finish();
    }
}

  activity_search.xml  (搜索界面布局)




    

   SearchActivity 

package com.example.databasetest;

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

import java.util.List;

public class SearchActivity extends AppCompatActivity implements View.OnClickListener {

    private Button btn_return;
    private ListView lv_searchlist;
    private TextView tv_searchText;
    private TextView tv_searchSum;
    DBOperate dbOperate=new DBOperate();
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_search);
        lv_searchlist=(ListView)findViewById(R.id.lv_searchlist);
        tv_searchText=(TextView)findViewById(R.id.tv_searchText);
        tv_searchSum=(TextView)findViewById(R.id.tv_searchSum);
        btn_return=(Button)findViewById(R.id.btn_return);
        btn_return.setOnClickListener(this);
        dbOperate.test(this);
        Bundle bundle=getIntent().getExtras();
        String searchKey=bundle.getString("searchKey");
        List searchList=dbOperate.searchByAll(searchKey);
        tv_searchText.setText(searchKey);
        tv_searchSum.setText(String.valueOf(searchList.size()+"条信息"));
        if (!searchList.isEmpty()){
            MyAdapter myAdapter=new MyAdapter(searchList,this);
            lv_searchlist.setAdapter(myAdapter);
        }
    }
    @Override
    public void onClick(View v) {
        Intent intent=new Intent();
        intent.setClass(this,MainActivity.class);
        startActivity(intent);
    }
}

  结果截图

    listview和sqlist实现学生列表增删改查_第3张图片 

   listview和sqlist实现学生列表增删改查_第4张图片   

 listview和sqlist实现学生列表增删改查_第5张图片

遇到的问题

   问题1:现学自定义Adapter

     由于在列表中要使用删除按钮,所以普通的ListView不能满足需求,我需要自定义Adapter

     参考博文https://blog.csdn.net/ytfunnysite/article/details/55263139

    

    问题2:关于TextView.setText里参数是int时报错

      报错信息如下

E/AndroidRuntime: FATAL EXCEPTION: main
                                                   Process: com.example.databasetest, PID: 13838
                                                   android.content.res.Resources$NotFoundException: String resource ID #0x1
                                                       at android.content.res.Resources.getText(Resources.java:378)
                                                       at android.widget.TextView.setText(TextView.java:4685)
                                                       at com.example.databasetest.MyAdapter.getView(MyAdapter.java:71)

           我在https://blog.csdn.net/owenchan1987/article/details/72824096找到了问题

           修改后  tv_stuID.setText(String.valueOf(oneStu.getId()));

问题3:SQLiteDatabase.execSQL(java.lang.String, java.lang.Object[])' on a null object reference

           报错信息如下:   

 Process: com.example.databasetest, PID: 20630
                                                                          java.lang.NullPointerException: Attempt to invoke virtual method 'void android.database.sqlite.SQLiteDatabase.execSQL(java.lang.String, java.lang.Object[])' on a null object reference
                                                                              at com.example.databasetest.DBOperate.delete(DBOperate.java:29)
                                                                              at com.example.databasetest.MyAdapter$1.onClick(MyAdapter.java:80)
                                                                              at android.view.View.performClick(View.java:5774)
                                                                              at android.view.View$PerformClick.run(View.java:22990)
                                                                              at android.os.Handler.handleCallback(Handler.java:836)
                                                                              at android.os.Handler.dispatchMessage(Handler.java:103)
                                                                              at android.os.Looper.loop(Looper.java:203)
                                                                              at android.app.ActivityThread.main(ActivityThread.java:6564)
                                                                              at java.lang.reflect.Method.invoke(Native Method)
                                                                              at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1134)
                                                                              at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:995)

  具体在DBOperate 里    

  起初我以为是new Object[] {I}这里有错,经过多次debug发现这个值是拿到了的,而且也转成Integer了,在网上很多人说这个空对象的错可能是findViewById()的原因,我又排查了一遍发现没有漏掉的。最后,大半天之后,又一次debug时突然看到database是null的。listview和sqlist实现学生列表增删改查_第6张图片 由于前面调试insert时是成功了的,所以我就没去注意database的情况。

     以下是我写在mainactivity里的添加学生

listview和sqlist实现学生列表增删改查_第7张图片

实际上,在mainActivity里的oncreate()里已经将数据库初始化了dbOperate.test(this);,所以在使用insert没有报错。但是在Adapter里是通过DBOperate对象来调用里面的删除方法,没有初始化数据库

listview和sqlist实现学生列表增删改查_第8张图片listview和sqlist实现学生列表增删改查_第9张图片

所以在删除时报的空对象其实指的这里的database

找到问题所在就好办了,第一种解决,在DBOperate里每个方法里都初始化一下数据库,还有就是在需要用到DBOperate时,new一个对象后就初始化一下。再不然就在MainActivity里的DBOperate设置为全局变量。果然,我在Adapter的构造函数里初始化一下数据库就没问题了。

listview和sqlist实现学生列表增删改查_第10张图片   listview和sqlist实现学生列表增删改查_第11张图片

 

问题4:

   报错

Process: com.example.databasetest, PID: 30263
                                                                          java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.databasetest/com.example.databasetest.UpdateDialog}: java.lang.IllegalStateException: You need to use a Theme.AppCompat theme (or descendant) with this activity.
                                                                              at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2931)
                                                                              at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2996)
                                                                              at android.app.ActivityThread.-wrap12(ActivityThread.java)
                                                                              at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1700)

参考解决办法:https://www.cnblogs.com/softidea/p/4823023.html

修改成       

问题5:自定义Adapter中实现startActivityForResult的分析

      因为在list里要实现修改的话,就要点击list里按钮跳转去修改,再传回值。本来以为不能用startActivityForResult,后来看论坛里有人说可以强制转换context为activity。参考博文https://blog.csdn.net/zhencheng20082009/article/details/62418777

  暂时没有解决,我最后是直接修改后跳主页面,个人觉得用户体验感不好,这里应该只刷新list界面

问题六:关于sqlist3的模糊查询问题

       最初是这样的:接收到输入框里的值了,但是查不到

       数据库操作是这样的

listview和sqlist实现学生列表增删改查_第12张图片

  后来觉得是sql语句出错了。果真,请参考博文https://blog.csdn.net/shareye1992/article/details/51699763

  改成key="%"+key+"%";就可

问题6:listView有很多项时的滚动问题

     关于这个滚动,我在网上翻了好一会都没解决,以前用list View的时候好像没怎么遇到这个问题。后来让我翻着翻着就发现一个小细节。之前,我的listView的宽和高都是wrap_content,这导致了后面如果我的数据多的话,listview的高就越来越高,就会把listview下面的布局挤到更下面去看不见。所以我们要给定listView高度,这样当有多项时,就自然出来可以上下滑动了。

   listview和sqlist实现学生列表增删改查_第13张图片

 

待解决的问题:如何建立adapter的activity去复写onActivityResult()那个方法?????????

你可能感兴趣的:(个人问题)