RecyclerView + SQLite 简易备忘录-----下

最后就是添加备忘录的界面了。同时也是显示备忘录内容的界面。

1.activity_add_info.xml

 

 也是比较简陋的一个页面设计。

顶部是一个自定义的Toolbar,剩下的部分都是ScrollView。这里我是放了一个ImageView,用于将图片插入进来。

整段代码只有ScrollView(滚动条)需要稍稍解释下。指路https://www.runoob.com/w3cnote/android-tutorial-scrollview.html

2.AddInfoActivity

先看整体,再细看。

 

 没个方法是干嘛的都在注释上。

现在按顺序看下方法。

 

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_add_info);
setSupportActionBar(findViewById(R.id.add_toolbar)); //toolbar的实例传入
ActionBar actionBar = getSupportActionBar();
actionBar.setHomeButtonEnabled(true); //设置界面左上角的图标可以点击
actionBar.setDisplayHomeAsUpEnabled(true);// 给左上角加上一个返回的图标
//绑定控件
initView();
//从如果是从主界面点击进入的则显示该条备忘录的内容
recyDisply();
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.add,menu);
return true;
}

上图加载菜单在前面讲过,详细讲下action按钮的点击
@Override
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
switch (item.getItemId()){
case android.R.id.home: //点击了左上角的返回按钮
recyUpdate(); //将内容保存到数据库
this.finish(); //结束该Activity
Intent intent = new Intent(AddInfoActivity.this,MainActivity.class); //启动主页面的Activity
startActivity(intent);
overridePendingTransition(R.anim.add_enter,R.anim.add_exit); //这是随手加的一个activity跳转的动画,不用管它。
case R.id.add_photo: //如果点击了插入图片,则弹出一个Dialog,用户选择是从相册插入还是相机拍照插入
String[] items = {"相机","相册"}; //设置Dialog的子项内容
AlertDialog.Builder builder = new AlertDialog.Builder(this); //创建一个Dialog
builder.setItems(items, new DialogInterface.OnClickListener() { //将子项内容添加进Dialog并设置监听。
@Override
public void onClick(DialogInterface dialogInterface, int i) { //子项的点击事件
switch (i){
case 0: //点击相机,就调用相机点击事件的方法
btnCameraOnClick();
break;
case 1: //点击相册,就调用相册点击事件的方法
btnPhotoOnClick();
break;
}
}
});
builder.create().show();
default:
break;
}
return super.onOptionsItemSelected(item);
}

如果点击相机,就调用btnCameraOnClick()方法。
顺着看看该方法。
//在弹出的Dialog中点击相机后
private void btnCameraOnClick(){
Time time = new Time();
time.setToNow(); //获取当前时间 下方月份+1是因为月份值从0~11,所以取值时加1.
String randtime = time.year + (time.month + 1) + time.monthDay + time.hour + time.minute + time.second + "";
outputImage =new File(getExternalCacheDir(),randtime+".jpg");//创建保存照片的文件,文件名为时间组成的字符串.jpg getExternalCacheDir()用于获取SD卡中专门用于存放当前应用缓存数据的位置。
if (outputImage.exists()) {
outputImage.delete();
}
try {
outputImage.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { //版本判断。如果运行设备的系统版本低于Android7.0就调用UrifromFile()方法将File对象转换为Uri对象。这个Uri对象标识着该照片的本地真实路径。
imageUri =FileProvider.getUriForFile(this, "com.java.memodemo.fileProvider", outputImage); //否则,就调用FileProvider方法将File对象转换成一个封住过的Uri对象。,因为从Android7.0开始,直接使用本地真实路径被认为是不安全的,会抛出异常。
} else { //FileProvider则是一种ContentProvider,它使用了和ContentProvider类似的机制来对数据进行保护。
imageUri =Uri.fromFile(outputImage);
}
Intent intent =new Intent("android.media.action.IMAGE_CAPTURE"); //将该intentaction指定为android.media.action.IMAGE_CAPTURE,意为打开相机
intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri); //告诉相机图片的保存位置
startActivityForResult(intent, 11); //打开相机
/*
startActivityForResult(Intent intent,int RequestCode)用于启动另一个activity并等待其返回的结果.
intent用于启动目标的Activity,此处系统会打开相机程序。
每个activity都可以启动任意的子activity并等待结果,而结果处理函数只有一个--onActivityResult(int requestCode, int resultCode, Intent intent)
因此为了区别请求的事件,android将每个请求设定一个大于等于0int值,这就是requestCode
*/
}

startActivityForResult(intent, 11);这句代码会调用onActivityResult()方法。
来看看该方法。
//在用startActivityForResult时启动该方法。
@Override //选完照片或者拍完照后,接收照片并显示,系统回调。
protected void onActivityResult(int requestCode, int resultCode, Intent data) { //第一个参数是请求码,第二个参数是返回数据时传入的处理结果,第三个参数data是携带者返回数据的intent
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode) { //首先通过requestCode判断数据来源。
case 11: //requestCode11,是来自相机
if (resultCode == RESULT_OK) { //再通过resultCode的值判断处理结果是否成功
disp_path = outputImage.toString();
Glide.with(AddInfoActivity.this).load(disp_path).into(img_preview); //最后通过Glide图片加载库根据图片路径将图片显示到ImageView的控件中。
}
break;
case 22: //requestCode22,是来自相册。然后根据选择照片的路径,显示照片。
Uri imageuri = data.getData(); //获取图片的缩略图路径。
if (imageuri == null) {
return;
}
disp_path = UriUtils.uri2File(imageuri).getPath(); //将缩略图路径转换为真实的图片路径。
Glide.with(AddInfoActivity.this).load(disp_path).into(img_preview);//最后通过Glide图片加载库根据图片路径将图片显示到ImageView的控件中。
break;
default:
break;
}
}
相信大家已经看明白了,现在补上在Dialog后点击相册的事件。
//在弹出的Dialog中点击相册后
private void btnPhotoOnClick(){
Intent intent = new Intent("android.intent.action.GET_CONTENT"); //创建一个打开相册的intent
intent.setType("image/*"); //指定打开页面的类型为图片
startActivityForResult(intent,22); //打开相册
}

