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
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
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不能满足需求,我需要自定义Adapter
参考博文https://blog.csdn.net/ytfunnysite/article/details/55263139
报错信息如下
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()));
报错信息如下:
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)
起初我以为是new Object[] {I}这里有错,经过多次debug发现这个值是拿到了的,而且也转成Integer了,在网上很多人说这个空对象的错可能是findViewById()的原因,我又排查了一遍发现没有漏掉的。最后,大半天之后,又一次debug时突然看到database是null的。 由于前面调试insert时是成功了的,所以我就没去注意database的情况。
以下是我写在mainactivity里的添加学生
实际上,在mainActivity里的oncreate()里已经将数据库初始化了dbOperate.test(this);,所以在使用insert没有报错。但是在Adapter里是通过DBOperate对象来调用里面的删除方法,没有初始化数据库
所以在删除时报的空对象其实指的这里的database
找到问题所在就好办了,第一种解决,在DBOperate里每个方法里都初始化一下数据库,还有就是在需要用到DBOperate时,new一个对象后就初始化一下。再不然就在MainActivity里的DBOperate设置为全局变量。果然,我在Adapter的构造函数里初始化一下数据库就没问题了。
报错
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
因为在list里要实现修改的话,就要点击list里按钮跳转去修改,再传回值。本来以为不能用startActivityForResult,后来看论坛里有人说可以强制转换context为activity。参考博文https://blog.csdn.net/zhencheng20082009/article/details/62418777
暂时没有解决,我最后是直接修改后跳主页面,个人觉得用户体验感不好,这里应该只刷新list界面
问题六:关于sqlist3的模糊查询问题
最初是这样的:接收到输入框里的值了,但是查不到
数据库操作是这样的
后来觉得是sql语句出错了。果真,请参考博文https://blog.csdn.net/shareye1992/article/details/51699763
改成key="%"+key+"%";就可
关于这个滚动,我在网上翻了好一会都没解决,以前用list View的时候好像没怎么遇到这个问题。后来让我翻着翻着就发现一个小细节。之前,我的listView的宽和高都是wrap_content,这导致了后面如果我的数据多的话,listview的高就越来越高,就会把listview下面的布局挤到更下面去看不见。所以我们要给定listView高度,这样当有多项时,就自然出来可以上下滑动了。
待解决的问题:如何建立adapter的activity去复写onActivityResult()那个方法?????????