暑假作业--密码备忘录
项目介绍
app功能:一个手机用户拥有一个账户本,能够将平时自己容易的忘记的账户记录下来,每次重启app时数据不会清零,不需要担心数据丢失,只要打开app,便可获取到自己的账户本。
效果图
实现的效果图,如下:
以下界面分别为进入app界面
提交账户内容界面
账户列表界面
删除账户信息
实现的工程目录如下
实现的具体过程:
a.布局代码:
(1)登录界面图:activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:orientation="vertical"
android:layout_height="match_parent"
tools:context=".MainActivity">
<RelativeLayout
android:background="@color/colorPrimary"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="40dp">
<TextView
android:layout_centerInParent="true"
android:text="首页"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<Button
android:layout_marginRight="10dp"
android:layout_centerVertical="true"
android:id="@+id/bt_add"
android:background="@color/colorAccent"
android:layout_alignParentRight="true"
android:text="添加"
android:layout_width="50dp"
android:layout_height="30dp" />
</RelativeLayout>
<android.support.v7.widget.RecyclerView
android:id="@+id/recycler"
android:layout_width="match_parent"
android:layout_height="match_parent"></android.support.v7.widget.RecyclerView>
</LinearLayout>
(2)注册界面:act_login.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"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="71dp"
android:background="@color/colorPrimary"
android:gravity="center"
android:text="登录" />
<EditText
android:id="@+id/et"
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_margin="50dp"
android:background="@drawable/shap_circle"
android:gravity="center_vertical"
android:hint="输入0000打开app"
android:inputType="textPassword"
android:paddingLeft="10dp" />
<Button
android:id="@+id/Button"
android:layout_width="100dp"
android:layout_height="40dp"
android:layout_gravity="center_horizontal"
android:layout_marginTop="100dp"
android:background="@color/colorPrimary"
android:text="登录" />
</LinearLayout>
(3)添加账户页面:act_add.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:background="@color/colorPrimary"
android:gravity="center"
android:text="添加"
android:layout_width="match_parent"
android:layout_height="40dp" />
<EditText
android:id="@+id/EditText"
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_marginTop="10dp"
android:hint="请输入平台" />
<EditText
android:id="@+id/EditText1"
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_marginTop="10dp"
android:hint="请输入账号" />
<EditText
android:id="@+id/EditText2"
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_marginTop="10dp"
android:hint="请输入密码" />
<Button
android:id="@+id/Button"
android:layout_width="100dp"
android:layout_height="50dp"
android:layout_gravity="center_horizontal"
android:layout_marginTop="20dp"
android:background="@color/colorPrimary"
android:text="添加" />
</LinearLayout>
(4)账户具体信息页面: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="wrap_content"
android:orientation="vertical"
android:padding="10dp">
<TextView
android:id="@+id/tv_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="标题" />
<TextView
android:id="@+id/tv_account"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:text="账号" />
<TextView
android:id="@+id/tv_pwd"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:text="密码" />
<TextView
android:id="@+id/tv_del"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="right"
android:text="删除"
android:textColor="@color/colorAccent" />
</LinearLayout>
b.实现代码:
(1)登陆界面:Login——主要是实现跳转页面的功能,输入0000直接打开app,因为这是一个记录密码的app,用户都需要用app来记录密码了,如果还让他记录app的登陆密码就太过分了。
import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.text.TextUtils;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
public class Login extends AppCompatActivity implements View.OnClickListener {
private EditText et;
private Button Button;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.act_login);
initView();
}
private void initView() {
et = (EditText) findViewById(R.id.et);
Button = (Button) findViewById(R.id.Button);
Button.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.Button:
submit();
break;
}
}
private void submit() {
String etString = et.getText().toString().trim();
if (TextUtils.isEmpty(etString)) {
Toast.makeText(this, "输入0000打开app", Toast.LENGTH_SHORT).show();
return;
}
if ("0000".equals(etString)){
Intent intent =new Intent(Login.this,MainActivity.class);
startActivity(intent);
finish();
}else {
Toast.makeText(this, "您输错了", Toast.LENGTH_SHORT).show();
}
}
}
(2)建立一个Model类来保存数据,主要含有用户名,密码和相关信息。
public class Model {
public String id;
public String title;
public String account;
public String pwd;
public Model(String id, String title, String account, String pwd) {
this.id = id;
this.title = title;
this.account = account;
this.pwd = pwd;
}
}
(3)建立完后,我们要自定义一个适配器BaseAdapter去加载数据到列表界面中:
import android.support.annotation.Nullable;
import com.chad.library.adapter.base.BaseQuickAdapter;
import com.chad.library.adapter.base.BaseViewHolder;
import java.util.List;
//RecyclerView 通用适配 BaseQuickAdapter 参考网址:https://blog.csdn.net/u011622280/article/details/69229930
public class BaseAdapter<T> extends BaseQuickAdapter<T,BaseViewHolder> {
private final ConVert conVert;
public BaseAdapter(int layoutResId, @Nullable List data, ConVert<T> conVert) {
super(layoutResId, data);
this.conVert =conVert;
}
@Override
protected void convert(BaseViewHolder helper, T item) {
conVert.convert(helper,item);
}
public interface ConVert<T>{
void convert(BaseViewHolder helper, T t);
}
}
(4)添加账户界面:Add——主要实现获取到用户输入的信息,然后保存到数据库中。
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.text.TextUtils;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
public class Add extends AppCompatActivity implements View.OnClickListener {
private EditText et_title;
private EditText et_account;
private EditText et_pwd;
private Button bt_add;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.act_add);
initView();
}
private void initView() {
et_title = (EditText) findViewById(R.id.EditText);
et_account = (EditText) findViewById(R.id.EditText1);
et_pwd = (EditText) findViewById(R.id.EditText2);
bt_add = (Button) findViewById(R.id.Button);
bt_add.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.Button:
submit();
break;
}
}
private void submit() {
// validate
String title = et_title.getText().toString().trim();
if (TextUtils.isEmpty(title)) {
Toast.makeText(this, "请输入平台", Toast.LENGTH_SHORT).show();
return;
}
String account = et_account.getText().toString().trim();
if (TextUtils.isEmpty(account)) {
Toast.makeText(this, "请输入账号", Toast.LENGTH_SHORT).show();
return;
}
String pwd = et_pwd.getText().toString().trim();
if (TextUtils.isEmpty(pwd)) {
Toast.makeText(this, "请输入密码", Toast.LENGTH_SHORT).show();
return;
}
new SqlDao(this).add(title,account,pwd);
finish();
}
}
(5)添加完信息后,我们应该将在列表界面中更新出相关数据出来,那么我们去更新数据,即数据库中获取数据,那么这里要去搜索与用户相对应的信息,而这里我们直接去搜索表名为用户名的表格即可,因为我们之前已经设置了表名为用户。以及删除列表项的功能。
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;
//数据库帮助类
public class DBHelper extends SQLiteOpenHelper {
private static final String TAG = "TestSQLite";
public static final int VERSION = 1;
//必须要有构造函数
public DBHelper(Context context, String name, SQLiteDatabase.CursorFactory factory,
int version) {
super(context, name, factory, version);
}
// 当第一次创建数据库的时候,调用该方法
public void onCreate(SQLiteDatabase db) {
String sql = "create table a_table(id INTEGER primary key autoincrement,title varchar(20),account varchar(85),pwd varchar(85))";
//输出创建数据库的日志信息
Log.i(TAG, "create Database------------->");
//execSQL函数用于执行SQL语句
db.execSQL(sql);
}
//当更新数据库的时候执行该方法
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
//输出更新数据库的日志信息
Log.i(TAG, "update Database------------->");
}
}
(6)打开关闭数据库:Sqldao——获取到传递过来的信息,并加载到布局中即可。
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.List;
public class SqlDao {
private Context context;
private final DBHelper dbHelper;
public SqlDao(Context context){
this.context=context;
dbHelper = new DBHelper(context,"a_db",null,1);
}
public void add(String title,String account,String pwd){
SQLiteDatabase db =dbHelper.getWritableDatabase();
//生成ContentValues对象 //key:列名,value:想插入的值
ContentValues cv = new ContentValues();
//往ContentValues对象存放数据
cv.put("title", title);
cv.put("account", account);
cv.put("pwd", pwd);
//调用insert方法,将数据插入数据库
db.insert("a_table", null, cv);
Toast.makeText(context,"添加成功", Toast.LENGTH_LONG).show();
//关闭数据库
db.close();
}
//删除关键词
public void delete(String id){
//得到一个可写的数据库
SQLiteDatabase db =dbHelper.getWritableDatabase();
db.delete("a_table","id = ?",new String[]{id});
Toast.makeText(context,"删除成功",Toast.LENGTH_LONG).show();
//关闭数据库
db.close();
}
public List<Model> getData(){
List<Model> list=new ArrayList<>();
//得到一个可写的数据库
SQLiteDatabase db =dbHelper.getReadableDatabase();
//参数1:表名
//参数2:要想显示的列
//参数3:where子句
//参数4:where子句对应的条件值
//参数5:分组方式
//参数6:having条件
//参数7:排序方式
Cursor cursor = db.query("a_table", new String[]{"id","title","account","pwd"}, "", null, null, null, null);
while(cursor.moveToNext()){
String id = cursor.getString(cursor.getColumnIndex("id"));
String title = cursor.getString(cursor.getColumnIndex("title"));
String account = cursor.getString(cursor.getColumnIndex("account"));
String pwd = cursor.getString(cursor.getColumnIndex("pwd"));
list.add(new Model(id,title,account,pwd));
}
//关闭数据库
db.close();
return list;
}
}
(7)主界面:MainActivity
import android.content.DialogInterface;
import android.content.Intent;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.widget.Button;
import com.chad.library.adapter.base.BaseViewHolder;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private RecyclerView recycler;
private Button bt_add;
private List<Model> list=new ArrayList<>();
private BaseAdapter<Model> adapter;
private SqlDao sqlDao;
@Override
protected void onCreate(Bundle savedInstanceState) {
sqlDao = new SqlDao(this);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
}
private void initView() {
recycler = (RecyclerView) findViewById(R.id.recycler);
bt_add = (Button) findViewById(R.id.bt_add);
bt_add.setOnClickListener(this);
recycler.setLayoutManager(new LinearLayoutManager(this));
adapter = new BaseAdapter<>(R.layout.item, list, new BaseAdapter.ConVert<Model>() {
@Override
public void convert(BaseViewHolder helper, final Model model) {
helper.setText(R.id.tv_title,model.title);
helper.setText(R.id.tv_account,model.account);
helper.setText(R.id.tv_pwd,model.pwd);
helper.getView(R.id.tv_del).setOnClickListener(new View.OnClickListener() {
private AlertDialog dialog;
@Override
public void onClick(View view) {
AlertDialog.Builder builder=new AlertDialog.Builder(MainActivity.this);
builder.setMessage("确认删除吗?");
builder.setNegativeButton("确认", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
sqlDao.delete(model.id);
list.remove(model);
adapter.notifyDataSetChanged();
dialog.dismiss();
}
}); builder.setPositiveButton("取消", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
dialog.dismiss();
}
});
dialog = builder.create();
dialog.show();
}
});
}
});
recycler.setAdapter(adapter);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.bt_add:
Intent intent =new Intent(MainActivity.this,Add.class);
startActivity(intent);
break;
}
}
@Override
protected void onResume() {
super.onResume();
list.clear();
getData();
}
public void getData(){
DBHelper dbHelper = new DBHelper(this, "a_db", null, 1);
//得到一个可写的数据库
SQLiteDatabase db =dbHelper.getReadableDatabase();
//参数1:表名
//参数2:要想显示的列
//参数3:where子句
//参数4:where子句对应的条件值
//参数5:分组方式
//参数6:having条件
//参数7:排序方式
Cursor cursor = db.query("a_table", new String[]{"id","title","account","pwd"}, "", null, null, null, null);
while(cursor.moveToNext()){
String id = cursor.getString(cursor.getColumnIndex("id"));
String title = cursor.getString(cursor.getColumnIndex("title"));
String account = cursor.getString(cursor.getColumnIndex("account"));
String pwd = cursor.getString(cursor.getColumnIndex("pwd"));
list.add(new Model(id,title,account,pwd));
}
adapter.notifyDataSetChanged();
//关闭数据库
db.close();
}
}
总结
这是第一次尝试使用as自带的数据库,并从数据库中获取数据,在使用数据库过程中,有个问题被困扰了很久,就是关于如何实现为每一个用户建立一个对应的表格,将用户的信息保存到对应的表格中,后来通过设置表名唯一,搜索表名来获取表中数据来实现。还有一个未实现的问题就是登陆注册界面,虽然说我之前在文中说密码备忘录不需要密码登陆,但实际原因还是因为能力不够,希望在以后的学习中能学习到注册登陆密码,最好再学习一下如果客户忘记密码的话要如何更改密码。总的来说,这一次的实现过程中,处处碰壁,主要是对数据库和as的不熟悉导致,希望之后能够加强as的熟悉,这样受限就不会那么多,不过这步还有很漫长,希望能坚持下去!