经过了一上午的折腾,大致了解了如何开发一个疫情每日登录APP,首先我们需要使用数据库存储数据,Android Studio自带了SQLite作为数据库,可以通过DataBaseHelper来实现,但毕竟还是有些繁琐。今天主要学习了Google的数据库框架Room框架,Room框架由三部分组成,Entity(实体)、Dao(操作接口层)、DataBase(继承了RoomDatabase的自定义类),下面是一个小demo:
首先是Entity
package com.michael.roomdemo.database;
import androidx.room.ColumnInfo;
import androidx.room.Entity;
import androidx.room.Ignore;
import androidx.room.PrimaryKey;
/**
* Model
* */
@Entity(tableName = "student")
public class Student
{
@PrimaryKey(autoGenerate = true)
@ColumnInfo(name = "id", typeAffinity = ColumnInfo.INTEGER)
public int id;
@ColumnInfo(name = "name", typeAffinity = ColumnInfo.TEXT)
public String name;
@ColumnInfo(name = "age", typeAffinity = ColumnInfo.TEXT)
public String age;
/**
* Room会使用这个构造器来存储数据,也就是当你从表中得到Student对象时候,Room会使用这个构造器
* */
public Student(int id, String name, String age)
{
this.id = id;
this.name = name;
this.age = age;
}
/**
* 由于Room只能识别和使用一个构造器,如果希望定义多个构造器,你可以使用Ignore标签,让Room忽略这个构造器
* 同样,@Ignore标签还可用于字段,使用@Ignore标签标记过的字段,Room不会持久化该字段的数据
* */
@Ignore
public Student(String name, String age)
{
this.name = name;
this.age = age;
}
}
- 这里需要使用
@Entity来注解该类 - 至少要有一个主键
@PrimaryKey
然后是Dao层:
package com.michael.roomdemo.database;
import java.util.List;
import androidx.room.Dao;
import androidx.room.Delete;
import androidx.room.Insert;
import androidx.room.Query;
import androidx.room.Update;
/**
* DAO
*
* 对数据库表的增删改查
*
* */
@Dao
public interface StudentDao
{
@Insert
void insertStudent(Student student);
@Delete
void deleteStudent(Student student);
@Update
void updateStudent(Student student);
@Query("SELECT * FROM student")
List<Student> getStudentList();
@Query("SELECT * FROM student WHERE id = :id")
Student getStudentById(int id);
}
- 使用
@Dao注解该接口 @Insert,@Update,@Delete,@Query代表我们常用的插入、更新、删除、查询数据库操作@Insert,@Update,@Delete可以传入多种不同的参数。@Query也可以返回多种不同的类型。
然后是我们的自定义数据库:
package com.michael.roomdemo.database;
import android.content.Context;
import androidx.room.Database;
import androidx.room.Room;
import androidx.room.RoomDatabase;
@Database(entities = {Student.class}, version = 1,exportSchema = false)
public abstract class MyDatabase extends RoomDatabase
{
private static final String DATABASE_NAME = "my_db";
private static MyDatabase databaseInstance;
public static synchronized MyDatabase getInstance(Context context)
{
if(databaseInstance == null)
{
databaseInstance = Room
.databaseBuilder(context.getApplicationContext(), MyDatabase.class, DATABASE_NAME)
.build();
}
return databaseInstance;
}
public abstract StudentDao studentDao();
}
在定义好这些基本操作后,我们来看看界面:

界面比较简陋,主要是点击添加student后就弹出添加的activity
然后长按列表元素后会触发事件,有更新和删除选项,依次弹出相应的activity
前台代码就不放了,主要放一下后台:
package com.michael.roomdemo;
import android.content.DialogInterface;
import android.os.AsyncTask;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.View;
import android.widget.AdapterView;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.Toast;
import com.michael.roomdemo.database.MyDatabase;
import com.michael.roomdemo.database.Student;
import java.util.ArrayList;
import java.util.List;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
public class MainActivity extends AppCompatActivity
{
private MyDatabase myDatabase;
private List<Student> studentList;
private StudentAdapter studentAdapter;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findViewById(R.id.btnInsertStudent).setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v)
{
openAddStudentDialog();
}
});
ListView lvStudent = findViewById(R.id.lvStudent);
studentList = new ArrayList<>();
studentAdapter = new StudentAdapter(MainActivity.this, studentList);
lvStudent.setAdapter(studentAdapter);
lvStudent.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener()
{
@Override
public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id)
{
updateOrDeleteDialog(studentList.get(position));
return false;
}
});
myDatabase = MyDatabase.getInstance(this);
new QueryStudentTask().execute();
}
//弹出选择是删除还是更新的选择框
private void updateOrDeleteDialog(final Student student)
{
final String[] options = new String[]{"更新", "删除"};
new AlertDialog.Builder(MainActivity.this)
.setTitle("")
.setItems(options, new DialogInterface.OnClickListener()
{
@Override
public void onClick(DialogInterface dialog, int which)
{
if(which == 0)
{
openUpdateStudentDialog(student);
}
else if(which == 1)
{
new DeleteStudentTask(student).execute();
}
}
}).show();
}
//弹出添加学生的Dialog
private void openAddStudentDialog()
{
View customView = this.getLayoutInflater().inflate(R.layout.dialog_layout_student, null);
final EditText etName = customView.findViewById(R.id.etName);
final EditText etAge = customView.findViewById(R.id.etAge);
final AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
AlertDialog dialog = builder.create();
dialog.setTitle("Add Student");
dialog.setButton(DialogInterface.BUTTON_POSITIVE, "OK", new DialogInterface.OnClickListener()
{
@Override
public void onClick(DialogInterface dialog, int which)
{
if (TextUtils.isEmpty(etName.getText().toString()) || TextUtils.isEmpty(etAge.getText().toString()))
{
Toast.makeText(MainActivity.this, "输入不能为空", Toast.LENGTH_SHORT).show();
} else
{
new InsertStudentTask(etName.getText().toString(), etAge.getText().toString()).execute();
}
}
});
dialog.setButton(DialogInterface.BUTTON_NEGATIVE, "CANCEL", new DialogInterface.OnClickListener()
{
@Override
public void onClick(DialogInterface dialog, int which)
{
dialog.dismiss();
}
});
dialog.setView(customView);
dialog.show();
}
//弹出更改学生信息的dialog
private void openUpdateStudentDialog(final Student student)
{
if (student == null)
{
return;
}
View customView = this.getLayoutInflater().inflate(R.layout.dialog_layout_student, null);
final EditText etName = customView.findViewById(R.id.etName);
final EditText etAge = customView.findViewById(R.id.etAge);
etName.setText(student.name);
etAge.setText(student.age);
final AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
AlertDialog dialog = builder.create();
dialog.setTitle("Update Student");
dialog.setButton(DialogInterface.BUTTON_POSITIVE, "OK", new DialogInterface.OnClickListener()
{
@Override
public void onClick(DialogInterface dialog, int which)
{
if (TextUtils.isEmpty(etName.getText().toString()) || TextUtils.isEmpty(etAge.getText().toString()))
{
Toast.makeText(MainActivity.this, "输入不能为空", Toast.LENGTH_SHORT).show();
} else
{
new UpdateStudentTask(student.id, etName.getText().toString(), etAge.getText().toString()).execute();
}
}
});
dialog.setButton(DialogInterface.BUTTON_NEGATIVE, "CANCEL", new DialogInterface.OnClickListener()
{
@Override
public void onClick(DialogInterface dialog, int which)
{
dialog.dismiss();
}
});
dialog.setView(customView);
dialog.show();
}
//插入的异步操作
private class InsertStudentTask extends AsyncTask<Void, Void, Void>
{
String name;
String age;
public InsertStudentTask(final String name, final String age)
{
this.name = name;
this.age = age;
}
@Override
protected Void doInBackground(Void... arg0)
{
myDatabase.studentDao().insertStudent(new Student(name, age));
studentList.clear();
studentList.addAll(myDatabase.studentDao().getStudentList());
return null;
}
@Override
protected void onPostExecute(Void result)
{
super.onPostExecute(result);
studentAdapter.notifyDataSetChanged();
}
}
//更新的异步操作
private class UpdateStudentTask extends AsyncTask<Void, Void, Void>
{
int id;
String name;
String age;
public UpdateStudentTask(final int id, final String name, final String age)
{
this.id = id;
this.name = name;
this.age = age;
}
@Override
protected Void doInBackground(Void... arg0)
{
myDatabase.studentDao().updateStudent(new Student(id, name, age));
studentList.clear();
studentList.addAll(myDatabase.studentDao().getStudentList());
return null;
}
@Override
protected void onPostExecute(Void result)
{
super.onPostExecute(result);
studentAdapter.notifyDataSetChanged();
}
}
//删除的异步操作
private class DeleteStudentTask extends AsyncTask<Void, Void, Void>
{
Student student;
public DeleteStudentTask(Student student)
{
this.student = student;
}
@Override
protected Void doInBackground(Void... arg0)
{
myDatabase.studentDao().deleteStudent(student);
studentList.clear();
studentList.addAll(myDatabase.studentDao().getStudentList());
return null;
}
@Override
protected void onPostExecute(Void result)
{
super.onPostExecute(result);
studentAdapter.notifyDataSetChanged();
}
}
//异步显示全部学生信息
private class QueryStudentTask extends AsyncTask<Void, Void, Void>
{
public QueryStudentTask()
{
}
@Override
protected Void doInBackground(Void... arg0)
{
studentList.clear();
studentList.addAll(myDatabase.studentDao().getStudentList());
return null;
}
@Override
protected void onPostExecute(Void result)
{
super.onPostExecute(result);
studentAdapter.notifyDataSetChanged();
}
}
}
这是主要后台,可以看注释
适应器代码:
package com.michael.roomdemo;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;
import com.michael.roomdemo.database.Student;
import java.util.List;
public class StudentAdapter extends BaseAdapter
{
private List<Student> data;
private LayoutInflater layoutInflater;
public StudentAdapter(Context context, List<Student> data)
{
this.data = data;
layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
class ViewHolder
{
TextView tvId;
TextView tvName;
TextView tvAge;
}
@Override
public View getView(int position, View convertView, ViewGroup parent)
{
ViewHolder viewHolder;
if (convertView == null)
{
convertView = layoutInflater.inflate(R.layout.list_item_student, null);
viewHolder = new ViewHolder();
viewHolder.tvId = convertView.findViewById(R.id.tvId);
viewHolder.tvName = convertView.findViewById(R.id.tvName);
viewHolder.tvAge = convertView.findViewById(R.id.tvAge);
convertView.setTag(viewHolder);
} else
{
viewHolder = (ViewHolder) convertView.getTag();
}
viewHolder.tvId.setText(String.valueOf(data.get(position).id));
viewHolder.tvName.setText(data.get(position).name);
viewHolder.tvAge.setText(data.get(position).age);
return convertView;
}
@Override
public int getCount()
{
if (data == null)
{
return 0;
}
return data.size();
}
@Override
public Student getItem(int position)
{
return data.get(position);
}
@Override
public long getItemId(int position)
{
return position;
}
}
来源:https://www.cnblogs.com/wushenjiang/p/12296343.html