效果演示
前言:
做了一个简易的学生管理项目,来分享给大家。
有点 Java开发的三层开发思想
实体类pojo,适配器Adapter,还有Dao层
声明:
1.SQLite学习请自行搜索。2.本博客只演示这个简易项目。
项目结构图:
先看一下数据库层,可以看到
在database包下有一个DBhelper类
这个类相信大家很熟悉吧。
public class DBhelper extends SQLiteOpenHelper { // 数据库名 private static final String DB_NAME = "stus_manage.db"; // 数据库版本 private static final Integer version = 1; public DBhelper(Context context) { super(context, DB_NAME, null, version); } @Override public void onCreate(SQLiteDatabase sqLiteDatabase) { // 创建表 String sql = "create table stus(stu_id varchar(20) primary key, stu_name varchar(50) not null)"; try { sqLiteDatabase.execSQL(sql); Log.d("数据库初始化提示:", "数据库初始化成功"); }catch (SQLException e){ Log.d("数据库初始化提示:", "数据库初始化失败"); e.printStackTrace(); } } @Override public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) { } }
注意,这里DBhelper继承自SQLiteOpenHelper类
这里放的东西类似于Java中的JDBC连接数据库放的参数。
可以看到定义了一个常量DB_NAME值为stus_manage.db顾名思义就是数据库名字了。
接下来还有个常量VERSION值为1,这里是数据库版本号,随便设置的。
然后重写了两个方法
onCreate(SQLiteDatabase db) : 当数据库被首次创建时执行该方法,一般将创建表等初始化操作在该方法中执行。
onUpgrade(SQLiteDatabse dv, int oldVersion,int new Version):当打开数据库时传入的版本号与当前的版本号不同时会调用该方法 。在onCreate中创建了一个表stus有连两个字段stu_id和stu_name
使用sqLiteDatabase.execSQL(sql);来执行SQL语句,语法类似于MySQL
onUpgrade用来更新数据库版本号,这里用不到,不再赘述。
既然是学生管理系统,那么就需要实体类学生。
在pojo包下有一个Stu实体类
public class Stu { private String id; private String name; public String getId() { return id; } public void setId(String id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Stu(String id, String name) { this.id = id; this.name = name; } }
实现定义两个字段id,name和实现Stu的get,set及构造函数。
接下来是不是需要Dao层,实现业务。及管理操作。
在dao包下有一个StuDao和一个StuDaoImpl
StuDao提供接口
public interface StuDao { public boolean save(Stu stu); public List<Stu> findByName(String name); public boolean delete(String id); public boolean update(Stu stu); }StuDaoImpl接口的业务实现类。
public class StuDaoImpl implements StuDao { private DBhelper dBhelper; private SQLiteDatabase database; private Cursor cursor; public StuDaoImpl(Context context) { super(); dBhelper = new DBhelper(context); database = dBhelper.getReadableDatabase(); } @Override public boolean save(Stu stu) { String sql = "insert into stus(stu_id,stu_name) values(?,?)"; try { database.execSQL(sql, new String[]{stu.getId(), stu.getName()}); Log.d("新增学生提示:", "新增成功"); return true; } catch (SQLException e) { Log.d("新增学生提示:", "新增失败"); e.printStackTrace(); } return false; } @Override public boolean update(Stu stu) { String sql = "UPDATE stus SET stu_name = ? WHERE stu_id = ?"; try { database.execSQL(sql, new String[]{stu.getName(),stu.getId()}); Log.d("修改学生提示:", "修改成功"); return true; } catch (SQLException e) { Log.d("修改学生提示:", "修改失败"); e.printStackTrace(); } return false; } @Override public List<Stu> findByName(String name) { String sql = "select stu_id,stu_name from stus where stu_name like '%"+name+"%'"; List<Stu> stuList = new ArrayList<Stu>(); try { cursor = database.rawQuery(sql,null); while (cursor.moveToNext()){ Stu stu = new Stu(cursor.getString(0),cursor.getString(1)); stuList.add(stu); } } catch (SQLException e) { e.printStackTrace(); } return stuList; } @Override public boolean delete(String id) { String sql = "delete from stus where stu_id = ?"; try { database.execSQL(sql, new String[]{id}); Log.d("删除学生提示:", id+"删除成功"); return true; } catch (SQLException e) { Log.d("删除学生提示:", id+"删除失败"); e.printStackTrace(); } return false; } }
有4个方法,分别对应增删改查。
注意,所有的执行SQL都需要try-catch一下
try-catch快捷键-CTRL+ALT+T
着重说一下模糊查询,like %参数%
"select stu_id,stu_name from stus where stu_name like '%"+name+"%'"
可以看到使用了拼接字符串,而没用占位符,因为这里%?%它需要用''单引号圈起来
业务层就这样,接下来是主活动,实现效果如下图
主活动里主要实现了增删查,点击ListView的项后进入修改页面
在sqlitetext包下有一个MainActivity
public class MainActivity extends AppCompatActivity { StuDao stuDao; List<Stu> stuList = new ArrayList<Stu>(); ListView listView = null; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initDB(); initListView(); } // 初始化ListView,查询所有学生,可用作刷新 void initListView() { listView = (ListView) findViewById(R.id.show_stus); // 第一次加载肯定TM的是加载所有学生,所以这里使用下列代码拿到所有学生的集合 stuList = stuDao.findByName(""); // 给ListView添加适配器 listView.setAdapter(new StuListViewAdapter(this, stuList)); // ListView的项的单击事件 listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { Stu stu = stuList.get(position); Intent intent = new Intent(MainActivity.this,UpdateStuActivity.class); intent.putExtra("id",stu.getId()); intent.putExtra("name",stu.getName()); startActivity(intent); } }); } // 初始化数据库 void initDB() { stuDao = new StuDaoImpl(this); } public void AddStuBtn(View view) { if (stuDao.save(new Stu(((EditText) findViewById(R.id.student_id)).getText().toString(), ((EditText) findViewById(R.id.student_name)).getText().toString()))) { Toast.makeText(MainActivity.this, "新增成功", Toast.LENGTH_SHORT).show(); } else { Toast.makeText(MainActivity.this, "新增失败", Toast.LENGTH_SHORT).show(); } // 清空输入框 ((EditText) findViewById(R.id.student_id)).setText(""); ((EditText) findViewById(R.id.student_name)).setText(""); initListView(); } public void SelectStuBtn(View view) { // 拿到输入框的值 String select_name = ((EditText)findViewById(R.id.select_student_name)).getText().toString(); // 根据输入的值模糊查询 stuList = stuDao.findByName(select_name); // 填充适配器 listView.setAdapter(new StuListViewAdapter(this,stuList)); } public void DeleteStuBtn(View view) { if (stuDao.delete(((EditText) findViewById(R.id.delete_student_id)).getText().toString())) { Toast.makeText(MainActivity.this, "删除成功", Toast.LENGTH_SHORT).show(); } else { Toast.makeText(MainActivity.this, "删除失败", Toast.LENGTH_SHORT).show(); } ((EditText) findViewById(R.id.delete_student_id)).setText(""); initListView(); } }
布局文件activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <EditText android:hint="学号" android:id="@+id/student_id" android:layout_width="match_parent" android:layout_height="wrap_content" /> <LinearLayout android:orientation="horizontal" android:layout_width="match_parent" android:layout_height="wrap_content"> <EditText android:hint="姓名" android:id="@+id/student_name" android:layout_weight="1" android:layout_width="0dp" android:layout_height="wrap_content" /> <Button android:onClick="AddStuBtn" android:text="新增" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </LinearLayout> <LinearLayout android:orientation="horizontal" android:layout_width="match_parent" android:layout_height="wrap_content"> <EditText android:hint="请输入要查询的学生的姓名或关键字" android:id="@+id/select_student_name" android:layout_weight="1" android:layout_width="0dp" android:layout_height="wrap_content" /> <Button android:onClick="SelectStuBtn" android:text="查询" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </LinearLayout> <LinearLayout android:orientation="horizontal" android:layout_width="match_parent" android:layout_height="wrap_content"> <EditText android:hint="请输入要删除的学生的学号" android:id="@+id/delete_student_id" android:layout_weight="1" android:layout_width="0dp" android:layout_height="wrap_content" /> <Button android:onClick="DeleteStuBtn" android:text="删除" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </LinearLayout> <ListView android:id="@+id/show_stus" android:layout_width="match_parent" android:layout_height="match_parent"/> </LinearLayout>
简单的LinearLayout
可以看到,查询和新增和删除操作后都重新填充了ListView
initListView();
重写了OnItemClickListener
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { Stu stu = stuList.get(position); Intent intent = new Intent(MainActivity.this,UpdateStuActivity.class); intent.putExtra("id",stu.getId()); intent.putExtra("name",stu.getName()); startActivity(intent); } });
用于跳转到修改学生页,并传入了学生id和学生name
这里我偷懒直接传了id和name
正确做法是传入id,根据id拿到(select到)stu对象,再getid和getname
接下来是修改页效果
在sqlitetext包下有一个UpdateStuActivity
public class UpdateStuActivity extends AppCompatActivity { StuDao stuDao; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_update_stu); initView(); stuDao = new StuDaoImpl(this); } public void initView() { // 拿到MainActivity传过来的值 String id = getIntent().getStringExtra("id"); String name = getIntent().getStringExtra("name"); // 给视图赋值 EditText editText = (EditText) findViewById(R.id.update_student_id); editText.setText(id); // 设置id不可编辑 editText.setFocusable(false); ((EditText) findViewById(R.id.update_student_name)).setText(name); } public void UpdateStuBtn(View view) { Stu stu = new Stu(((EditText) findViewById(R.id.update_student_id)).getText().toString(), ((EditText) findViewById(R.id.update_student_name)).getText().toString()); if (stuDao.update(stu)) { Toast.makeText(UpdateStuActivity.this, "修改成功", Toast.LENGTH_SHORT).show(); } else { Toast.makeText(UpdateStuActivity.this, "修改失败", Toast.LENGTH_SHORT).show(); } finish(); } }布局文件activity_update_stu.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="要修改的学生学号:" /> <EditText android:id="@+id/update_student_id" android:layout_width="match_parent" android:layout_height="wrap_content" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="要修改的学生姓名:" /> <EditText android:id="@+id/update_student_name" android:layout_width="match_parent" android:layout_height="wrap_content" /> <Button android:onClick="UpdateStuBtn" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="提交" /> </LinearLayout>
可以看到,设置id为不可编辑
editText.setFocusable(false);
并且在修改后直接finish了
最后再来看一下ListView的适配器
在adapter包下StuListViewAdapter
public class StuListViewAdapter extends BaseAdapter { // private Context context; private List<Stu> stuList; private LayoutInflater layoutInflater; public StuListViewAdapter(Context context, List<Stu> stuList) { super(); // this.context = context; this.stuList = stuList; layoutInflater = LayoutInflater.from(context); } @Override public int getCount() { if(this.stuList.size()==0){ return 1; } return this.stuList.size(); } @Override public Object getItem(int i) { return this.stuList.get(i); } @Override public long getItemId(int i) { return 0; } @Override public View getView(int i, View view, ViewGroup viewGroup) { if(stuList.size()>0){ // 获取当前项的实例 Stu stu = stuList.get(i); view = layoutInflater.inflate(R.layout.stu_list_view_item,null); // 给控件赋值 ((TextView)view.findViewById(R.id.show_student_id)).setText(stu.getId()); ((TextView)view.findViewById(R.id.show_student_name)).setText(stu.getName()); }else { view = layoutInflater.inflate(R.layout.nothing_to_show,null); } return view; } }
这里讲一下getCount()
@Override public int getCount() { if(this.stuList.size()==0){ return 1; } return this.stuList.size(); }
这里本来直接返回size即可
但是这里做了个判断,如果没查到值怎么办?是吧,要给用户一个提示吧
所以给返回一行并填充一个提示没查到的布局。
然后再讲一下getView()
@Override public View getView(int i, View view, ViewGroup viewGroup) { if(stuList.size()>0){ // 获取当前项的实例 Stu stu = stuList.get(i); view = layoutInflater.inflate(R.layout.stu_list_view_item,null); // 给控件赋值 ((TextView)view.findViewById(R.id.show_student_id)).setText(stu.getId()); ((TextView)view.findViewById(R.id.show_student_name)).setText(stu.getName()); }else { view = layoutInflater.inflate(R.layout.nothing_to_show,null); } return view; }
获取查询到的集合的size()如果有值就填充正常的布局,没有值就填充nothing_to_show
如果在getCount里没有返回1那么就算你填充了nothing_to_show也显示不出来
因为你给ListView的Item为0,getCount返回1是给ListView先放一个item
然后在getView拿到视图。
nothing_to_show效果展示
能查到值的布局-------stu_list_view_item.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="horizontal" android:layout_width="match_parent" android:layout_height="wrap_content"> <ImageView android:src="@drawable/tbag_icon" android:layout_width="50dp" android:layout_height="50dp" /> <LinearLayout android:layout_gravity="center" android:orientation="vertical" android:layout_weight="1" android:layout_width="0dp" android:layout_height="wrap_content"> <TextView android:id="@+id/show_student_id" android:textColor="@color/colorAccent" android:layout_width="match_parent" android:layout_height="wrap_content" /> <TextView android:id="@+id/show_student_name" android:textColor="@color/colorPrimary" android:layout_width="match_parent" android:layout_height="wrap_content" /> </LinearLayout> </LinearLayout>没查到值的布局-------nothing_to_show.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:gravity="center" android:text="哎呀,什么都没找到呀!" android:layout_width="match_parent" android:layout_height="wrap_content" /> </LinearLayout>
整个项目到此结束
需要源码自行
链接:https://pan.baidu.com/s/1kxJ5Cd9d2sl-uY8pZ1zFCA 密码:smc5
解压密码:csdn