<think>我们继续完成日记本应用的核心模块,特别是日记编辑页面(DiaryEditActivity)和数据库操作方法。同时补充之前省略的DiaryAdapter(日记列表适配器)和Diary类(日记数据模型)。注意:由于代码量较大,我们将分模块展示。请确保在项目中创建对应的文件。我们将按照以下顺序完成:1.Diary类(数据模型)2.DBHelper中的日记增删改查方法3.DiaryListActivity中使用的DiaryAdapter4.DiaryEditActivity(核心:编辑日记,包括图片处理)5.相关布局文件(补充之前未展示的部分)首先,我们创建一个简单的Diary类,用于表示日记对象:文件:java/com/example/diary03/Diary.java```javapackagecom.example.diary03;//日记数据模型,类似于一个装日记的盒子,里面存放了日记的各种属性publicclassDiary{privateintid;privateintuserId;privateStringtitle;privateStringcontent;privateStringimagePath;privateStringcreatedAt;//构造方法publicDiary(intid,intuserId,Stringtitle,Stringcontent,StringimagePath,StringcreatedAt){this.id=id;this.userId=userId;this.title=title;this.content=content;this.imagePath=imagePath;this.createdAt=createdAt;}//以下为各个属性的getter方法,用于取出盒子里的内容publicintgetId(){returnid;}publicintgetUserId(){returnuserId;}publicStringgetTitle(){returntitle;}publicStringgetContent(){returncontent;}publicStringgetImagePath(){returnimagePath;}publicStringgetCreatedAt(){returncreatedAt;}}```接下来,补充DBHelper类中关于日记的增删改查方法(之前省略的部分)。注意:我们假设已经有一个方法getUserByUsername(根据用户名获取用户ID),但为了完整,我们将实现它。文件:java/com/example/diary03/DBHelper.java(补充方法)```java//在DBHelper类中添加以下方法//根据用户名获取用户ID(用于将用户名转换为存储日记时需要的外键)publicintgetUserByUsername(Stringusername){SQLiteDatabasedb=this.getReadableDatabase();Cursorcursor=db.rawQuery("SELECTidFROMusersWHEREusername=?",newString[]{username});if(cursor.moveToFirst()){intid=cursor.getInt(0);cursor.close();returnid;}cursor.close();return-1;//未找到}//添加日记(将新日记存入档案库)publiclongaddDiary(intuserId,Stringtitle,Stringcontent,StringimagePath){SQLiteDatabasedb=this.getWritableDatabase();ContentValuesvalues=newContentValues();values.put("user_id",userId);values.put("title",title);values.put("content",content);values.put("image_path",imagePath);longid=db.insert("diaries",null,values);db.close();returnid;}//更新日记(更新档案库中的已有日记)publicintupdateDiary(intdiaryId,Stringtitle,Stringcontent,StringimagePath){SQLiteDatabasedb=this.getWritableDatabase();ContentValuesvalues=newContentValues();values.put("title",title);values.put("content",content);if(imagePath!=null){values.put("image_path",imagePath);}introwsAffected=db.update("diaries",values,"id=?",newString[]{String.valueOf(diaryId)});db.close();returnrowsAffected;}//删除日记(从档案库中移除)publicintdeleteDiary(intdiaryId){SQLiteDatabasedb=this.getWritableDatabase();introwsAffected=db.delete("diaries","id=?",newString[]{String.valueOf(diaryId)});db.close();returnrowsAffected;}//获取指定用户的所有日记(从档案库取出该用户的所有日记)publicArrayList<Diary>getAllDiaries(Stringusername){ArrayList<Diary>diaries=newArrayList<>();intuserId=getUserByUsername(username);if(userId==-1){returndiaries;//返回空列表}SQLiteDatabasedb=this.getReadableDatabase();Cursorcursor=db.rawQuery("SELECT*FROMdiariesWHEREuser_id=?ORDERBYcreated_atDESC",newString[]{String.valueOf(userId)});if(cursor.moveToFirst()){do{intid=cursor.getInt(0);//userId已经获取,这里不需要再取Stringtitle=cursor.getString(2);Stringcontent=cursor.getString(3);StringimagePath=cursor.getString(4);StringcreatedAt=cursor.getString(5);Diarydiary=newDiary(id,userId,title,content,imagePath,createdAt);diaries.add(diary);}while(cursor.moveToNext());}cursor.close();db.close();returndiaries;}//获取单个日记(根据日记ID)publicDiarygetDiaryById(intdiaryId){SQLiteDatabasedb=this.getReadableDatabase();Cursorcursor=db.rawQuery("SELECT*FROMdiariesWHEREid=?",newString[]{String.valueOf(diaryId)});Diarydiary=null;if(cursor.moveToFirst()){intuserId=cursor.getInt(1);Stringtitle=cursor.getString(2);Stringcontent=cursor.getString(3);StringimagePath=cursor.getString(4);StringcreatedAt=cursor.getString(5);diary=newDiary(diaryId,userId,title,content,imagePath,createdAt);}cursor.close();db.close();returndiary;}```接下来,我们创建DiaryAdapter(日记列表的适配器),用于在ListView中显示日记列表。文件:java/com/example/diary03/DiaryAdapter.java```javapackagecom.example.diary03;importandroid.content.Context;importandroid.view.LayoutInflater;importandroid.view.View;importandroid.view.ViewGroup;importandroid.widget.ArrayAdapter;importandroid.widget.TextView;importjava.util.ArrayList;//日记列表适配器:就像一个展示架,把每篇日记按照指定的样式摆放在列表的每一项中publicclassDiaryAdapterextendsArrayAdapter<Diary>{publicDiaryAdapter(Contextcontext,ArrayList<Diary>diaries){super(context,0,diaries);}@OverridepublicViewgetView(intposition,ViewconvertView,ViewGroupparent){//获取日记数据项Diarydiary=getItem(position);//检查是否有复用的视图,否则就创建一个新的if(convertView==null){convertView=LayoutInflater.from(getContext()).inflate(R.layout.list_item_diary,parent,false);}//查找视图中的控件TextViewtvTitle=convertView.findViewById(R.id.tvTitle);TextViewtvDate=convertView.findViewById(R.id.tvDate);TextViewtvContentPreview=convertView.findViewById(R.id.tvContentPreview);//设置控件内容tvTitle.setText(diary.getTitle());tvDate.setText(diary.getCreatedAt());//内容预览只取前30个字符Stringcontent=diary.getContent();if(content.length()>30){content=content.substring(0,30)+"...";}tvContentPreview.setText(content);returnconvertView;}}```然后,我们实现日记编辑页面(DiaryEditActivity),包括拍照和从相册选择图片。文件:java/com/example/diary03/DiaryEditActivity.java```javapackagecom.example.diary03;importandroid.content.Intent;importandroid.graphics.Bitmap;importandroid.os.Bundle;importandroid.provider.MediaStore;importandroid.view.View;importandroid.widget.Button;importandroid.widget.EditText;importandroid.widget.ImageView;importandroid.widget.TextView;importandroid.widget.Toast;importandroidx.annotation.Nullable;importandroidx.appcompat.app.AppCompatActivity;importjava.text.SimpleDateFormat;importjava.util.Date;importjava.util.Locale;publicclassDiaryEditActivityextendsAppCompatActivity{privateEditTextetTitle,etContent;privateTextViewtvDate;privateImageViewivPhoto;privateButtonbtnCamera,btnGallery,btnSave;privateDBHelperdbHelper;privateStringcurrentPhotoPath=null;//当前图片路径privateStringmode;//模式:添加或编辑privateintdiaryId=-1;//如果是编辑模式,记录日记ID@OverrideprotectedvoidonCreate(BundlesavedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.activity_diary_edit);//初始化视图etTitle=findViewById(R.id.etTitle);etContent=findViewById(R.id.etContent);tvDate=findViewById(R.id.tvDate);ivPhoto=findViewById(R.id.ivPhoto);btnCamera=findViewById(R.id.btnCamera);btnGallery=findViewById(R.id.btnGallery);btnSave=findViewById(R.id.btnSave);dbHelper=newDBHelper(this);//获取传递过来的模式mode=getIntent().getStringExtra("mode");//如果是编辑模式,加载现有日记if("edit".equals(mode)){diaryId=getIntent().getIntExtra("diary_id",-1);loadDiaryData();}else{//添加模式,设置当前时间为创建时间StringcurrentTime=newSimpleDateFormat("yyyy-MM-ddHH:mm",Locale.getDefault()).format(newDate());tvDate.setText(currentTime);}//拍照按钮点击事件btnCamera.setOnClickListener(newView.OnClickListener(){@OverridepublicvoidonClick(Viewv){//请求相机权限(实际项目中需要先检查权限)ImageUtils.openCamera(DiaryEditActivity.this,1);}});//相册按钮点击事件btnGallery.setOnClickListener(newView.OnClickListener(){@OverridepublicvoidonClick(Viewv){ImageUtils.openGallery(DiaryEditActivity.this,2);}});//保存按钮点击事件btnSave.setOnClickListener(newView.OnClickListener(){@OverridepublicvoidonClick(Viewv){saveDiary();}});}//加载日记数据(编辑模式)privatevoidloadDiaryData(){Diarydiary=dbHelper.getDiaryById(diaryId);if(diary!=null){etTitle.setText(diary.getTitle());etContent.setText(diary.getContent());tvDate.setText(diary.getCreatedAt());currentPhotoPath=diary.getImagePath();//如果有图片路径,显示图片if(currentPhotoPath!=null){//这里简化处理:实际应该异步加载并调整尺寸Bitmapbitmap=ImageUtils.loadImage(currentPhotoPath);if(bitmap!=null){ivPhoto.setImageBitmap(bitmap);ivPhoto.setVisibility(View.VISIBLE);}}}}//保存日记(添加或更新)privatevoidsaveDiary(){Stringtitle=etTitle.getText().toString().trim();Stringcontent=etContent.getText().toString().trim();if(title.isEmpty()){Toast.makeText(this,"标题不能为空",Toast.LENGTH_SHORT).show();return;}//获取当前登录用户的IDSharedPreferencespref=getSharedPreferences("login_pref",MODE_PRIVATE);Stringusername=pref.getString("username","");intuserId=dbHelper.getUserByUsername(username);if(userId==-1){Toast.makeText(this,"用户不存在",Toast.LENGTH_SHORT).show();return;}if("add".equals(mode)){//添加日记longnewRowId=dbHelper.addDiary(userId,title,content,currentPhotoPath);if(newRowId!=-1){Toast.makeText(this,"日记保存成功",Toast.LENGTH_SHORT).show();setResult(RESULT_OK);finish();}else{Toast.makeText(this,"保存失败",Toast.LENGTH_SHORT).show();}}elseif("edit".equals(mode)){//更新日记introws=dbHelper.updateDiary(diaryId,title,content,currentPhotoPath);if(rows>0){Toast.makeText(this,"更新成功",Toast.LENGTH_SHORT).show();setResult(RESULT_OK);finish();}else{Toast.makeText(this,"更新失败",Toast.LENGTH_SHORT).show();}}}//处理返回的图片数据(拍照或相册)@OverrideprotectedvoidonActivityResult(intrequestCode,intresultCode,@NullableIntentdata){super.onActivityResult(requestCode,resultCode,data);if(resultCode==RESULT_OK){if(requestCode==1){//拍照返回Bundleextras=data.getExtras();BitmapimageBitmap=(Bitmap)extras.get("data");//保存图片并获取路径currentPhotoPath=ImageUtils.saveImage(imageBitmap,this);//显示图片if(currentPhotoPath!=null){ivPhoto.setImageBitmap(imageBitmap);ivPhoto.setVisibility(View.VISIBLE);}}elseif(requestCode==2){//相册返回if(data!=null&&data.getData()!=null){//从Uri获取图片并保存Bitmapbitmap=ImageUtils.getBitmapFromUri(this,data.getData());if(bitmap!=null){currentPhotoPath=ImageUtils.saveImage(bitmap,this);ivPhoto.setImageBitmap(bitmap);ivPhoto.setVisibility(View.VISIBLE);}}}}}}```同时,我们补充ImageUtils类中缺失的两个方法(之前只有openCamera和openGallery):文件:java/com/example/diary03/ImageUtils.java(补充方法)```java//从Uri获取BitmappublicstaticBitmapgetBitmapFromUri(Contextcontext,Uriuri){try{returnMediaStore.Images.Media.getBitmap(context.getContentResolver(),uri);}catch(IOExceptione){e.printStackTrace();}returnnull;}//从文件路径加载Bitmap(用于编辑时显示已存在的图片)publicstaticBitmaploadImage(Stringpath){returnBitmapFactory.decodeFile(path);}```现在,我们展示日记列表项的布局文件(list_item_diary.xml),该文件需要创建在res/layout下:文件:res/layout/list_item_diary.xml```xml<?xmlversion="1.0"encoding="utf-8"?><LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="vertical"android:padding="16dp"android:background="@android:color/white"android:elevation="4dp"android:layout_marginBottom="8dp"><TextViewandroid:id="@+id/tvTitle"android:layout_width="match_parent"android:layout_height="wrap_content"android:textSize="18sp"android:textStyle="bold"android:textColor="@color/primary"/><TextViewandroid:id="@+id/tvDate"android:layout_width="match_parent"android:layout_height="wrap_content"android:textSize="12sp"android:textColor="@color/text_secondary"android:paddingTop="4dp"android:paddingBottom="8dp"/><TextViewandroid:id="@+id/tvContentPreview"android:layout_width="match_parent"android:layout_height="wrap_content"android:textSize="14sp"android:textColor="@android:color/black"android:maxLines="2"android:ellipsize="end"/></LinearLayout>```最后,补充一些资源文件(values/strings.xml和values/colors.xml)的部分内容:文件:res/values/strings.xml```xml<resources><!--登录页面--><stringname="app_name">日记本</string><stringname="username_hint">用户名</string><stringname="password_hint">密码</string><stringname="remember_password">记住密码</string><stringname="login_button">登录</string><stringname="register_button">注册</string><!--注册页面--><stringname="register_title">注册</string><stringname="confirm_password_hint">确认密码</string><stringname="register">注册</string><!--日记列表页面--><stringname="diary_list_title">日记列表</string><!--日记编辑页面--><stringname="title_hint">日记标题</string><stringname="content_hint">写下你的心情...</string><stringname="take_photo">拍照</string><stringname="choose_from_gallery">相册</string><stringname="save_diary">保存日记</string></resources>```文件:res/values/colors.xml```xml<?xmlversion="1.0"encoding="utf-8"?><resources><colorname="primary">#64B5F6</color><colorname="primary_dark">#42A5F5</color><colorname="app_background">#E3F2FD</color><colorname="text_primary">#212121</color><colorname="text_secondary">#757575</color></resources>```由于项目代码量较大,以上仅为核心代码。实际运行前还需要配置AndroidManifest.xml(添加Activity和权限)以及处理运行时权限(在打开相机和相册时)。运行指南:1.在AndroidStudio中创建新项目,包名为com.example.diary03。2.将上述Java文件放入对应的包路径下。3.将布局文件放入res/layout下,资源文件放入values下。4.在AndroidManifest.xml中注册所有Activity,并添加必要的权限:```xml<uses-permissionandroid:name="android.permission.CAMERA"/><uses-permissionandroid:name="android.permission.WRITE_EXTERNAL_STORAGE"android:maxSdkVersion="28"/><!--Android10以上使用作用域存储,但为了简化,我们使用旧的方式-->```注意:由于从Android10开始引入了作用域存储,图片保存可能需要额外处理。为了简化,我们将图片保存到应用的私有目录,因此不需要额外存储权限(但需要WRITE_EXTERNAL_STORAGE权限,在Android10以下)。另外,打开相册需要读取存储权限。这个示例项目为了简单,没有处理运行时权限(实际应用必须处理)。另外,图片处理可能在大图时出现OOM,实际应用中应该优化。总结:我们完成了一个包含登录、注册和日记管理功能的日记本应用。主要技术点包括:-SQLite数据库设计(用户、日记表)-SharedPreferences存储登录状态-使用ListView展示日记列表-通过Intent在不同Activity间传递数据-调用相机和相册获取图片-图片的保存和加载项目结构清晰,代码中均有详细注释。请注意,这只是一个基础版本,还有很多可以优化的地方,比如:-使用RecyclerView代替ListView-运行时权限处理-图片的异步加载和压缩-登录密码加密存储-日记内容的分页加载等。希望这个实现对您有帮助。§§相关问题§§:1.如何实现运行时权限申请?2.如何加密存储用户的密码?3.如何优化图片加载以避免内存溢出?4.使用RecyclerView代替ListView有哪些优势?</think>
以下是一个完整的Android Studio日记本应用实现方案,我将按照要求详细展示每个文件的完整内容并逐一解释核心模块。项目完全符合您的要求:使用SQLite数据库、SharedPreferences、常见控件和事件处理,并采用淡蓝色主题。
---
### **完整项目结构**
```
diary03/
├── app/
│ ├── src/
│ │ ├── main/
│ │ │ ├── java/com/example/diary03/
│ │ │ │ ├── LoginActivity.java
│ │ │ │ ├── RegisterActivity.java
│ │ │ │ ├── DiaryListActivity.java
│ │ │ │ ├── DiaryEditActivity.java
│ │ │ │ ├── DBHelper.java
│ │ │ │ └── DiaryAdapter.java
│ │ │ ├── res/
│ │ │ │ ├── layout/
│ │ │ │ │ ├── activity_login.xml
│ │ │ │ │ ├── activity_register.xml
│ │ │ │ │ ├── activity_diary_list.xml
│ │ │ │ │ ├── activity_diary_edit.xml
│ │ │ │ │ └── diary_item.xml
│ │ │ │ ├── values/
│ │ │ │ │ ├── colors.xml
│ │ │ │ │ ├── strings.xml
│ │ │ │ │ └── themes.xml
│ │ │ │ └── menu/
│ │ │ │ └── main_menu.xml
│ │ │ ├── AndroidManifest.xml
```
---
### **1. 数据库模块 (DBHelper.java)**
```java
package com.example.diary03;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import java.util.ArrayList;
// 数据库管家:负责创建和管理本地数据存储(就像个档案管理员)
public class DBHelper extends SQLiteOpenHelper {
// 数据库名称和版本
private static final String DATABASE_NAME = "DiaryDB";
private static final int DATABASE_VERSION = 1;
// 用户表(账户保险柜)
private static final String TABLE_USERS = "users";
private static final String COLUMN_USER_ID = "id";
private static final String COLUMN_USERNAME = "username";
private static final String COLUMN_PASSWORD = "password";
// 日记表(日记档案库)
private static final String TABLE_DIARIES = "diaries";
private static final String COLUMN_DIARY_ID = "id";
private static final String COLUMN_USER_ID_FK = "user_id";
private static final String COLUMN_TITLE = "title";
private static final String COLUMN_CONTENT = "content";
private static final String COLUMN_IMAGE_PATH = "image_path";
private static final String COLUMN_CREATED_AT = "created_at";
// 创建用户表的SQL语句(建立新档案柜)
private static final String CREATE_USER_TABLE = "CREATE TABLE " + TABLE_USERS + "("
+ COLUMN_USER_ID + " INTEGER PRIMARY KEY AUTOINCREMENT,"
+ COLUMN_USERNAME + " TEXT UNIQUE NOT NULL,"
+ COLUMN_PASSWORD + " TEXT NOT NULL"
+ ")";
// 创建日记表的SQL语句(建立日记存储架)
private static final String CREATE_DIARY_TABLE = "CREATE TABLE " + TABLE_DIARIES + "("
+ COLUMN_DIARY_ID + " INTEGER PRIMARY KEY AUTOINCREMENT,"
+ COLUMN_USER_ID_FK + " INTEGER,"
+ COLUMN_TITLE + " TEXT NOT NULL,"
+ COLUMN_CONTENT + " TEXT NOT NULL,"
+ COLUMN_IMAGE_PATH + " TEXT,"
+ COLUMN_CREATED_AT + " DATETIME DEFAULT CURRENT_TIMESTAMP,"
+ "FOREIGN KEY(" + COLUMN_USER_ID_FK + ") REFERENCES " + TABLE_USERS + "(" + COLUMN_USER_ID + ")"
+ ")";
public DBHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
// 创建用户和日记表
db.execSQL(CREATE_USER_TABLE);
db.execSQL(CREATE_DIARY_TABLE);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// 升级数据库(重建档案库)
db.execSQL("DROP TABLE IF EXISTS " + TABLE_USERS);
db.execSQL("DROP TABLE IF EXISTS " + TABLE_DIARIES);
onCreate(db);
}
// 用户注册(在保险柜存入新钥匙)
public long registerUser(String username, String password) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(COLUMN_USERNAME, username);
values.put(COLUMN_PASSWORD, password);
// 插入数据,返回行ID或-1(失败)
return db.insert(TABLE_USERS, null, values);
}
// 用户登录(验证钥匙匹配)
public boolean checkUserCredentials(String username, String password) {
SQLiteDatabase db = this.getReadableDatabase();
String selection = COLUMN_USERNAME + " = ? AND " + COLUMN_PASSWORD + " = ?";
String[] selectionArgs = {username, password};
Cursor cursor = db.query(TABLE_USERS, null, selection, selectionArgs,
null, null, null);
int count = cursor.getCount();
cursor.close();
return count > 0;
}
// 添加日记(在档案库增加新卷宗)
public long addDiary(int userId, String title, String content, String imagePath) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(COLUMN_USER_ID_FK, userId);
values.put(COLUMN_TITLE, title);
values.put(COLUMN_CONTENT, content);
values.put(COLUMN_IMAGE_PATH, imagePath);
return db.insert(TABLE_DIARIES, null, values);
}
// 获取所有日记(取出用户的卷宗集合)
public ArrayList<Diary> getAllDiaries(int userId) {
ArrayList<Diary> diaries = new ArrayList<>();
SQLiteDatabase db = this.getReadableDatabase();
String selection = COLUMN_USER_ID_FK + " = ?";
String[] selectionArgs = {String.valueOf(userId)};
Cursor cursor = db.query(TABLE_DIARIES, null, selection, selectionArgs,
null, null, COLUMN_CREATED_AT + " DESC");
if (cursor.moveToFirst()) {
do {
Diary diary = new Diary(
cursor.getInt(cursor.getColumnIndex(COLUMN_DIARY_ID)),
cursor.getString(cursor.getColumnIndex(COLUMN_TITLE)),
cursor.getString(cursor.getColumnIndex(COLUMN_CONTENT)),
cursor.getString(cursor.getColumnIndex(COLUMN_IMAGE_PATH)),
cursor.getString(cursor.getColumnIndex(COLUMN_CREATED_AT))
);
diaries.add(diary);
} while (cursor.moveToNext());
}
cursor.close();
return diaries;
}
// 根据用户名获取用户ID(找到钥匙主人)
public int getUserId(String username) {
SQLiteDatabase db = this.getReadableDatabase();
String[] columns = {COLUMN_USER_ID};
String selection = COLUMN_USERNAME + " = ?";
String[] selectionArgs = {username};
Cursor cursor = db.query(TABLE_USERS, columns, selection, selectionArgs,
null, null, null);
if (cursor.moveToFirst()) {
return cursor.getInt(cursor.getColumnIndex(COLUMN_USER_ID));
}
cursor.close();
return -1;
}
}
```
---
### **2. 数据模型 (Diary.java)**
```java
package com.example.diary03;
// 日记实体类(像一本日记本的单页)
public class Diary {
private int id;
private String title;
private String content;
private String imagePath;
private String createdAt;
public Diary(int id, String title, String content, String imagePath, String createdAt) {
this.id = id;
this.title = title;
this.content = content;
this.imagePath = imagePath;
this.createdAt = createdAt;
}
// 获取方法(阅读日记的不同部分)
public int getId() { return id; }
public String getTitle() { return title; }
public String getContent() { return content; }
public String getImagePath() { return imagePath; }
public String getCreatedAt() { return createdAt; }
}
```
---
### **3. 登录功能 (LoginActivity.java)**
```java
package com.example.diary03;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
// 入口门禁系统
public class LoginActivity extends AppCompatActivity {
private EditText etUsername, etPassword;
private CheckBox cbRemember;
private SharedPreferences sharedPreferences;
// 偏好设置键(记忆标签)
private static final String PREFS_NAME = "login_pref";
private static final String KEY_USERNAME = "username";
private static final String KEY_PASSWORD = "password";
private static final String KEY_REMEMBER = "remember";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
// 初始化视图组件
etUsername = findViewById(R.id.et_username);
etPassword = findViewById(R.id.et_password);
cbRemember = findViewById(R.id.cb_remember);
Button btnLogin = findViewById(R.id.btn_login);
TextView tvRegister = findViewById(R.id.tv_register);
// 偏好设置初始化(记忆盒子)
sharedPreferences = getSharedPreferences(PREFS_NAME, MODE_PRIVATE);
// 自动填充记住的凭据
if (sharedPreferences.getBoolean(KEY_REMEMBER, false)) {
etUsername.setText(sharedPreferences.getString(KEY_USERNAME, ""));
etPassword.setText(sharedPreferences.getString(KEY_PASSWORD, ""));
cbRemember.setChecked(true);
}
// 登录按钮点击事件(验证通行证)
btnLogin.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String username = etUsername.getText().toString().trim();
String password = etPassword.getText().toString().trim();
DBHelper dbHelper = new DBHelper(LoginActivity.this);
if (dbHelper.checkUserCredentials(username, password)) {
// 记住密码功能
saveCredentials(username, password);
// 跳转到日记列表
Intent intent = new Intent(LoginActivity.this, DiaryListActivity.class);
startActivity(intent);
finish();
} else {
Toast.makeText(LoginActivity.this, "用户名或密码错误", Toast.LENGTH_SHORT).show();
}
}
});
// 注册跳转(获取新通行证)
tvRegister.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
startActivity(new Intent(LoginActivity.this, RegisterActivity.class));
}
});
}
// 保存凭证(在记忆盒子存储信息)
private void saveCredentials(String username, String password) {
SharedPreferences.Editor editor = sharedPreferences.edit();
if (cbRemember.isChecked()) {
editor.putString(KEY_USERNAME, username);
editor.putString(KEY_PASSWORD, password);
editor.putBoolean(KEY_REMEMBER, true);
} else {
editor.clear();
}
editor.apply();
}
}
```
---
### **4. 注册功能 (RegisterActivity.java)**
```java
package com.example.diary03;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
// 用户注册(制作新通行证)
public class RegisterActivity extends AppCompatActivity {
private EditText etUsername, etPassword, etConfirmPassword;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_register);
// 初始化视图组件
etUsername = findViewById(R.id.et_reg_username);
etPassword = findViewById(R.id.et_reg_password);
etConfirmPassword = findViewById(R.id.et_confirm_password);
Button btnRegister = findViewById(R.id.btn_register);
// 注册按钮点击事件(提交通行证申请)
btnRegister.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String username = etUsername.getText().toString().trim();
String password = etPassword.getText().toString().trim();
String confirm = etConfirmPassword.getText().toString().trim();
if (!password.equals(confirm)) {
Toast.makeText(RegisterActivity.this, "两次密码不一致", Toast.LENGTH_SHORT).show();
return;
}
DBHelper dbHelper = new DBHelper(RegisterActivity.this);
if (dbHelper.registerUser(username, password) != -1) {
Toast.makeText(RegisterActivity.this, "注册成功,请登录", Toast.LENGTH_SHORT).show();
finish(); // 返回登录界面
} else {
Toast.makeText(RegisterActivity.this, "用户名已存在", Toast.LENGTH_SHORT).show();
}
}
});
}
}
```
---
### **5. 日记列表 (DiaryListActivity.java)**
```java
package com.example.diary03;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import java.util.ArrayList;
// 日记档案管理室
public class DiaryListActivity extends AppCompatActivity {
private ListView listView;
private DiaryAdapter adapter;
private ArrayList<Diary> diaryList;
private DBHelper dbHelper;
private int currentUserId;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_diary_list);
// 获取当前用户ID(通行证号码)
SharedPreferences pref = getSharedPreferences("login_pref", MODE_PRIVATE);
String username = pref.getString("username", "");
dbHelper = new DBHelper(this);
currentUserId = dbHelper.getUserId(username);
// 初始化视图
listView = findViewById(R.id.lv_diaries);
FloatingActionButton fabAdd = findViewById(R.id.fab_add);
// 加载日记数据(取出档案)
loadDiaries();
// 添加新日记按钮(制作新档案)
fabAdd.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(DiaryListActivity.this, DiaryEditActivity.class);
startActivityForResult(intent, 1);
}
});
// 列表项点击(查看档案详情)
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Diary selectedDiary = diaryList.get(position);
Intent intent = new Intent(DiaryListActivity.this, DiaryEditActivity.class);
intent.putExtra("diary_id", selectedDiary.getId());
startActivityForResult(intent, 1);
}
});
}
// 加载日记(更新档案架)
private void loadDiaries() {
diaryList = dbHelper.getAllDiaries(currentUserId);
adapter = new DiaryAdapter(this, diaryList);
listView.setAdapter(adapter);
}
// 菜单创建(档案管理工具)
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main_menu, menu);
return true;
}
// 菜单项选择(使用管理工具)
@Override
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
int id = item.getItemId();
if (id == R.id.menu_logout) {
// 退出登录(交回通行证)
SharedPreferences.Editor editor = getSharedPreferences("login_pref", MODE_PRIVATE).edit();
editor.clear();
editor.apply();
startActivity(new Intent(this, LoginActivity.class));
finish();
return true;
}
return super.onOptionsItemSelected(item);
}
// 处理结果(档案更新通知)
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK) {
loadDiaries(); // 刷新列表
}
}
}
```
---
### **6. 日记编辑 (DiaryEditActivity.java)**
```java
package com.example.diary03;
import android.content.Intent;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.provider.MediaStore;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
// 档案编辑工作台
public class DiaryEditActivity extends AppCompatActivity {
private EditText etTitle, etContent;
private TextView tvDate;
private ImageView ivPhoto;
private Button btnSave, btnCamera, btnGallery;
private DBHelper dbHelper;
private int currentUserId;
private String currentPhotoPath