成果展示:
1.前期准备
(1)在
配置文件中添加
权限及启动页面顺序
①展开工程,打开app下方的AndroidManifest.xml,添加权限,如下:
<uses-permission android:name="android.permission.CAMERA"
/>
<
uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
② 依旧在AndroidManifest.xml文件中添加启动页面顺序的功能代码
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package
="com.example.ts_menu"> //这里注意
修改成自己
创建的包名
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
android:allowBackup="true"
android:icon
="@mIPmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon
="@mIPmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".AddInfoActivity"></activity>
<activity android:name=".LoginActivity">
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
<activity android:name=".MainActivity">
(2)添加依赖
展开工程,打开app下方的build.gradle ,添加依赖,如下:依赖添加好之后,要记着同步,在页面右上角的位置单击:Sync Now 即可。
implementation com.android.support:recyclerview-v7:+implementation com.github.bumptech.glide:glide:4.9.0API com.blankj:utilcode:1.23.7
(3)素材
一共5张图片,粘贴到工程的drawable文件夹下来,其中bgone.png,bgthree.jpg两个图片是登录界面和信息添加界面的背景,buttonbg.png,savebg.png图片是添加备忘录按钮和保存按钮的背景,另外一张背景图片是sunshine.jpg是一张默认显示的照片。选择你自己喜欢的图片添加进去吧!
2.所需的布局文件
2.1 activity_login.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:layout_height="match_parent"
android:orientation="vertical"
android:background="@drawable/bgone"
tools:context=".LoginActivity">
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="#000000"
android:layout_margin="100dp"
android:gravity="center"/>
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_margin="10dp">
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#000000"
android:textSize="30sp" />
android:id="@+id/editText_inputname"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="#000000"
android:textSize="30sp" />
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_margin="10dp">
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#000000"
android:textSize="30sp" />
android:id="@+id/editText_inputpwd"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="#000000"
android:inputType="textPassword"
android:textSize="30sp" />
android:id="@+id/checkBox_reme"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right"
android:layout_margin="10dp"/>
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_margin="10dp">
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#000000"
android:layout_weight="1"/>
android:id="@+id/button_login"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#000000"
android:layout_weight="1"/>
2.2 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:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity">
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="愿这小小的备忘录,记下我生活中的点点滴滴"
android:textColor="#000000"
android:layout_gravity="center"
android:layout_margin="10dp" />
android:id="@+id/button_add"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#000000"
android:layout_gravity="right"
android:background="@drawable/buttonbg"
android:layout_margin="10dp" />
<android.support.v7.widget.RecyclerView
android:id="@+id/recy_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
2.3 activity_add_info.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:layout_height="match_parent"
android:orientation="vertical"
android:background="@drawable/bgthree"
tools:context=".AddInfoActivity">
android:id="@+id/editText_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="#000000"
android:textSize="30sp"/>
android:layout_width="match_parent"
android:layout_height="2dp"
android:background="#009688"
android:layout_marginTop="-10dp"/>
android:id="@+id/editText_content"
android:layout_width="match_parent"
android:layout_height="200dp"
android:textColor="#000000"
android:layout_width="match_parent"
android:layout_height="2dp"
android:background="#009688"
android:layout_marginTop="-10dp"/>
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text=
"请选用下面的任一种方式,添加一张心情图片:"
android:textColor="#000000"
android:layout_margin="10dp"/>
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_margin="10dp">
android:id="@+id/button_camera"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#000000"
android:layout_margin="10dp"/>
android:id="@+id/button_photo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#000000"
android:layout_margin="10dp"/>
android:id="@+id/imageView_preview"
android:layout_width="wrap_content"
android:layout_height="200dp"
android:src="@drawable/sunshine"
android:layout_marginBottom="20dp"
android:layout_gravity="center"/>
android:id="@+id/button_save"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="#000000"
android:background="@drawable/savebg"
android:layout_margin="10dp"/>
2.4 recy_item.xml
文件代码:
主界面--子布局界面
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#7AECCC"
android:id="@+id/item_layout"
android:layout_margin="5dp" >
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_gravity="center"
android:layout_weight="1"
android:layout_margin="5dp"
android:id="@+id/item_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="#000000"/>
android:id="@+id/item_content"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#000000"/>
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_margin="5dp">
android:id="@+id/item_image"
android:layout_width="100dp"
android:layout_height="100dp"
android:src=
"@mIPmap/ic_launcher_round"/>
android:id="@+id/item_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#000000"
android:layout_gravity="center"/>
3.所需的java类文件
以下是所需要添加的package,及java类文件。
package所需要添加的文件有adapter、bean、db三个package包。
java类文件除了开始的主文件MainActivity,还需添加MemoAdapter、MemoBean、MydbHelper、AddInfoActivity、LoginActivity5个java类文件。
3.1 MemoAdapter
文件代码:
备忘录的自定义适配器功能代码
package com.example.ts_menu.adapter;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.database.sqlite.SQLiteDatabase;
import android.graphics.Color;
import android.graphics.drawable.GradientDrawable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Requires
API;
import androidx.recyclerview.widget.RecyclerView;
import com.bumptech.glide.Glide;
import com.example.ts_menu.R;
import com.example.ts_menu.bean.MemoBean;
import com.example.ts_menu.db.MyDbHelper;
//2 鼠标定位类文件行红色波浪线处,Alt+Enter键:添加未实现的方法
//3 鼠标定位类文件行ViewHolder处,Alt+Enter键:添加内部类
//4 鼠标定位界面最下方内部类ViewHolder处,添加extends RecyclerView.ViewHolder
//5 鼠标定位界面最下方内部类ViewHolder红色波浪线处,Alt+Enter键:添加构造方法
//7 定义两个对象下方的空白处:Alt+Insert键,添加适配器的构造方法
public class MemoAdapter extends RecyclerView.Adapter<MemoAdapter.ViewHolder> {
private Context mcontext;
private List<MemoBean> arr1;
private MyDbHelper mhelper1;
private SQLiteDatabase db;
public MemoAdapter(Context mcontext, List<MemoBean> arr1) {
this.mcontext = mcontext;
public MemoAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int i) {
View view= LayoutInflater.from(mcontext).inflate(R.layout.recy_item,parent,false);
ViewHolder mholder=new ViewHolder(view);
@RequiresAPI(API = Build.VERSION_CODES.JELLY_BEAN)
public void onBindViewHolder(@NonNull MemoAdapter.ViewHolder mholder, final int i) {
final MemoBean memoBean=arr1.get(i);
mholder.item_title.setText(memoBean.getTitle());
mholder.item_content.setText(memoBean.getContent());
mholder.item_time.setText(memoBean.getTime());
Glide.with(mcontext).load(memoBean.getImgpath()).into(mholder.item_img);
// 完善:设置RecyclerView中每一个子项的颜色和形状
Random random = new Random();
int color = Color.argb(255, random.nextInt(256), random.nextInt(256), random.nextInt(256));
GradientDrawable gradientDrawable = new GradientDrawable();
gradientDrawable.setShape(GradientDrawable.RECTANGLE);//形状
gradientDrawable.setCornerRadius(
10f);
//设置圆角Radius
gradientDrawable.setColor(color);//颜色
mholder.item_layout.setBackground(gradientDrawable);
//设置为background
mholder.item_layout.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
AlertDialog.Builder dialog=new AlertDialog.Builder(mcontext);
dialog.setMessage(
"确定删除吗?");
dialog.setPositiveButton("确定", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialogInterface, int abc) {
mhelper1= new MyDbHelper(mcontext);
db=mhelper1.getWritableDatabase();
db.delete("tb_memory","title=?",new String[]{arr1.get(i).getTitle()});
dialogInterface.dismiss();
dialog.setNegativeButton("取消",null);
dialog.setCancelable(false);
public int getItemCount() {
public class ViewHolder extends RecyclerView.ViewHolder{
TextView item_title,item_content,item_time;
LinearLayout item_layout;
public ViewHolder(@NonNull View itemView) {
item_title=itemView.findViewById(R.id.item_title);
item_content=itemView.findViewById(R.id.item_content);
item_img=itemView.findViewById(R.id.item_image);
item_time=itemView.findViewById(R.id.item_time);
item_layout=itemView.findViewById(R.id.item_layout);
3.2 MemoBean
文件代码:
一个javabean文件,为了存储备忘录的信息
package com.example.ts_menu.bean;
public MemoBean(String title, String content, String imgpath, String time) {
public String getTitle() {
public void setTitle(String title) {
public String getContent() {
public void setContent(String content) {
public String getImgpath() {
public void setImgpath(String imgpath) {
public String getTime() {
public void setTime(String time) {
3.3 MydbHelper
文件代码:
数据库文件
package com.example.ts_menu.db;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
public class MyDbHelper extends SQLiteOpenHelper {
private static String DBNAME="zsmemo.db";
private static int VERSION=1;
public MyDbHelper( Context context) {
super(context, DBNAME, null, VERSION);
public void onCreate(SQLiteDatabase db) {
db.execSQL("create table tb_memory(_id Integer primary key,title String (200),content String (2000),imgpath String (200),mtime String (50))");
public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {
3.4 AddInfoActivity
文件代码:
拍照功能直接闪退:
if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.N)
{
StrictMode.VmPolicy.Builder builder=new StrictMode.VmPolicy.Builder();
StrictMode.setVmPolicy(builder.build());
}
使用上述代码防止闪退。
在拍照功能时应该将保存路径代码改为tmp_path=Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM).getAbsolutePath()+"/image"+randtime+".jpg";
有效防止拍照后确定不了问题。
package com.example.ts_menu;
import android.content.ContentValues;
import android.content.Intent;
import android.database.sqlite.SQLiteDatabase;
import android.os.Environment;
import android.provider.MediaStore;
import android.os.Bundle;
import android.text.format.Time;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.Toast;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import com.blankj.utilcode.util.UriUtils;
import com.bumptech.glide.Glide;
import com.example.ts_menu.db.MyDbHelper;
import com.example.ts_menu.db.MyDbHelper;
import java.io.IOException;
public class AddInfoActivity extends AppCompatActivity {
EditText edit_title,edit_content;
Button btn_camera,btn_photo,btn_save;
String tmp_path,disp_path;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_add_info);
//3 接受拍好照片、接受从图库当中选择的照片 ------方法:系统回调
private void initView() {
edit_title=findViewById(R.id.editText_title);
edit_content=findViewById(R.id.editText_content);
btn_camera=findViewById(R.id.button_camera);
btn_photo=findViewById(R.id.button_photo);
img_preview=findViewById(R.id.imageView_preview);
btn_save=findViewById(R.id.button_save);
mhelper=new MyDbHelper(AddInfoActivity.this);
db= mhelper.getWritableDatabase();
private void btnOnClick() {
btn_camera.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
String randtime=time.year+(time.month+1)+time.monthDay+time.hour+time.minute+time.second+"";
// tmp_path= Environment.getExternalStorageDirectory()+"/image"+ randtime+".jpg";
tmp_path=Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM).getAbsolutePath()+"/image"+randtime+".jpg";
File imgfile=new File(tmp_path);
} catch (IOException e) {
Intent intent=new Intent("android.media.action.IMAGE_CAPTURE");
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(imgfile) );
startActivityForResult(intent,11);
btn_photo.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
Intent intent=new Intent("android.intent.action.GET_CONTENT");
intent.setType("image/*");
startActivityForResult(intent,22);
//3 接受拍好照片、接受从图库当中选择的照片 ------方法:系统回调
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
if(resultCode==RESULT_OK){
Glide.with(AddInfoActivity.this).load(disp_path).into(img_preview);
Uri imageuri=data.getData();
disp_path=UriUtils.uri2File(imageuri).getPath();
Glide.with(AddInfoActivity.this).load(disp_path).into(img_preview);
//4 把信息保存到数据库中-------------代码
btn_save.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
ContentValues contentValues=new ContentValues();//一行
contentValues.put("title",edit_title.getText().toString());//1行——1列
contentValues.put("content",edit_content.getText().toString());//1行——3列
contentValues.put("imgpath",disp_path);
contentValues.put("mtime",time.year+"/"+(time.month+1)+"/"+time.monthDay);
db.insert("tb_memory",null,contentValues);
Toast.makeText(AddInfoActivity.this,"保存成功",Toast.LENGTH_SHORT).show();
Intent intent=new Intent(AddInfoActivity.this,MainActivity.class);
3.5 LoginActivity
文件代码:
package com.example.ts_menu;
import android.content.Intent;
import android.content.SharedPreferences;
//import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.EditText;
import androidx.appcompat.app.AppCompatActivity;
public class LoginActivity extends AppCompatActivity {
private EditText edit_inputname,edit_inputpwd;
private CheckBox check_reme;
private Button btn_login;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
private void initView() {
edit_inputname=findViewById(R.id.editText_inputname);
edit_inputpwd=findViewById(R.id.editText_inputpwd);
check_reme=findViewById(R.id.checkBox_reme);
btn_login=findViewById(R.id.button_login);
private void btnloginonClick() {
btn_login.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
SharedPreferences.Editor editor=getSharedPreferences("myinfo",0).edit();
editor.putString("name",edit_inputname.getText().toString());
editor.putString("pwd",edit_inputpwd.getText().toString());
editor.putBoolean("st",check_reme.isChecked());
Intent intent=new Intent(LoginActivity.this,MainActivity.class);
private void displayinfo() {
String strname=getSharedPreferences("myinfo",0).getString("name","");
String strpwd=getSharedPreferences("myinfo",0).getString("pwd","");
Boolean status=getSharedPreferences("myinfo",0).getBoolean("st",false);
edit_inputname.setText(strname);
edit_inputpwd.setText(strpwd);
check_reme.setChecked(true);
edit_inputname.setText("");
edit_inputpwd.setText("");
check_reme.setChecked(false);
3.6 MainActivity
文件代码:
package com.example.ts_menu;
import android.content.Intent;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.view.View;
import android.widget.Adapter;
import android.widget.Button;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.RecyclerView;
import androidx.recyclerview.widget.StaggeredGridLayoutManager;
import com.example.ts_menu.adapter.MemoAdapter;
import com.example.ts_menu.bean.MemoBean;
import com.example.ts_menu.db.MyDbHelper;
import java.util.ArrayList;
public class MainActivity extends AppCompatActivity {
private RecyclerView recy_view;
private MyDbHelper mhelper;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//3完善:从数据库获取数据,显示到RecyclerView控件里面
private void initView() {
btn_add=findViewById(R.id.button_add);
recy_view=findViewById(R.id.recy_view);
mhelper=new MyDbHelper(MainActivity.this);
db=mhelper.getWritableDatabase();
private void btnonclicknext() {
btn_add.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
Intent intent=new Intent(MainActivity.this,AddInfoActivity.class);
//3完善:从数据库获取数据,显示到RecyclerView控件里面---------------代码
private void recyDisplay() {
//3.1准备数据-----------标题、内容、图片、时间(类)
List<MemoBean> arr=new ArrayList();
Cursor cursor=db.rawQuery("select * from tb_memory",null);
while(cursor.moveToNext()){
String mytitle=cursor.getString(cursor.getColumnIndex("title"));
String mycontent=cursor.getString(cursor.getColumnIndex("content"));
String myimgpath=cursor.getString(cursor.getColumnIndex("imgpath"));
String mymtime=cursor.getString(cursor.getColumnIndex("mtime"));
MemoBean memoBean=new MemoBean(mytitle,mycontent,myimgpath,mymtime);
//3.3 数据------桥(适配器MemoAdapter)----------------子布局
MemoAdapter adapter=new MemoAdapter(MainActivity.this,arr);
StaggeredGridLayoutManager st=new StaggeredGridLayoutManager(2,StaggeredGridLayoutManager.VERTICAL);
recy_view.setLayoutManager(st);
recy_view.setAdapter(adapter);
注意:activity文件中相关的名称报错,得换成自己所创建工程的名字。