startActivityForResult(intent,22);与上面打开相机同理。
最后就是关于数据库的操作了。
//插入到数据库
private void saveToDb(){
Time time = new Time();
time.setToNow();
ContentValues contentValues = new ContentValues();
String title = edit_title.getText().toString();
String content = edit_content.getText().toString();
contentValues.put("titel",title);
contentValues.put("content",content);
contentValues.put("imgpath",disp_path);
contentValues.put("mtime",time.year + "/" + (time.month + 1) + "/" +time.monthDay);
if(edit_title.getText() == null && edit_content.getText() == null && disp_path == null){
return;
}
database.insert("tb_memory",null,contentValues);
}

//从数据库显示
private void recyDisply(){
String myid = getIntent().getStringExtra("_id");
if(myid == null){
return;
}
String mysql = "select * from tb_memory where _id ="+myid;
MemoBean memoBean = null;
Cursor cursor = database.rawQuery(mysql,null);
while (cursor.moveToNext()){
String mytitle = cursor.getString(cursor.getColumnIndex("titel"));
String mycontent = cursor.getString(cursor.getColumnIndex("content"));
String mytime = cursor.getString(cursor.getColumnIndex("mtime"));
String myimgpath = cursor.getString(cursor.getColumnIndex("imgpath"));
memoBean = new MemoBean(myid,mytitle,mycontent,myimgpath,mytime);
}
edit_title.setText(memoBean.getTitle());
edit_content.setText(memoBean.getContent());
if(memoBean.getImgpath() != null){
Glide.with(AddInfoActivity.this).load(memoBean.getImgpath()).into(img_preview);
}
}

   //更新数据库
private void recyUpdate(){
String myid = getIntent().getStringExtra("_id");
if(myid == null){
saveToDb();
return;
}
Time time = new Time();
time.setToNow();
ContentValues contentValues = new ContentValues();
String title = edit_title.getText().toString();
String content = edit_content.getText().toString();
contentValues.put("titel",title);
contentValues.put("content",content);
if(disp_path == null){
String mysql = "select * from tb_memory where _id ="+myid;
String myimgpath = null;
Cursor cursor = database.rawQuery(mysql,null);
while (cursor.moveToNext()){
myimgpath = cursor.getString(cursor.getColumnIndex("imgpath"));
}
contentValues.put("imgpath",myimgpath);
}else {
contentValues.put("imgpath",disp_path);
}
contentValues.put("mtime",time.year + "/" + (time.month + 1) + "/" +time.monthDay);
if(edit_title.getText() == null && edit_content.getText() == null && disp_path == null){
return;
}
database.update("tb_memory",contentValues,"_id = ?",new String[]{myid});
Toast.makeText(AddInfoActivity.this,"修改成功",Toast.LENGTH_LONG).show();
}
}
从数据库删除的方法在RecyclerView的适配器里,早早就讲过了。
需要注意的是该页面如何知道是显示添加一条新的备忘录还是显示从主页面点入的备忘录内容。
回看recyDisply()的方法的第一二句:
String myid = getIntent().getStringExtra("_id");
if(myid == null){
return;
}

在这里,我们接收了一个Intent传递过来的叫“_id”的数据。然后对这个id进行判断,如果为空,表示数据库中不存在该条备忘录,自然不需要执行后面显示内容的代码。
如果该id不为空,则表示数据库中已经存在该_id的备忘录,我们就将该条备忘录的内容显示出来,用户可对其进行修改。
那么,接收的这个_id从哪里来?

MemoAdapter
//点击显示
mholder.item_layout.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new Intent(mcontext, AddInfoActivity.class);
intent.putExtra("_id",arr.get(position).getId());
Toast.makeText(mcontext,"_id"+arr.get(position).getId(),Toast.LENGTH_LONG).show();
startActivity(intent);
}
});

对RecyclerView中的子项进行点击后,我们就进入AddInfoActivity,这里的intent.putExtra("_id",arr.get(position).getId());便是将该条备忘录的id传递了过去。
我们在AddInfoActivity就可以通过getIntent().getStringExtra("_id");接收。
自然,从主界面已经存在的子项中进入,_id是存在的。
而从悬浮按钮点击进入,_id自然为null。
对于更新数据库和插入数据库的判断也是同理。
点击左上角的返回按钮后,我们在recyUpdate()方法中进行判断。
String myid = getIntent().getStringExtra("_id");
if(myid == null){
saveToDb();
return;
}

如果该id已经存在,则执行后面的更新代码。
如果不存在,则执行saveToDb();添加到数据库。
----------------------完结
源码:https://github.com/Xiang-MY/MemoDemo
 

 

posted @ 2022-03-23 16:34  虞美人体重90  阅读(202)  评论(0编辑  收藏  举报