├── .gitignore ├── .idea ├── codeStyles │ └── Project.xml ├── compiler.xml ├── dictionaries │ └── mabeg.xml ├── encodings.xml ├── gradle.xml ├── jarRepositories.xml ├── misc.xml ├── runConfigurations.xml └── vcs.xml ├── LICENSE ├── README.md ├── app ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── example │ │ └── notebook │ │ └── ExampleInstrumentedTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── com │ │ │ └── example │ │ │ └── notebook │ │ │ ├── Alarm │ │ │ ├── AlarmActivity.java │ │ │ ├── AlarmCrud.java │ │ │ ├── AlarmReceiver.java │ │ │ ├── EditAlarmActivity.java │ │ │ ├── Plan.java │ │ │ ├── PlanAdapter.java │ │ │ └── PlanDatabase.java │ │ │ ├── BaseActivity.java │ │ │ ├── BaseCrud.java │ │ │ ├── EditActivity.java │ │ │ ├── HandWriting │ │ │ ├── CustomView.java │ │ │ └── HandwritingActivity.java │ │ │ ├── MainActivity.java │ │ │ ├── MyIntentService.java │ │ │ ├── Note.java │ │ │ ├── NoteAdapter.java │ │ │ └── NoteDatabase.java │ └── res │ │ ├── anim │ │ ├── in_lefttoright.xml │ │ ├── in_righttoleft.xml │ │ ├── in_slow.xml │ │ ├── night_switch.xml │ │ ├── night_switch_over.xml │ │ ├── no.xml │ │ ├── out_lefttoright.xml │ │ ├── out_righttoleft.xml │ │ └── out_slow.xml │ │ ├── drawable-v24 │ │ ├── alarm_24.png │ │ ├── bgd.jpg │ │ ├── ic_launcher_foreground.xml │ │ ├── music_collection.png │ │ ├── note_shape.xml │ │ ├── skin.png │ │ └── tomato.png │ │ ├── drawable │ │ ├── ic_baseline_add_24.xml │ │ ├── ic_baseline_add_circle_outline_24.xml │ │ ├── ic_baseline_create_24.xml │ │ ├── ic_baseline_delete_24.xml │ │ ├── ic_baseline_keyboard_voice_24.xml │ │ ├── ic_baseline_library_music_24.xml │ │ ├── ic_baseline_list_24.xml │ │ ├── ic_baseline_menu_book_24.xml │ │ ├── ic_baseline_search_24.xml │ │ ├── ic_baseline_settings_24.xml │ │ ├── ic_create_24.xml │ │ ├── ic_delete_all_24.xml │ │ ├── ic_error_outline_black_24dp.xml │ │ ├── ic_keyboard_arrow_left_black_24dp.xml │ │ ├── ic_launcher_background.xml │ │ ├── ic_menu_24.xml │ │ ├── ic_menu_black_24dp.xml │ │ ├── ic_notifications_black_24dp.xml │ │ ├── red_alarm_24dp.xml │ │ └── top_button_shap.xml │ │ ├── layout │ │ ├── activity_edit.xml │ │ ├── activity_handwriting.xml │ │ ├── activity_main.xml │ │ ├── edit_alarm_layout.xml │ │ ├── note_layout.xml │ │ ├── plan_layout.xml │ │ ├── setting_cover.xml │ │ ├── setting_layout.xml │ │ └── usersetting_layout.xml │ │ ├── menu │ │ ├── edit_menu.xml │ │ ├── main_menu.xml │ │ └── memo_menu.xml │ │ ├── mipmap-anydpi-v26 │ │ ├── ic_launcher.xml │ │ └── ic_launcher_round.xml │ │ ├── mipmap-hdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-mdpi │ │ ├── ic_launcher.png │ │ ├── ic_launcher_round.png │ │ └── main1.png │ │ ├── mipmap-xhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── raw │ │ ├── be_quiet.mp3 │ │ ├── dream_wedding.mp3 │ │ ├── girly_heart.mp3 │ │ ├── perfect_encounter.mp3 │ │ ├── run.mp3 │ │ └── sword_fairy.mp3 │ │ ├── values-v23 │ │ └── styles.xml │ │ └── values │ │ ├── attr.xml │ │ ├── colors.xml │ │ ├── strings.xml │ │ └── styles.xml │ └── test │ └── java │ └── com │ └── example │ └── notebook │ └── ExampleUnitTest.java ├── build.gradle ├── git ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── settings.gradle └── test.txt /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/caches 5 | /.idea/libraries 6 | /.idea/modules.xml 7 | /.idea/workspace.xml 8 | /.idea/navEditor.xml 9 | /.idea/assetWizardSettings.xml 10 | .DS_Store 11 | /build 12 | /captures 13 | .externalNativeBuild 14 | .cxx 15 | -------------------------------------------------------------------------------- /.idea/codeStyles/Project.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | xmlns:android 14 | 15 | ^$ 16 | 17 | 18 | 19 |
20 |
21 | 22 | 23 | 24 | xmlns:.* 25 | 26 | ^$ 27 | 28 | 29 | BY_NAME 30 | 31 |
32 |
33 | 34 | 35 | 36 | .*:id 37 | 38 | http://schemas.android.com/apk/res/android 39 | 40 | 41 | 42 |
43 |
44 | 45 | 46 | 47 | .*:name 48 | 49 | http://schemas.android.com/apk/res/android 50 | 51 | 52 | 53 |
54 |
55 | 56 | 57 | 58 | name 59 | 60 | ^$ 61 | 62 | 63 | 64 |
65 |
66 | 67 | 68 | 69 | style 70 | 71 | ^$ 72 | 73 | 74 | 75 |
76 |
77 | 78 | 79 | 80 | .* 81 | 82 | ^$ 83 | 84 | 85 | BY_NAME 86 | 87 |
88 |
89 | 90 | 91 | 92 | .* 93 | 94 | http://schemas.android.com/apk/res/android 95 | 96 | 97 | ANDROID_ATTRIBUTE_ORDER 98 | 99 |
100 |
101 | 102 | 103 | 104 | .* 105 | 106 | .* 107 | 108 | 109 | BY_NAME 110 | 111 |
112 |
113 |
114 |
115 |
116 |
-------------------------------------------------------------------------------- /.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/dictionaries/mabeg.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | fabs 5 | 6 | 7 | -------------------------------------------------------------------------------- /.idea/encodings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 21 | 22 | -------------------------------------------------------------------------------- /.idea/jarRepositories.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 9 | 10 | 14 | 15 | 19 | 20 | 24 | 25 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 9 | -------------------------------------------------------------------------------- /.idea/runConfigurations.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 12 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 码不停蹄 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # NoteBook 2 | 3 | [安卓大作业]基于android studio开发的记事本 4 | 5 | 1、 基本功能,可新建、编写、保存、删除日记(必选);
6 | 2、 支持阅读模式(不可编辑)(必选)
7 | 3、 支持插入表情(必选 )
8 | 4、 手写日记功能(可选)
9 | 5、 支持插入背景音乐(必选);
10 | 6、 支持备忘录,设置定时提醒(必选);
11 | 7、 上述功能需要在Android系统上实现演示(必选)。
12 | 13 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 30 5 | buildToolsVersion "30.0.3" 6 | lintOptions { 7 | checkReleaseBuilds false 8 | abortOnError false 9 | } 10 | 11 | defaultConfig { 12 | applicationId "com.example.notebook" 13 | minSdkVersion 21 14 | targetSdkVersion 30 15 | versionCode 1 16 | versionName "1.0" 17 | 18 | testInstrumentationRunner "androidx.run.runner.AndroidJUnitRunner" 19 | } 20 | 21 | buildTypes { 22 | release { 23 | minifyEnabled false 24 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' 25 | } 26 | } 27 | } 28 | 29 | dependencies { 30 | implementation fileTree(dir: "libs", include: ["*.jar"]) 31 | implementation 'androidx.appcompat:appcompat:1.1.0' 32 | implementation 'androidx.constraintlayout:constraintlayout:1.1.3' 33 | implementation 'com.google.android.material:material:1.3.0' 34 | implementation 'androidx.navigation:navigation-fragment:2.2.2' 35 | implementation 'androidx.navigation:navigation-ui:2.2.2' 36 | implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.2.0' 37 | implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.2.0' 38 | testImplementation 'junit:junit:4.12' 39 | androidTestImplementation 'androidx.run.ext:junit:1.1.1' 40 | androidTestImplementation 'androidx.run.espresso:espresso-core:3.2.0' 41 | implementation 'androidx.recyclerview:recyclerview:1.0.0' 42 | implementation 'com.github.bumptech.glide:glide:3.7.0' 43 | implementation 'androidx.preference:preference:1.1.1' 44 | } -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile -------------------------------------------------------------------------------- /app/src/androidTest/java/com/example/notebook/ExampleInstrumentedTest.java: -------------------------------------------------------------------------------- 1 | package com.example.notebook; 2 | 3 | import android.content.Context; 4 | 5 | import androidx.test.platform.app.InstrumentationRegistry; 6 | import androidx.test.ext.junit.runners.AndroidJUnit4; 7 | 8 | import org.junit.Test; 9 | import org.junit.runner.RunWith; 10 | 11 | import static org.junit.Assert.*; 12 | 13 | /** 14 | * Instrumented run, which will execute on an Android device. 15 | * 16 | * @see Testing documentation 17 | */ 18 | @RunWith(AndroidJUnit4.class) 19 | public class ExampleInstrumentedTest { 20 | @Test 21 | public void useAppContext() { 22 | // Context of the app under run. 23 | Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); 24 | assertEquals("com.example.notebook", appContext.getPackageName()); 25 | } 26 | } -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 13 | 14 | 15 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/notebook/Alarm/AlarmActivity.java: -------------------------------------------------------------------------------- 1 | package com.example.notebook.Alarm; 2 | 3 | import android.content.DialogInterface; 4 | import android.content.Intent; 5 | import android.icu.text.SimpleDateFormat; 6 | import android.os.Build; 7 | import android.os.Bundle; 8 | import android.view.Menu; 9 | 10 | import com.example.notebook.BaseActivity; 11 | import com.example.notebook.R; 12 | import java.util.Date; 13 | import androidx.annotation.RequiresApi; 14 | import androidx.appcompat.app.AlertDialog; 15 | 16 | /** 17 | * 闹钟警报类(对话框显示) 18 | */ 19 | public class AlarmActivity extends BaseActivity{ 20 | @RequiresApi(api = Build.VERSION_CODES.N) 21 | @Override 22 | protected void onCreate(Bundle savedInstanceState) { 23 | super.onCreate(savedInstanceState); 24 | new AlertDialog.Builder(AlarmActivity.this) 25 | .setIcon(R.drawable.alarm_24) 26 | .setTitle("闹钟提醒") 27 | .setMessage( 28 | "有待办事项,请您及时查看" 29 | +"\n"+"当前时间为: " 30 | + new SimpleDateFormat("yyyy-MM-dd HH:mm") 31 | .format(new Date())) 32 | .setPositiveButton("我知道了", new DialogInterface.OnClickListener() { 33 | @Override 34 | public void onClick(DialogInterface dialog, int which) { 35 | AlarmActivity.this.finish(); 36 | } 37 | }).show(); 38 | } 39 | 40 | @Override 41 | protected void needRefresh() { 42 | 43 | } 44 | 45 | //菜单 46 | @Override 47 | public boolean onCreateOptionsMenu(Menu menu) { 48 | getMenuInflater().inflate(R.menu.memo_menu,menu); //渲染memo_menu 49 | return super.onCreateOptionsMenu(menu); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/notebook/Alarm/AlarmCrud.java: -------------------------------------------------------------------------------- 1 | package com.example.notebook.Alarm; 2 | 3 | import android.content.ContentValues; 4 | import android.content.Context; 5 | import android.database.Cursor; 6 | import android.database.sqlite.SQLiteDatabase; 7 | import android.database.sqlite.SQLiteOpenHelper; 8 | 9 | import java.util.ArrayList; 10 | import java.util.List; 11 | 12 | public class AlarmCrud { 13 | SQLiteOpenHelper dbHandler; 14 | SQLiteDatabase db; 15 | 16 | private static final String[] columns = { 17 | PlanDatabase.ID, 18 | PlanDatabase.TITLE, 19 | PlanDatabase.CONTENT, 20 | PlanDatabase.TIME, 21 | }; 22 | 23 | public AlarmCrud(Context context){ 24 | dbHandler = new PlanDatabase(context); 25 | } 26 | 27 | public void open(){ 28 | db = dbHandler.getWritableDatabase(); 29 | } 30 | 31 | public void close(){ 32 | dbHandler.close(); 33 | } 34 | 35 | public Plan addPlan(Plan plan){ 36 | //add a plan object to database 37 | ContentValues contentValues = new ContentValues(); 38 | contentValues.put(PlanDatabase.TITLE, plan.getTitle()); 39 | contentValues.put(PlanDatabase.CONTENT, plan.getContent()); 40 | contentValues.put(PlanDatabase.TIME, plan.getTime()); 41 | long insertId = db.insert(PlanDatabase.TABLE_NAME, null, contentValues); 42 | plan.setId(insertId); 43 | return plan; 44 | } 45 | 46 | public Plan getPlan(long id){ 47 | //get a plan from database using cursor index 48 | Cursor cursor = db.query(PlanDatabase.TABLE_NAME,columns,PlanDatabase.ID + "=?", 49 | new String[]{String.valueOf(id)},null,null, null, null); 50 | if (cursor != null) cursor.moveToFirst(); 51 | Plan e = new Plan(cursor.getString(1),cursor.getString(2), cursor.getString(3)); 52 | return e; 53 | } 54 | 55 | public List getAllPlans(){ 56 | Cursor cursor = db.query(PlanDatabase.TABLE_NAME,columns,null,null,null, null, null); 57 | 58 | List plans = new ArrayList<>(); 59 | if(cursor.getCount() > 0){ 60 | while(cursor.moveToNext()){ 61 | Plan plan = new Plan(); 62 | plan.setId(cursor.getLong(cursor.getColumnIndex(PlanDatabase.ID))); 63 | plan.setTitle(cursor.getString(cursor.getColumnIndex(PlanDatabase.TITLE))); 64 | plan.setContent(cursor.getString(cursor.getColumnIndex(PlanDatabase.CONTENT))); 65 | plan.setTime(cursor.getString(cursor.getColumnIndex(PlanDatabase.TIME))); 66 | plans.add(plan); 67 | } 68 | } 69 | return plans; 70 | } 71 | 72 | public int updatePlan(Plan plan) { 73 | //update the info of an existing plan 74 | ContentValues values = new ContentValues(); 75 | values.put(PlanDatabase.TITLE, plan.getTitle()); 76 | values.put(PlanDatabase.CONTENT, plan.getContent()); 77 | values.put(PlanDatabase.TIME, plan.getTime()); 78 | // updating row 79 | return db.update(PlanDatabase.TABLE_NAME, values, 80 | PlanDatabase.ID + "=?",new String[] { String.valueOf(plan.getId())}); 81 | } 82 | 83 | public void removePlan(Plan plan) { 84 | //remove a plan according to ID value 85 | db.delete(PlanDatabase.TABLE_NAME, PlanDatabase.ID + "=" + plan.getId(), null); 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/notebook/Alarm/AlarmReceiver.java: -------------------------------------------------------------------------------- 1 | package com.example.notebook.Alarm; 2 | 3 | import android.content.BroadcastReceiver; 4 | import android.content.Context; 5 | import android.content.Intent; 6 | 7 | public class AlarmReceiver extends BroadcastReceiver { 8 | @Override 9 | public void onReceive(Context context, Intent intent) { 10 | Intent intent1=new Intent(context,AlarmActivity.class); 11 | intent1.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 12 | context.startActivity(intent1); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/notebook/Alarm/EditAlarmActivity.java: -------------------------------------------------------------------------------- 1 | package com.example.notebook.Alarm; 2 | 3 | import android.app.DatePickerDialog; 4 | import android.app.TimePickerDialog; 5 | import android.content.DialogInterface; 6 | import android.content.Intent; 7 | import android.os.Bundle; 8 | import android.util.Log; 9 | import android.view.KeyEvent; 10 | import android.view.Menu; 11 | import android.view.MenuItem; 12 | import android.view.View; 13 | import android.widget.Button; 14 | import android.widget.DatePicker; 15 | import android.widget.EditText; 16 | import android.widget.TextView; 17 | import android.widget.TimePicker; 18 | import android.widget.Toast; 19 | import com.example.notebook.BaseActivity; 20 | import com.example.notebook.R; 21 | import java.util.Calendar; 22 | import java.util.Objects; 23 | 24 | import androidx.annotation.Nullable; 25 | import androidx.appcompat.app.AlertDialog; 26 | import androidx.appcompat.widget.Toolbar; 27 | 28 | public class EditAlarmActivity extends BaseActivity implements View.OnClickListener { 29 | 30 | private DatePickerDialog.OnDateSetListener dateSetListener; 31 | private TimePickerDialog.OnTimeSetListener timeSetListener; 32 | private EditText et_title; 33 | private EditText et; 34 | private Button set_date; 35 | private Button set_time; 36 | 37 | private TextView date; 38 | private TextView time; 39 | private Plan plan; 40 | private int[] dateArray = new int[3]; 41 | private int[] timeArray = new int[2]; 42 | 43 | private int openMode = 0; 44 | private String old_title = ""; 45 | private String old_content = ""; 46 | private String old_time = ""; 47 | private long id = 0; 48 | private boolean timeChange = false; 49 | 50 | @Override 51 | public boolean onCreateOptionsMenu(Menu menu) { 52 | getMenuInflater().inflate(R.menu.memo_menu, menu); 53 | return super.onCreateOptionsMenu(menu); 54 | } 55 | 56 | @Override 57 | protected void onCreate(@Nullable Bundle savedInstanceState) { 58 | super.onCreate(savedInstanceState); 59 | setContentView(R.layout.edit_alarm_layout); 60 | Toolbar myToolbar = findViewById(R.id.my_toolbar); 61 | setSupportActionBar(myToolbar); 62 | Objects.requireNonNull(getSupportActionBar()).setHomeButtonEnabled(true); 63 | getSupportActionBar().setDisplayHomeAsUpEnabled(true); 64 | 65 | init(); 66 | 67 | final Intent intent = getIntent(); 68 | openMode = intent.getExtras().getInt("mode", 0); 69 | if(openMode == 1){ 70 | id = intent.getLongExtra("id", 0); 71 | old_title = intent.getStringExtra("title"); 72 | old_content = intent.getStringExtra("content"); 73 | old_time = intent.getStringExtra("time"); 74 | et_title.setText(old_title); 75 | et_title.setSelection(old_title.length()); 76 | et.setText(old_content); 77 | et.setSelection(old_content.length()); 78 | 79 | String[] wholeTime = old_time.split(" "); 80 | String[] temp = wholeTime[0].split("-"); 81 | String[] temp1 = wholeTime[1].split(":"); 82 | setDateTV(Integer.parseInt(temp[0]), Integer.parseInt(temp[1]), Integer.parseInt(temp[2])); 83 | setTimeTV(Integer.parseInt(temp1[0]), Integer.parseInt(temp1[1])); 84 | } 85 | myToolbar.setNavigationIcon(getDrawable(R.drawable.ic_keyboard_arrow_left_black_24dp)); 86 | 87 | myToolbar.setNavigationOnClickListener(new View.OnClickListener() { 88 | @Override 89 | public void onClick(View v) { 90 | if(!canBeSet()) { 91 | Toast.makeText(com.example.notebook.Alarm.EditAlarmActivity.this, "无效的时间", Toast.LENGTH_SHORT).show(); 92 | }else if(et.getText().toString().length() + et_title.getText().toString().length() == 0 && openMode == 2){ 93 | Intent intent1 = new Intent(); 94 | intent1.putExtra("mode", -1);//nothing new happens. 95 | setResult(RESULT_OK, intent1); 96 | finish();//返回 97 | overridePendingTransition(R.anim.in_lefttoright, R.anim.out_lefttoright); 98 | } 99 | else if (et_title.getText().toString().length() == 0) { 100 | Toast.makeText(com.example.notebook.Alarm.EditAlarmActivity.this, "标题不能为空", Toast.LENGTH_SHORT).show(); 101 | } 102 | else { 103 | isTimeChange(); 104 | Intent intent = new Intent(); 105 | if (openMode == 2) { 106 | intent.putExtra("mode", 10); // 新的备忘录; 107 | intent.putExtra("title", et_title.getText().toString()); 108 | intent.putExtra("content", et.getText().toString()); 109 | intent.putExtra("time", date.getText().toString() + " " + time.getText().toString()); 110 | Log.d(TAG, date.getText().toString() + time.getText().toString()); 111 | } else { 112 | if (et.getText().toString().equals(old_content) && et_title.getText().toString().equals(old_title) && !timeChange) { 113 | intent.putExtra("mode", -1); // 没有编辑 114 | } 115 | else { 116 | intent.putExtra("mode", 11); //编辑内容 117 | intent.putExtra("title", et_title.getText().toString()); 118 | intent.putExtra("content", et.getText().toString()); 119 | intent.putExtra("time", date.getText().toString() + " " + time.getText().toString()); 120 | intent.putExtra("id", id); 121 | } 122 | } 123 | setResult(RESULT_OK, intent); 124 | finish();//返回 125 | overridePendingTransition(R.anim.in_lefttoright, R.anim.out_lefttoright); 126 | } 127 | } 128 | }); 129 | 130 | } 131 | 132 | public boolean onKeyDown(int keyCode, KeyEvent event) { 133 | if( keyCode== KeyEvent.KEYCODE_HOME){ 134 | return true; 135 | } else if( keyCode== KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_DOWN){ 136 | if(!canBeSet()) { 137 | Toast.makeText(com.example.notebook.Alarm.EditAlarmActivity.this, "Invalid Time", Toast.LENGTH_SHORT).show(); 138 | }else if(et.getText().toString().length() + et_title.getText().toString().length() == 0 && openMode == 2){ 139 | Intent intent1 = new Intent(); 140 | intent1.putExtra("mode", -1);//nothing new happens. 141 | setResult(RESULT_OK, intent1); 142 | finish();//返回 143 | overridePendingTransition(R.anim.in_lefttoright, R.anim.out_lefttoright); 144 | } 145 | else if (et_title.getText().toString().length() == 0) { 146 | Toast.makeText(com.example.notebook.Alarm.EditAlarmActivity.this, "标题不能为空!", Toast.LENGTH_SHORT).show(); 147 | } 148 | else { 149 | isTimeChange(); 150 | Intent intent = new Intent(); 151 | if (openMode == 2) { 152 | intent.putExtra("mode", 10); // 一个新的备忘录 153 | intent.putExtra("title", et_title.getText().toString()); 154 | intent.putExtra("content", et.getText().toString()); 155 | intent.putExtra("time", date.getText().toString() + " " + time.getText().toString()); 156 | Log.d(TAG, date.getText().toString() + time.getText().toString()); 157 | } else { 158 | if (et.getText().toString().equals(old_content) && et_title.getText().toString().equals(old_title) && !timeChange) { 159 | intent.putExtra("mode", -1); //没有编辑 160 | } 161 | else { 162 | intent.putExtra("mode", 11); //编辑内容 163 | intent.putExtra("title", et_title.getText().toString()); 164 | intent.putExtra("content", et.getText().toString()); 165 | intent.putExtra("time", date.getText().toString() + " " + time.getText().toString()); 166 | intent.putExtra("id", id); 167 | } 168 | } 169 | setResult(RESULT_OK, intent); 170 | finish();//返回 171 | overridePendingTransition(R.anim.in_lefttoright, R.anim.out_lefttoright); 172 | } 173 | } 174 | return super.onKeyDown(keyCode, event); 175 | } 176 | 177 | @Override 178 | public boolean onOptionsItemSelected(MenuItem item) { 179 | final Intent intent = new Intent(); 180 | switch (item.getItemId()){ 181 | case R.id.delete: 182 | new AlertDialog.Builder(com.example.notebook.Alarm.EditAlarmActivity.this) 183 | .setMessage("确定删除这条备忘录?") 184 | .setPositiveButton("确定", new DialogInterface.OnClickListener() { 185 | @Override 186 | public void onClick(DialogInterface dialog, int which) { 187 | if(openMode == 2){ 188 | intent.putExtra("mode", -1); // delete the plan 189 | setResult(RESULT_OK, intent); 190 | } 191 | else { 192 | intent.putExtra("mode", 12); // delete the plan 193 | intent.putExtra("id", id); 194 | setResult(RESULT_OK, intent); 195 | } 196 | finish(); 197 | } 198 | }).setNegativeButton("取消", new DialogInterface.OnClickListener() { 199 | @Override 200 | public void onClick(DialogInterface dialog, int which) { 201 | dialog.dismiss(); 202 | } 203 | }).create().show(); 204 | break; 205 | } 206 | return super.onOptionsItemSelected(item); 207 | } 208 | 209 | @Override 210 | protected void needRefresh() { 211 | setTheme(R.style.AppTheme); 212 | startActivity(new Intent(this, com.example.notebook.Alarm.EditAlarmActivity.class)); 213 | overridePendingTransition(R.anim.night_switch, R.anim.night_switch_over); 214 | finish(); 215 | } 216 | 217 | private void init(){ 218 | plan = new Plan(); 219 | dateArray[0] = plan.getYear(); 220 | dateArray[1] = plan.getMonth() + 1; 221 | dateArray[2] = plan.getDay(); 222 | timeArray[0] = plan.getHour(); 223 | timeArray[1] = plan.getMinute(); 224 | et_title = findViewById(R.id.et_title); 225 | et = findViewById(R.id.et); 226 | set_date = findViewById(R.id.set_date); 227 | set_time = findViewById(R.id.set_time); 228 | date = findViewById(R.id.date); 229 | time = findViewById(R.id.time); 230 | 231 | //初始化两个textView 232 | setDateTV(dateArray[0], dateArray[1], dateArray[2]); 233 | setTimeTV((timeArray[1]>54? timeArray[0]+1 : timeArray[0]), (timeArray[1]+5)%60); 234 | Log.d(TAG, "init: "+dateArray[1]); 235 | 236 | set_date.setOnClickListener(this); 237 | set_time.setOnClickListener(this); 238 | 239 | dateSetListener = new DatePickerDialog.OnDateSetListener() { 240 | @Override 241 | public void onDateSet(DatePicker view, int year, int month, int dayOfMonth) { 242 | setDateTV(year, month+1, dayOfMonth); 243 | 244 | } 245 | }; 246 | timeSetListener = new TimePickerDialog.OnTimeSetListener() { 247 | @Override 248 | public void onTimeSet(TimePicker view, int hourOfDay, int minute) { 249 | setTimeTV(hourOfDay, minute); 250 | } 251 | }; 252 | } 253 | 254 | private void setDateTV(int y, int m, int d){ 255 | //更新tv和dateArray 256 | String temp = y + "-"; 257 | if(m<10) temp += "0"; 258 | temp += (m + "-"); 259 | if(d<10) temp +="0"; 260 | temp += d; 261 | date.setText(temp); 262 | dateArray[0] = y; 263 | dateArray[1] = m; 264 | dateArray[2] = d; 265 | } 266 | 267 | private void setTimeTV(int h, int m){ 268 | String temp = ""; 269 | if(h<10) temp += "0"; 270 | temp += (h + ":"); 271 | if(m<10) temp += "0"; 272 | temp += m; 273 | time.setText(temp); 274 | timeArray[0] = h; 275 | timeArray[1] = m; 276 | } 277 | 278 | @Override 279 | public void onClick(View v) { 280 | switch (v.getId()){ 281 | case R.id.set_date: //选择日期 282 | DatePickerDialog dialog = new DatePickerDialog(com.example.notebook.Alarm.EditAlarmActivity.this, 283 | R.style.DayDialogTheme, dateSetListener, 284 | dateArray[0], dateArray[1] - 1, dateArray[2]); 285 | dialog.show(); 286 | break; 287 | case R.id.set_time://选择时间 288 | TimePickerDialog dialog1 = new TimePickerDialog(com.example.notebook.Alarm.EditAlarmActivity.this, 289 | R.style.DayDialogTheme, timeSetListener, 290 | timeArray[0], timeArray[1], true); 291 | dialog1.show(); 292 | break; 293 | } 294 | } 295 | 296 | private void isTimeChange(){ 297 | String newTime = date.getText().toString() + " " + time.getText().toString(); 298 | if(!newTime.equals(old_time)) timeChange = true; 299 | } 300 | 301 | private boolean canBeSet(){ 302 | Calendar calendar = Calendar.getInstance(); 303 | calendar.set(dateArray[0], dateArray[1] - 1, dateArray[2], timeArray[0], timeArray[1]); 304 | Calendar cur = Calendar.getInstance(); 305 | Log.d(TAG, "canBeSet: " + cur.getTime().toString() + calendar.getTime().toString()); 306 | if(cur.before(calendar)) return true; 307 | else { 308 | Toast.makeText(this, "请设置正确的时间", Toast.LENGTH_SHORT).show(); 309 | return false; 310 | } 311 | } 312 | } 313 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/notebook/Alarm/Plan.java: -------------------------------------------------------------------------------- 1 | package com.example.notebook.Alarm; 2 | 3 | import android.util.Log; 4 | 5 | import java.text.ParseException; 6 | import java.text.SimpleDateFormat; 7 | import java.util.Calendar; 8 | import java.util.Date; 9 | 10 | public class Plan { 11 | private long id; 12 | private String title; 13 | private String content; 14 | private Calendar planTime; 15 | 16 | 17 | public Plan(String title, String content, String planTime) { 18 | this.title = title; 19 | this.content = content; 20 | setTime(planTime); 21 | } 22 | 23 | public Plan(){ 24 | this.planTime = Calendar.getInstance(); 25 | } 26 | 27 | public int getYear(){ 28 | return planTime.get(Calendar.YEAR); 29 | } 30 | 31 | public int getMonth(){ 32 | return planTime.get(Calendar.MONTH); 33 | } 34 | 35 | public int getDay() { 36 | return planTime.get(Calendar.DAY_OF_MONTH); 37 | } 38 | 39 | public int getHour() { 40 | return planTime.get(Calendar.HOUR_OF_DAY); 41 | } 42 | 43 | public int getMinute() { 44 | return planTime.get(Calendar.MINUTE); 45 | } 46 | 47 | public long getId() { 48 | return id; 49 | } 50 | 51 | public void setId(long id) { 52 | this.id = id; 53 | } 54 | 55 | public String getTitle() { 56 | return title; 57 | } 58 | 59 | public void setTitle(String title) { 60 | this.title = title; 61 | } 62 | 63 | public String getContent() { 64 | return content; 65 | } 66 | 67 | public void setContent(String content) { 68 | this.content = content; 69 | } 70 | 71 | public Calendar getPlanTime() { 72 | return planTime; 73 | } 74 | 75 | public String getTime(){ 76 | SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm"); 77 | return simpleDateFormat.format(planTime.getTime()); 78 | } 79 | public void setTime(String format){ 80 | SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm"); 81 | try { 82 | Date temp = simpleDateFormat.parse(format); 83 | Log.d("shit", ""+temp); 84 | planTime = Calendar.getInstance(); 85 | planTime.setTime(temp); 86 | } catch (ParseException e) { 87 | 88 | } 89 | } 90 | 91 | } 92 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/notebook/Alarm/PlanAdapter.java: -------------------------------------------------------------------------------- 1 | package com.example.notebook.Alarm; 2 | 3 | import android.content.Context; 4 | import android.text.TextUtils; 5 | import android.view.View; 6 | import android.view.ViewGroup; 7 | import android.widget.BaseAdapter; 8 | import android.widget.Filter; 9 | import android.widget.Filterable; 10 | import android.widget.TextView; 11 | 12 | import com.example.notebook.R; 13 | 14 | import java.util.ArrayList; 15 | import java.util.List; 16 | 17 | public class PlanAdapter extends BaseAdapter implements Filterable { 18 | private Context mContext; 19 | 20 | private List backList;//用来备份原始数据 21 | private List planList;//这个数据是会改变的,所以要有个变量来备份一下原始数据 22 | com.example.notebook.Alarm.PlanAdapter.MyFilter mFilter; 23 | 24 | public PlanAdapter(Context mContext, List planList) { 25 | this.mContext = mContext; 26 | this.planList = planList; 27 | backList = planList; 28 | } 29 | 30 | @Override 31 | public int getCount() { 32 | return planList.size(); 33 | } 34 | 35 | @Override 36 | public Object getItem(int position) { 37 | return planList.get(position); 38 | } 39 | 40 | @Override 41 | public long getItemId(int position) { 42 | return position; 43 | } 44 | 45 | @Override 46 | public View getView(int position, View convertView, ViewGroup parent) { 47 | mContext.setTheme(R.style.AppTheme); 48 | View v = View.inflate(mContext, R.layout.plan_layout, null); 49 | TextView tv_title = v.findViewById(R.id.tv_title); 50 | TextView tv_content = v.findViewById(R.id.tv_content); 51 | TextView tv_time = v.findViewById(R.id.tv_time); 52 | 53 | //设置内容->TextView 54 | tv_title.setText(planList.get(position).getTitle()); 55 | tv_content.setText(planList.get(position).getContent()); 56 | tv_time.setText(planList.get(position).getTime()); 57 | 58 | //保存内容->tag 59 | v.setTag(planList.get(position).getId()); 60 | 61 | return v; 62 | } 63 | 64 | @Override 65 | public Filter getFilter() { 66 | if (mFilter ==null){ 67 | mFilter = new com.example.notebook.Alarm.PlanAdapter.MyFilter(); 68 | } 69 | return mFilter; 70 | } 71 | 72 | 73 | class MyFilter extends Filter { 74 | //在performFiltering(CharSequence charSequence)这个方法中定义过滤规则 75 | @Override 76 | protected FilterResults performFiltering(CharSequence charSequence) { 77 | FilterResults result = new FilterResults(); 78 | List list; 79 | if (TextUtils.isEmpty(charSequence)) {//当过滤的关键字为空的时候,我们则显示所有的数据 80 | list = backList; 81 | } else {//否则把符合条件的数据对象添加到集合中 82 | list = new ArrayList<>(); 83 | for (Plan plan : backList) { 84 | if (plan.getTitle().contains(charSequence) || plan.getContent().contains(charSequence)) { 85 | list.add(plan); 86 | } 87 | 88 | } 89 | } 90 | result.values = list; //将得到的集合保存到FilterResults的value变量中 91 | result.count = list.size();//将集合的大小保存到FilterResults的count变量中 92 | 93 | return result; 94 | } 95 | //在publishResults方法中告诉适配器更新界面 96 | @Override 97 | protected void publishResults(CharSequence charSequence, FilterResults filterResults) { 98 | planList = (List)filterResults.values; 99 | if (filterResults.count>0){ 100 | notifyDataSetChanged();//通知数据发生了改变 101 | }else { 102 | notifyDataSetInvalidated();//通知数据失效 103 | } 104 | } 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/notebook/Alarm/PlanDatabase.java: -------------------------------------------------------------------------------- 1 | package com.example.notebook.Alarm; 2 | 3 | import android.content.Context; 4 | import android.database.sqlite.SQLiteDatabase; 5 | import android.database.sqlite.SQLiteOpenHelper; 6 | 7 | public class PlanDatabase extends SQLiteOpenHelper { 8 | 9 | public static final String TABLE_NAME = "plans"; 10 | public static final String TITLE = "title"; 11 | public static final String CONTENT = "content"; 12 | public static final String ID = "_id"; 13 | public static final String TIME = "time"; 14 | public static final String MODE = "mode"; 15 | 16 | 17 | public PlanDatabase(Context context){ 18 | super(context, "plans", null, 1); 19 | } 20 | 21 | @Override 22 | public void onCreate(SQLiteDatabase db) { 23 | db.execSQL("CREATE TABLE "+ TABLE_NAME 24 | + "(" 25 | + ID + " INTEGER PRIMARY KEY AUTOINCREMENT," 26 | + TITLE + " TEXT NOT NULL," 27 | + CONTENT + " TEXT," 28 | + TIME + " TEXT NOT NULL)" 29 | ); 30 | } 31 | 32 | @Override 33 | public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { 34 | 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/notebook/BaseActivity.java: -------------------------------------------------------------------------------- 1 | package com.example.notebook; 2 | 3 | import android.os.Bundle; 4 | import androidx.appcompat.app.AppCompatActivity; 5 | 6 | public abstract class BaseActivity extends AppCompatActivity { 7 | public final String TAG = "BaseActivity"; 8 | @Override 9 | protected void onCreate(Bundle savedInstanceState){ 10 | super.onCreate(savedInstanceState); 11 | setTheme(R.style.AppTheme); 12 | } 13 | 14 | protected abstract void needRefresh(); 15 | } -------------------------------------------------------------------------------- /app/src/main/java/com/example/notebook/BaseCrud.java: -------------------------------------------------------------------------------- 1 | package com.example.notebook; 2 | 3 | import android.content.ContentValues; 4 | import android.content.Context; 5 | import android.database.Cursor; 6 | import android.database.sqlite.SQLiteDatabase; 7 | import android.database.sqlite.SQLiteOpenHelper; 8 | 9 | import java.util.ArrayList; 10 | import java.util.List; 11 | 12 | public class BaseCrud { 13 | SQLiteOpenHelper dbHandler; 14 | SQLiteDatabase db; 15 | 16 | private static final String[] columns = { 17 | NoteDatabase.ID, 18 | NoteDatabase.CONTENT, 19 | NoteDatabase.TIME, 20 | NoteDatabase.MODE 21 | }; 22 | 23 | public BaseCrud(Context context){ 24 | dbHandler = new NoteDatabase(context); 25 | } 26 | 27 | public void open(){ 28 | db = dbHandler.getWritableDatabase(); 29 | } 30 | 31 | public void close(){ 32 | dbHandler.close(); 33 | } 34 | 35 | //加入内容到数据库的列 36 | public Note addNote(Note note){ 37 | ContentValues contentValues = new ContentValues(); 38 | contentValues.put(NoteDatabase.CONTENT, note.getContent()); 39 | contentValues.put(NoteDatabase.TIME, note.getTime()); 40 | contentValues.put(NoteDatabase.MODE, note.getTag()); 41 | long insertId = db.insert(NoteDatabase.TABLE_NAME, null, contentValues); 42 | note.setId(insertId); 43 | return note; 44 | } 45 | 46 | public Note getNote(long id){ 47 | Cursor cursor = db.query(NoteDatabase.TABLE_NAME,columns,NoteDatabase.ID + "=?", 48 | new String[]{String.valueOf(id)},null,null, null, null); 49 | if (cursor != null) cursor.moveToFirst(); 50 | Note e = new Note(cursor.getString(1),cursor.getString(2), cursor.getInt(3)); 51 | return e; 52 | } 53 | 54 | 55 | public List getAllNotes(){ 56 | Cursor cursor = db.query(NoteDatabase.TABLE_NAME,columns,null,null,null, null, null); 57 | 58 | List notes = new ArrayList<>(); 59 | if(cursor.getCount() > 0){ 60 | while(cursor.moveToNext()){ 61 | Note note = new Note(); 62 | note.setId(cursor.getLong(cursor.getColumnIndex(NoteDatabase.ID))); 63 | note.setContent(cursor.getString(cursor.getColumnIndex(NoteDatabase.CONTENT))); 64 | note.setTime(cursor.getString(cursor.getColumnIndex(NoteDatabase.TIME))); 65 | note.setTag(cursor.getInt(cursor.getColumnIndex(NoteDatabase.MODE))); 66 | notes.add(note); 67 | } 68 | } 69 | return notes; 70 | } 71 | public int updateNote(Note note) { 72 | ContentValues values = new ContentValues(); 73 | values.put(NoteDatabase.CONTENT, note.getContent()); 74 | values.put(NoteDatabase.TIME, note.getTime()); 75 | values.put(NoteDatabase.MODE, note.getTag()); 76 | return db.update(NoteDatabase.TABLE_NAME, values, 77 | NoteDatabase.ID + "=?",new String[] { String.valueOf(note.getId())}); 78 | } 79 | 80 | public void removeNote(Note note) { 81 | db.delete(NoteDatabase.TABLE_NAME, NoteDatabase.ID + "=" + note.getId(), null); 82 | } 83 | 84 | } 85 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/notebook/EditActivity.java: -------------------------------------------------------------------------------- 1 | package com.example.notebook; 2 | 3 | import androidx.appcompat.app.AlertDialog; 4 | import androidx.appcompat.widget.Toolbar; 5 | 6 | import android.annotation.SuppressLint; 7 | import android.content.Context; 8 | import android.content.DialogInterface; 9 | import android.content.Intent; 10 | import android.graphics.PorterDuff; 11 | import android.graphics.drawable.Drawable; 12 | import android.os.Bundle; 13 | import android.view.KeyEvent; 14 | import android.view.Menu; 15 | import android.view.MenuItem; 16 | import android.view.View; 17 | import android.view.inputmethod.InputMethodManager; 18 | import android.widget.Button; 19 | import android.widget.EditText; 20 | import android.widget.Toast; 21 | 22 | import com.example.notebook.HandWriting.HandwritingActivity; 23 | 24 | import java.text.SimpleDateFormat; 25 | import java.util.Date; 26 | 27 | public class EditActivity extends BaseActivity { 28 | 29 | private EditText editText; 30 | private String old_content = ""; 31 | private String old_time = ""; 32 | private int old_Tag = 1; 33 | private long id = 0; 34 | private int openMode = 0; 35 | private int tag = 1; 36 | public Intent intent = new Intent(); //信息的发送 37 | private boolean tagChange = false; 38 | private Toolbar myToolbar; 39 | private boolean isRead; 40 | Toast toast1, toast2; 41 | private Intent intentMusic; 42 | private int[] curColor = { 43 | R.color.blackColor, 44 | R.color.Violet, 45 | R.color.DoderBlue, 46 | R.color.Auqamarin, 47 | R.color.HotPink, 48 | R.color.white}; 49 | 50 | @Override 51 | protected void onCreate(Bundle savedInstanceState) { 52 | super.onCreate(savedInstanceState); 53 | setContentView(R.layout.activity_edit); 54 | 55 | //跳转到手写页面 56 | Button handBtn = findViewById(R.id.edit_btn1); 57 | handBtn.setOnClickListener(new View.OnClickListener() { 58 | @Override 59 | public void onClick(View v) { 60 | Intent intent=new Intent(EditActivity.this, HandwritingActivity.class); 61 | startActivity(intent); 62 | } 63 | }); 64 | 65 | Button emojiBtn = findViewById(R.id.edit_btn2); 66 | emojiBtn.setOnClickListener(new View.OnClickListener() { 67 | @Override 68 | public void onClick(View v) { 69 | final String emojiArr[]=new String[78]; 70 | for(int i=0;i<78;i++) 71 | { 72 | emojiArr[i]= new String(Character.toChars(128513+i)); 73 | } 74 | AlertDialog.Builder builder =new AlertDialog.Builder(EditActivity.this); 75 | //builder.setIcon(R.drawable.ic_launcher_foreground); 76 | builder.setTitle("选择你喜欢的表情:"); 77 | builder.setItems(emojiArr, new DialogInterface.OnClickListener() { //设置监听 78 | @Override 79 | public void onClick(DialogInterface dialog, int which) { 80 | String string = editText.getText().toString(); 81 | string=string + emojiArr[which]; 82 | editText.setText(string); 83 | } 84 | }); 85 | builder.create().show(); //创建、显示对话框 86 | } 87 | 88 | }); 89 | 90 | toast1=Toast.makeText(getApplicationContext(), "您已进入阅读模式", Toast.LENGTH_SHORT); 91 | toast2=Toast.makeText(getApplicationContext(), "您已进入编辑模式", Toast.LENGTH_SHORT); 92 | isRead = false; 93 | 94 | editText = findViewById(R.id.et); 95 | myToolbar=findViewById(R.id.myToolbar); 96 | 97 | 98 | //编辑界面的头部 99 | setSupportActionBar(myToolbar); 100 | getSupportActionBar().setHomeButtonEnabled(true); 101 | getSupportActionBar().setDisplayHomeAsUpEnabled(true); 102 | 103 | //实现返回主界面 104 | myToolbar.setNavigationOnClickListener(new View.OnClickListener() { 105 | @Override 106 | public void onClick(View v) { 107 | autoSetMessage(); 108 | setResult(RESULT_OK, intent); 109 | finish(); 110 | } 111 | }); 112 | 113 | //返回编辑内容的相关操作 114 | Intent getIntent = getIntent(); 115 | openMode = getIntent.getIntExtra("mode", 0); 116 | 117 | if (openMode == 3) {//打开已存在的note 118 | id = getIntent.getLongExtra("id", 0); 119 | old_content = getIntent.getStringExtra("content"); 120 | old_time = getIntent.getStringExtra("time"); 121 | old_Tag = getIntent.getIntExtra("tag", 1); 122 | editText.setText(old_content); 123 | editText.setSelection(old_content.length()); 124 | } 125 | 126 | //获取保存的背景色 127 | getWindow().setBackgroundDrawableResource(curColor[MainActivity.curId]); 128 | } 129 | 130 | @Override 131 | protected void needRefresh() { 132 | setTheme(R.style.AppTheme); 133 | startActivity(new Intent(this, EditActivity.class)); 134 | overridePendingTransition(R.anim.night_switch, R.anim.night_switch_over); 135 | finish(); 136 | } 137 | 138 | //返回编辑页并保存内容 139 | @Override 140 | public boolean onKeyDown(int keyCode, KeyEvent event) { 141 | if (keyCode == KeyEvent.KEYCODE_HOME) { 142 | return true; 143 | } else if (keyCode == KeyEvent.KEYCODE_BACK) { 144 | autoSetMessage(); 145 | setResult(RESULT_OK, intent); 146 | finish(); 147 | return true; 148 | } 149 | stopService(intentMusic); 150 | return super.onKeyDown(keyCode, event); 151 | } 152 | 153 | //菜单 154 | @Override 155 | public boolean onCreateOptionsMenu(Menu menu) { 156 | getMenuInflater().inflate(R.menu.edit_menu,menu); //渲染edit_menu 157 | return super.onCreateOptionsMenu(menu); 158 | } 159 | 160 | //完成删除功能、换肤功能 161 | @SuppressLint("ResourceAsColor") 162 | @Override 163 | public boolean onOptionsItemSelected(MenuItem item) { 164 | final String[] colors={"护眼色", "紫罗兰", "道奇蓝","碧绿色","热情粉","纯白色"}; 165 | final String[] musics={"奔跑吧","梦中的婚礼","安静","少女的心","剑仙","完美的邂逅"}; 166 | 167 | switch (item.getItemId()){ 168 | case R.id.delete: 169 | new AlertDialog.Builder(EditActivity.this) 170 | .setMessage("确定删除当前便签吗?") 171 | .setPositiveButton("确定", new DialogInterface.OnClickListener() { 172 | @Override 173 | public void onClick(DialogInterface dialog, int which) { 174 | if(openMode==4){ 175 | intent.putExtra("mode",-1); //新笔记,返回-1,什么也不做 176 | }else { 177 | intent.putExtra("mode",2); //已经存在的笔记,用于返回操作 178 | intent.putExtra("id",id); 179 | } 180 | setResult(RESULT_OK,intent); 181 | finish(); 182 | } 183 | }).setNegativeButton("取消", new DialogInterface.OnClickListener() { 184 | @Override 185 | public void onClick(DialogInterface dialog, int which) { 186 | dialog.dismiss(); 187 | } 188 | }).create().show(); 189 | break; 190 | case R.id.read: 191 | Drawable drawable = item.getIcon(); //图标颜色变换 192 | if(isRead){ 193 | drawable.setColorFilter(null); //消除上一级的改变 194 | drawable.setColorFilter(getResources().getColor(R.color.greyC), PorterDuff.Mode.SRC_IN); 195 | toast1.setText("您已进入编辑模式"); 196 | toast2.show(); 197 | editText.setFocusableInTouchMode(true); 198 | editText.setFocusable(true); 199 | isRead = false; 200 | }else{ 201 | drawable.setColorFilter(null); 202 | drawable.setColorFilter(getResources().getColor(R.color.p), PorterDuff.Mode.SRC_IN); 203 | toast1.setText("您已进入阅读模式"); 204 | toast1.show(); 205 | InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); 206 | imm.hideSoftInputFromWindow(editText.getWindowToken(), 0); 207 | editText.setFocusableInTouchMode(false); 208 | editText.setFocusable(false); 209 | isRead = true; 210 | } 211 | break; 212 | case R.id.change: 213 | new AlertDialog.Builder(EditActivity.this) 214 | .setTitle("选择一个背景色") 215 | .setIcon(R.drawable.tomato) 216 | .setItems(colors, new DialogInterface.OnClickListener() { 217 | @Override 218 | public void onClick(DialogInterface dialog, int which) { 219 | switch (which){ 220 | case 0: 221 | MainActivity.curId = 0; 222 | break; 223 | case 1: 224 | MainActivity.curId = 1; 225 | break; 226 | case 2: 227 | MainActivity.curId = 2; 228 | break; 229 | case 3: 230 | MainActivity.curId = 3; 231 | break; 232 | case 4: 233 | MainActivity.curId = 4; 234 | break; 235 | case 5: 236 | MainActivity.curId = 5; 237 | break; 238 | default: 239 | break; 240 | } 241 | getWindow().setBackgroundDrawableResource(curColor[MainActivity.curId]); 242 | } 243 | }).create().show(); 244 | break; 245 | case R.id.music: 246 | new AlertDialog.Builder(EditActivity.this) 247 | .setTitle("选择一个背景音乐") 248 | .setIcon(R.drawable.music_collection) 249 | .setItems(musics, new DialogInterface.OnClickListener() { 250 | @Override 251 | public void onClick(DialogInterface dialog, int which) { 252 | switch (which){ 253 | case 0: 254 | // 启动服务播放背景音乐 255 | intentMusic = new Intent(EditActivity.this, MyIntentService.class); 256 | String action_1 = MyIntentService.ACTION_MUSIC_1; 257 | // 设置action 258 | intentMusic.setAction(action_1); 259 | startService(intentMusic); 260 | break; 261 | case 1: 262 | // 启动服务播放背景音乐 263 | intentMusic = new Intent(EditActivity.this, MyIntentService.class); 264 | String action_2 = MyIntentService.ACTION_MUSIC_2; 265 | // 设置action 266 | intentMusic.setAction(action_2); 267 | startService(intentMusic); 268 | break; 269 | case 2: 270 | // 启动服务播放背景音乐 271 | intentMusic = new Intent(EditActivity.this, MyIntentService.class); 272 | String action_3 = MyIntentService.ACTION_MUSIC_3; 273 | // 设置action 274 | intentMusic.setAction(action_3); 275 | startService(intentMusic); 276 | break; 277 | case 3: 278 | // 启动服务播放背景音乐 279 | intentMusic = new Intent(EditActivity.this, MyIntentService.class); 280 | String action_4 = MyIntentService.ACTION_MUSIC_4; 281 | // 设置action 282 | intentMusic.setAction(action_4); 283 | startService(intentMusic); 284 | break; 285 | case 4: 286 | // 启动服务播放背景音乐 287 | intentMusic = new Intent(EditActivity.this, MyIntentService.class); 288 | String action_5 = MyIntentService.ACTION_MUSIC_5; 289 | // 设置action 290 | intentMusic.setAction(action_5); 291 | startService(intentMusic); 292 | break; 293 | case 5: 294 | // 启动服务播放背景音乐 295 | intentMusic = new Intent(EditActivity.this, MyIntentService.class); 296 | String action_6 = MyIntentService.ACTION_MUSIC_6; 297 | // 设置action 298 | intentMusic.setAction(action_6); 299 | startService(intentMusic); 300 | break; 301 | } 302 | } 303 | }).create().show(); 304 | break; 305 | 306 | } 307 | return super.onOptionsItemSelected(item); 308 | } 309 | 310 | public void autoSetMessage() { 311 | if (openMode == 4) { 312 | if (editText.getText().toString().length() == 0) { 313 | intent.putExtra("mode", -1); //没有信息 314 | } else { 315 | intent.putExtra("mode", 0); // 有一个新的 316 | intent.putExtra("content", editText.getText().toString()); 317 | intent.putExtra("time", dateToStr()); 318 | intent.putExtra("tag", tag); 319 | } 320 | } else { 321 | if (editText.getText().toString().equals(old_content) && !tagChange) 322 | intent.putExtra("mode", -1); // 没有修改 323 | else { 324 | intent.putExtra("mode", 1); //有修改 325 | intent.putExtra("content", editText.getText().toString()); 326 | intent.putExtra("time", dateToStr()); 327 | intent.putExtra("id", id); 328 | intent.putExtra("tag", tag); 329 | } 330 | } 331 | } 332 | //时间戳 333 | public String dateToStr () { 334 | Date date = new Date(); 335 | SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss"); 336 | return simpleDateFormat.format(date); 337 | } 338 | } -------------------------------------------------------------------------------- /app/src/main/java/com/example/notebook/HandWriting/CustomView.java: -------------------------------------------------------------------------------- 1 | package com.example.notebook.HandWriting; 2 | 3 | import android.content.Context; 4 | import android.graphics.Canvas; 5 | import android.graphics.Color; 6 | import android.graphics.Paint; 7 | import android.graphics.Path; 8 | import android.graphics.RectF; 9 | import android.view.View; 10 | 11 | /** 12 | * 使用内部类 自定义一个简单的View 13 | * @author Wang 14 | * 15 | */ 16 | class CustomView extends View { 17 | 18 | Paint paint; 19 | 20 | public CustomView(Context context) { 21 | super(context); 22 | paint = new Paint(); //设置一个笔刷大小是3的黄色的画笔 23 | paint.setColor(Color.YELLOW);//颜色 24 | paint.setStrokeJoin(Paint.Join.ROUND); 25 | paint.setStrokeCap(Paint.Cap.ROUND); 26 | paint.setStrokeWidth(3);//画笔大小 27 | } 28 | 29 | 30 | @Override 31 | protected void onDraw(Canvas canvas) { 32 | //直接将View显示区域用某个颜色填充满 33 | //canvas.drawColor(Color.BLUE); 34 | 35 | //绘圆 36 | canvas.drawCircle(100, 100, 90, paint); 37 | //绘线 38 | paint.setColor(Color.GREEN); 39 | paint.setStrokeWidth(10); 40 | canvas.drawLine(300,300,400,500,paint); 41 | 42 | RectF rect = new RectF(100, 100, 300, 300); 43 | 44 | //绘制弧线区域 45 | paint.setColor(Color.RED); 46 | canvas.drawArc(rect, //弧线所使用的矩形区域大小 47 | 0, //开始角度 48 | 120, //扫过的角度 49 | true, //是否使用中心 50 | paint); 51 | 52 | //矩形区域内切椭圆 53 | rect = new RectF(500,500,600,700); 54 | canvas.drawOval(rect, paint); 55 | 56 | //绘矩形 57 | paint.setColor(Color.BLUE); 58 | rect = new RectF(800,800,1000,1000); 59 | canvas.drawRect(rect,paint); 60 | 61 | //绘圆角矩形 62 | paint.setColor(Color.YELLOW); 63 | canvas.drawRoundRect(rect, 64 | 50, //x轴的半径 65 | 50, //y轴的半径 66 | paint); 67 | 68 | Path path = new Path(); //定义一条路径 69 | path.moveTo(100, 500); //移动到 坐标10,10 70 | path.lineTo(300, 600); 71 | path.lineTo(200,500); 72 | path.lineTo(100, 500); 73 | canvas.drawPath(path, paint); 74 | 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/notebook/HandWriting/HandwritingActivity.java: -------------------------------------------------------------------------------- 1 | package com.example.notebook.HandWriting; 2 | 3 | import androidx.appcompat.app.AppCompatActivity; 4 | 5 | import android.content.Intent; 6 | import android.graphics.Bitmap; 7 | import android.graphics.Canvas; 8 | import android.graphics.Color; 9 | import android.graphics.Paint; 10 | import android.net.Uri; 11 | import android.os.Bundle; 12 | import android.os.Environment; 13 | import android.view.MotionEvent; 14 | import android.view.View; 15 | import android.widget.Button; 16 | import android.widget.ImageView; 17 | import android.widget.Toast; 18 | 19 | import com.example.notebook.R; 20 | 21 | import java.io.File; 22 | import java.io.FileOutputStream; 23 | public class HandwritingActivity extends AppCompatActivity { 24 | 25 | private ImageView iv; 26 | private Bitmap baseBitmap; 27 | private Button btn_resume; 28 | private Button btn_save; 29 | private Canvas canvas; 30 | private Paint paint; 31 | 32 | float radio; 33 | 34 | @Override 35 | protected void onCreate(Bundle savedInstanceState) { 36 | super.onCreate(savedInstanceState); 37 | setContentView(R.layout.activity_handwriting); 38 | 39 | radio = 5; 40 | 41 | iv = findViewById(R.id.iv); 42 | // 初始化一个画笔,笔触宽度为5,颜色为红色 43 | paint = new Paint(); 44 | paint.setStrokeWidth(radio); 45 | paint.setColor(Color.RED); 46 | iv = findViewById(R.id.iv); 47 | btn_resume = findViewById(R.id.btn_resume); 48 | btn_save = findViewById(R.id.btn_save); 49 | 50 | btn_resume.setOnClickListener(click); 51 | btn_save.setOnClickListener(click); 52 | iv.setOnTouchListener(touch); 53 | } 54 | 55 | private View.OnTouchListener touch = new View.OnTouchListener() { 56 | // 定义手指开始触摸的坐标 57 | float startX; 58 | float startY; 59 | 60 | @Override 61 | public boolean onTouch(View v, MotionEvent event) { 62 | switch (event.getAction()) { 63 | // 用户按下动作 64 | case MotionEvent.ACTION_DOWN: 65 | // 第一次绘图初始化内存图片,指定背景为白色 66 | if (baseBitmap == null) { 67 | baseBitmap = Bitmap.createBitmap(iv.getWidth(), 68 | iv.getHeight(), Bitmap.Config.ARGB_8888); 69 | canvas = new Canvas(baseBitmap); 70 | canvas.drawColor(Color.WHITE); 71 | } 72 | // 记录开始触摸的点的坐标 73 | startX = event.getX(); 74 | startY = event.getY(); 75 | break; 76 | // 用户手指在屏幕上移动的动作 77 | case MotionEvent.ACTION_MOVE: 78 | // 记录移动位置的点的坐标 79 | float stopX = event.getX(); 80 | float stopY = event.getY(); 81 | 82 | Thread t =new Thread(new Runnable() { 83 | @Override 84 | public void run() { 85 | radio+=0.1; 86 | 87 | try { 88 | Thread.sleep(1000); 89 | } catch (InterruptedException e) { 90 | e.printStackTrace(); 91 | } 92 | } 93 | }); 94 | t.start(); 95 | 96 | paint.setStrokeWidth(radio); 97 | //根据两点坐标,绘制连线 98 | canvas.drawLine(startX, startY, stopX, stopY, paint); 99 | 100 | // 更新开始点的位置 101 | startX = event.getX(); 102 | startY = event.getY(); 103 | // 把图片展示到ImageView中 104 | iv.setImageBitmap(baseBitmap); 105 | break; 106 | case MotionEvent.ACTION_UP: 107 | radio = 5; 108 | break; 109 | default: 110 | break; 111 | } 112 | return true; 113 | } 114 | }; 115 | private View.OnClickListener click = new View.OnClickListener() { 116 | 117 | @Override 118 | public void onClick(View v) { 119 | switch (v.getId()) { 120 | case R.id.btn_save: 121 | saveBitmap(); 122 | break; 123 | case R.id.btn_resume: 124 | resumeCanvas(); 125 | break; 126 | default: 127 | break; 128 | } 129 | } 130 | }; 131 | 132 | /** 133 | * 保存图片到SD卡上 134 | */ 135 | protected void saveBitmap() { 136 | try { 137 | // 保存图片到SD卡上 138 | String fileName = "/sdcard/"+System.currentTimeMillis() + ".png"; 139 | File file = new File(fileName); 140 | FileOutputStream stream = new FileOutputStream(file); 141 | baseBitmap.compress(Bitmap.CompressFormat.PNG, 100, stream); 142 | Toast.makeText(HandwritingActivity.this, "保存图片成功", Toast.LENGTH_SHORT).show(); 143 | // // Android设备Gallery应用只会在启动的时候扫描系统文件夹 144 | // // 这里模拟一个媒体装载的广播,用于使保存的图片可以在Gallery中查看 145 | Intent intent = new Intent(); 146 | intent.setAction(Intent.ACTION_MEDIA_MOUNTED); 147 | intent.setData(Uri.fromFile(Environment 148 | .getExternalStorageDirectory())); 149 | sendBroadcast(intent); 150 | } catch (Exception e) { 151 | Toast.makeText(HandwritingActivity.this, "保存图片失败", Toast.LENGTH_SHORT).show(); 152 | e.printStackTrace(); 153 | } 154 | } 155 | 156 | // 手动清除画板的绘图,重新创建一个画板 157 | protected void resumeCanvas() { 158 | if (baseBitmap != null) { 159 | baseBitmap = Bitmap.createBitmap(iv.getWidth(), 160 | iv.getHeight(), Bitmap.Config.ARGB_8888); 161 | canvas = new Canvas(baseBitmap); 162 | canvas.drawColor(Color.WHITE); 163 | iv.setImageBitmap(baseBitmap); 164 | Toast.makeText(HandwritingActivity.this, "清除画板成功,可以重新开始绘图", Toast.LENGTH_SHORT).show(); 165 | } 166 | } 167 | } 168 | 169 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/notebook/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.example.notebook; 2 | 3 | import androidx.annotation.Nullable; 4 | import androidx.annotation.RequiresApi; 5 | import androidx.appcompat.widget.Toolbar; 6 | 7 | import android.app.AlarmManager; 8 | import android.app.AlertDialog; 9 | import android.app.PendingIntent; 10 | import android.content.Context; 11 | import android.content.DialogInterface; 12 | import android.content.Intent; 13 | import android.content.SharedPreferences; 14 | import android.database.Cursor; 15 | import android.database.sqlite.SQLiteDatabase; 16 | import android.graphics.Bitmap; 17 | import android.icu.text.SimpleDateFormat; 18 | import android.net.ParseException; 19 | import android.os.Build; 20 | import android.os.Bundle; 21 | import android.util.DisplayMetrics; 22 | import android.util.Log; 23 | import android.view.LayoutInflater; 24 | import android.view.Menu; 25 | import android.view.MenuItem; 26 | import android.view.View; 27 | import android.view.ViewGroup; 28 | import android.view.WindowManager; 29 | import android.widget.AdapterView; 30 | import android.widget.CompoundButton; 31 | import android.widget.ImageView; 32 | import android.widget.LinearLayout; 33 | import android.widget.ListView; 34 | import android.widget.PopupWindow; 35 | import android.widget.RelativeLayout; 36 | import android.widget.TextView; 37 | import android.widget.ToggleButton; 38 | 39 | import com.example.notebook.Alarm.AlarmReceiver; 40 | import com.example.notebook.Alarm.EditAlarmActivity; 41 | import com.example.notebook.Alarm.Plan; 42 | import com.example.notebook.Alarm.PlanAdapter; 43 | import com.example.notebook.Alarm.PlanDatabase; 44 | import com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton; 45 | import com.google.android.material.floatingactionbutton.FloatingActionButton; 46 | 47 | import java.util.ArrayList; 48 | import java.util.Calendar; 49 | import java.util.Collections; 50 | import java.util.Comparator; 51 | import java.util.Date; 52 | import java.util.List; 53 | import java.util.Objects; 54 | 55 | import static android.view.View.GONE; 56 | 57 | 58 | public class MainActivity extends BaseActivity implements 59 | AdapterView.OnItemClickListener, 60 | AdapterView.OnItemLongClickListener { 61 | 62 | private NoteDatabase dbHelper; 63 | private PlanDatabase planDbHelper; 64 | private Toolbar myToolbar; 65 | TextView textView; 66 | private ListView lv; 67 | private Context context = this; 68 | private NoteAdapter adapter; 69 | private List noteList = new ArrayList(); 70 | private List planList = new ArrayList(); 71 | //fab 72 | private FloatingActionButton mAddMemoFab, mAddNoteFab; 73 | private ExtendedFloatingActionButton mAddFab; 74 | TextView addMemoActionText, addNoteActionText; 75 | private Boolean isAllFabsVisible; 76 | 77 | private SharedPreferences sharedPreferences; 78 | private ToggleButton content_switch; 79 | 80 | private AlarmManager alarmManager; 81 | private Achievement achievement; 82 | private ListView lv_plan; 83 | private LinearLayout lv_layout; 84 | private LinearLayout lv_plan_layout; 85 | private PlanAdapter planAdapter; 86 | 87 | public static int curId = 5; 88 | 89 | String[] list_String = {"before one month", "before three months", "before six months", "before one year"}; 90 | 91 | @Override 92 | protected void onCreate(Bundle savedInstanceState) { 93 | super.onCreate(savedInstanceState); 94 | getWindow().setStatusBarColor(getResources().getColor(R.color.greyMain)); 95 | setContentView(R.layout.activity_main); 96 | //实例化闹钟管理器 97 | alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE); 98 | achievement = new Achievement(context); 99 | initView(); 100 | 101 | } 102 | 103 | @Override 104 | protected void needRefresh() { 105 | setTheme(R.style.AppTheme); 106 | Intent intent = new Intent(this, MainActivity.class); 107 | intent.putExtra("opMode", 10); 108 | startActivity(intent); 109 | overridePendingTransition(R.anim.night_switch, R.anim.night_switch_over); 110 | finish(); 111 | } 112 | 113 | public void initView() { 114 | initPrefs(); 115 | textView = findViewById(R.id.et); 116 | lv = findViewById(R.id.lv); 117 | myToolbar = findViewById(R.id.myToolbar); 118 | content_switch = findViewById(R.id.content_switch); 119 | lv_plan = findViewById(R.id.lv_plan); 120 | lv_layout = findViewById(R.id.lv_layout); 121 | lv_plan_layout = findViewById(R.id.lv_plan_layout); 122 | refreshLvVisibility(); 123 | adapter = new NoteAdapter(getApplicationContext(), noteList); 124 | planAdapter = new PlanAdapter(getApplicationContext(), planList); 125 | refreshListView(); 126 | lv.setAdapter(adapter); 127 | lv_plan.setAdapter(planAdapter); 128 | 129 | //自定义状态栏 130 | setSupportActionBar(myToolbar); 131 | 132 | lv.setOnItemClickListener(this); //点击操作 133 | lv_plan.setOnItemClickListener(this); 134 | lv.setOnItemLongClickListener(this); //长按操作 135 | lv_plan.setOnItemLongClickListener(this); 136 | 137 | //fab 138 | mAddFab = findViewById(R.id.add_fab); 139 | mAddMemoFab = findViewById(R.id.add_memo_fab); 140 | mAddNoteFab = findViewById(R.id.add_note_fab); 141 | addMemoActionText = findViewById(R.id.add_memo_action_text); 142 | addNoteActionText = findViewById(R.id.add_note_action_text); 143 | 144 | //设置fab 145 | mAddMemoFab.setVisibility(View.GONE); 146 | mAddNoteFab.setVisibility(View.GONE); 147 | addMemoActionText.setVisibility(View.GONE); 148 | addNoteActionText.setVisibility(View.GONE); 149 | 150 | isAllFabsVisible = false; 151 | 152 | //新增fab 153 | mAddFab.shrink(); 154 | 155 | boolean temp = sharedPreferences.getBoolean("content_switch", false); 156 | content_switch.setChecked(temp);//判断是看note还是plan 157 | content_switch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { 158 | @Override 159 | public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { 160 | SharedPreferences.Editor editor = sharedPreferences.edit(); 161 | editor.putBoolean("content_switch", isChecked); //Boolean类型的数据,content_switch为键名,isChecked为键值 162 | editor.commit(); 163 | refreshLvVisibility(); 164 | } 165 | }); 166 | 167 | //主fab点击 168 | mAddFab.setOnClickListener(new View.OnClickListener() { 169 | @Override 170 | public void onClick(View view) { 171 | if (!isAllFabsVisible) { 172 | mAddMemoFab.show(); 173 | mAddNoteFab.show(); 174 | addMemoActionText.setVisibility(View.VISIBLE); 175 | addNoteActionText.setVisibility(View.VISIBLE); 176 | 177 | mAddFab.extend(); 178 | 179 | isAllFabsVisible = true; 180 | } else { 181 | mAddMemoFab.hide(); 182 | mAddNoteFab.hide(); 183 | addMemoActionText.setVisibility(View.GONE); 184 | addNoteActionText.setVisibility(View.GONE); 185 | 186 | mAddFab.shrink(); 187 | 188 | isAllFabsVisible = false; 189 | } 190 | } 191 | }); 192 | 193 | //添加日记 194 | mAddNoteFab.setOnClickListener(new View.OnClickListener() { 195 | @Override 196 | public void onClick(View v) { 197 | Intent intent = new Intent(MainActivity.this, EditActivity.class); 198 | intent.putExtra("mode", 4); //新建日记 199 | startActivityForResult(intent, 1); 200 | } 201 | }); 202 | 203 | //添加备忘录 204 | mAddMemoFab.setOnClickListener(new View.OnClickListener() { 205 | @Override 206 | public void onClick(View v) { 207 | Intent intent = new Intent(MainActivity.this, EditAlarmActivity.class); 208 | intent.putExtra("mode", 2); // MODE of 'new plan' 209 | startActivityForResult(intent, 1); 210 | overridePendingTransition(R.anim.in_righttoleft, R.anim.no); 211 | } 212 | }); 213 | } 214 | 215 | private void refreshLvVisibility() { 216 | //决定应该显示notes还是plans 217 | boolean temp = sharedPreferences.getBoolean("content_switch", false); 218 | if(temp){ 219 | lv_layout.setVisibility(GONE); 220 | lv_plan_layout.setVisibility(View.VISIBLE); 221 | } 222 | else{ 223 | lv_layout.setVisibility(View.VISIBLE); 224 | lv_plan_layout.setVisibility(GONE); 225 | } 226 | } 227 | 228 | //接受返回的结果(包括:删除的) 229 | @Override 230 | protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { 231 | 232 | int returnMode; 233 | long note_Id; 234 | returnMode = data.getExtras().getInt("mode", -1); 235 | note_Id = data.getExtras().getLong("id", 0); 236 | 237 | if (returnMode == 1) { //更新当前笔记内容 238 | String content = data.getExtras().getString("content"); 239 | String time = data.getExtras().getString("time"); 240 | int tag = data.getExtras().getInt("tag", 1); 241 | Note newNote = new Note(content, time, tag); 242 | newNote.setId(note_Id); 243 | BaseCrud op = new BaseCrud(context); 244 | op.open(); 245 | op.updateNote(newNote); 246 | achievement.editNote(op.getNote(note_Id).getContent(), content); 247 | op.close(); 248 | }else if (returnMode == 0) { // 创建新笔记 249 | String content = data.getExtras().getString("content"); 250 | String time = data.getExtras().getString("time"); 251 | int tag = data.getExtras().getInt("tag", 1); 252 | Note newNote = new Note(content, time, tag); 253 | BaseCrud op = new BaseCrud(context); 254 | op.open(); 255 | op.addNote(newNote); 256 | op.close(); 257 | achievement.addNote(content); 258 | }else if(returnMode==2){ //删除已经创建好的笔记内容 259 | Note delNote=new Note(); 260 | delNote.setId(note_Id); 261 | BaseCrud op = new BaseCrud(context); 262 | op.open(); 263 | op.removeNote(delNote); 264 | op.close(); 265 | achievement.deleteNote(); 266 | }else if (returnMode == 11){ //编辑备忘录 267 | String title = data.getExtras().getString("title", null); 268 | String content = data.getExtras().getString("content", null); 269 | String time = data.getExtras().getString("time", null); 270 | Log.d(TAG, time); 271 | Plan plan = new Plan(title, content, time); 272 | plan.setId(note_Id); 273 | com.example.notebook.Alarm.AlarmCrud op = new com.example.notebook.Alarm.AlarmCrud(context); 274 | op.open(); 275 | op.updatePlan(plan); 276 | op.close(); 277 | }else if (returnMode == 12){ //删除存在的备忘录 278 | Plan plan = new Plan(); 279 | plan.setId(note_Id); 280 | com.example.notebook.Alarm.AlarmCrud op = new com.example.notebook.Alarm.AlarmCrud(context); 281 | op.open(); 282 | op.removePlan(plan); 283 | op.close(); 284 | }else if (returnMode == 10){ //创建新的备忘录 285 | String title = data.getExtras().getString("title", null); 286 | String content = data.getExtras().getString("content", null); 287 | String time = data.getExtras().getString("time", null); 288 | Plan newPlan = new Plan(title, content, time); 289 | com.example.notebook.Alarm.AlarmCrud op = new com.example.notebook.Alarm.AlarmCrud(context); 290 | op.open(); 291 | op.addPlan(newPlan); 292 | Log.d(TAG, "onActivityResult: "+ time); 293 | op.close(); 294 | } 295 | refreshListView(); 296 | super.onActivityResult(requestCode, resultCode, data); 297 | } 298 | 299 | private void initPrefs() { 300 | sharedPreferences = androidx.preference.PreferenceManager.getDefaultSharedPreferences(getBaseContext()); 301 | SharedPreferences.Editor editor = sharedPreferences.edit(); 302 | if (!sharedPreferences.contains("nightMode")) { 303 | editor.putBoolean("nightMode", false); 304 | editor.apply(); 305 | } 306 | if (!sharedPreferences.contains("reverseSort")) { 307 | editor.putBoolean("reverseSort", false); 308 | editor.apply(); 309 | } 310 | if (!sharedPreferences.contains("fabColor")) { 311 | editor.putInt("fabColor", -500041); 312 | editor.apply(); 313 | } 314 | if (!sharedPreferences.contains("tagListString")) { 315 | String s = "no tag_life_study_work_play"; 316 | editor.putString("tagListString", s); 317 | editor.apply(); 318 | } 319 | if(!sharedPreferences.contains("content_switch")) { 320 | editor.putBoolean("content_switch", false); 321 | editor.apply(); 322 | } 323 | if(!sharedPreferences.contains("fabPlanColor")){ 324 | editor.putInt("fabPlanColor", -500041); 325 | editor.apply(); 326 | } 327 | if(!sharedPreferences.contains("noteTitle")){ 328 | editor.putBoolean("noteTitle", true); 329 | editor.apply(); 330 | } 331 | } 332 | 333 | //菜单栏:删除的加入 334 | @Override 335 | public boolean onCreateOptionsMenu(Menu menu) { 336 | final int mode = (content_switch.isChecked()? 2 : 1); 337 | final String itemName = (mode == 1 ? "notes" : "plans"); 338 | new Thread(new Runnable() { 339 | @Override 340 | public void run() { 341 | final View view = findViewById(R.id.menu_clear); 342 | if (view != null) { 343 | view.setOnLongClickListener(new View.OnLongClickListener() { 344 | @Override 345 | public boolean onLongClick(View v) { 346 | AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this); 347 | builder.setTitle("Delete all "+ itemName); 348 | builder.setIcon(R.drawable.ic_error_outline_black_24dp); 349 | builder.setItems(list_String, new DialogInterface.OnClickListener() {//列表对话框; 350 | @Override 351 | public void onClick(DialogInterface dialog, final int which) {//根据这里which值,即可以指定是点击哪一个Item; 352 | new AlertDialog.Builder(MainActivity.this) 353 | .setMessage("Do you want to delete all " + itemName + " " + list_String[which] + "? ") 354 | .setPositiveButton("是", new DialogInterface.OnClickListener() { 355 | @Override 356 | public void onClick(DialogInterface dialog, int a) { 357 | Log.d(TAG, "onClick: " + which); 358 | removeSelectItems(which, mode); 359 | refreshListView(); 360 | } 361 | 362 | //根据模式与时长删除对顶的计划s/笔记s 363 | private void removeSelectItems(int which, int mode) { 364 | int monthNum = 0; 365 | switch (which){ 366 | case 0: 367 | monthNum = 1; 368 | break; 369 | case 1: 370 | monthNum = 3; 371 | break; 372 | case 2: 373 | monthNum = 6; 374 | break; 375 | case 3: 376 | monthNum = 12; 377 | break; 378 | } 379 | Calendar rightNow = Calendar.getInstance(); 380 | rightNow.add(Calendar.MONTH,-monthNum);//日期加3个月 381 | Date selectDate = rightNow.getTime(); 382 | java.text.SimpleDateFormat simpleDateFormat = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 383 | String selectDateStr = simpleDateFormat.format(selectDate); 384 | Log.d(TAG, "removeSelectItems: " + selectDateStr); 385 | switch(mode){ 386 | case 1: //notes 387 | dbHelper = new NoteDatabase(context); 388 | SQLiteDatabase db = dbHelper.getWritableDatabase(); 389 | Cursor cursor = db.rawQuery("select * from notes" ,null); 390 | while(cursor.moveToNext()){ 391 | if (cursor.getString(cursor.getColumnIndex(NoteDatabase.TIME)).compareTo(selectDateStr) < 0){ 392 | db.delete("notes", NoteDatabase.ID + "=?", new String[]{Long.toString(cursor.getLong(cursor.getColumnIndex(NoteDatabase.ID)))}); 393 | } 394 | } 395 | db.execSQL("update sqlite_sequence set seq=0 where name='notes'"); //reset id to 1 396 | refreshListView(); 397 | break; 398 | case 2: //plans 399 | planDbHelper = new PlanDatabase(context); 400 | SQLiteDatabase pdb = planDbHelper.getWritableDatabase(); 401 | Cursor cursor1 = pdb.rawQuery("select * from plans" ,null); 402 | while(cursor1.moveToNext()){ 403 | if (cursor1.getString(cursor1.getColumnIndex(PlanDatabase.TIME)).compareTo(selectDateStr) < 0){ 404 | pdb.delete("plans", PlanDatabase.ID + "=?", new String[]{Long.toString(cursor1.getLong(cursor1.getColumnIndex(PlanDatabase.ID)))}); 405 | } 406 | } 407 | pdb.execSQL("update sqlite_sequence set seq=0 where name='plans'"); 408 | refreshListView(); 409 | break; 410 | } 411 | } 412 | }).setNegativeButton("否", new DialogInterface.OnClickListener() { 413 | @Override 414 | public void onClick(DialogInterface dialog, int which) { 415 | dialog.dismiss(); 416 | } 417 | }).create().show(); 418 | } 419 | }); 420 | 421 | AlertDialog dialog = builder.create(); 422 | dialog.show(); 423 | return true; 424 | } 425 | }); 426 | } 427 | } 428 | }); 429 | 430 | 431 | return super.onCreateOptionsMenu(menu); 432 | } 433 | 434 | //删除主界面全部便签 435 | @Override 436 | public boolean onOptionsItemSelected(MenuItem item) { 437 | switch (item.getItemId()) { 438 | case R.id.menu_clear: 439 | if(!content_switch.isChecked()) { 440 | new AlertDialog.Builder(MainActivity.this) 441 | .setMessage("Delete All Notes ?") 442 | .setPositiveButton("确定", new DialogInterface.OnClickListener() { 443 | @Override 444 | public void onClick(DialogInterface dialog, int which) { 445 | dbHelper = new NoteDatabase(context); 446 | SQLiteDatabase db = dbHelper.getWritableDatabase(); 447 | db.delete("notes", null, null);//delete data in table NOTES 448 | db.execSQL("update sqlite_sequence set seq=0 where name='notes'"); //reset id to 1 449 | refreshListView(); 450 | } 451 | }).setNegativeButton("取消", new DialogInterface.OnClickListener() { 452 | @Override 453 | public void onClick(DialogInterface dialog, int which) { 454 | dialog.dismiss(); 455 | } 456 | }).create().show(); 457 | } 458 | else{ 459 | new AlertDialog.Builder(MainActivity.this) 460 | .setMessage("Delete All Plans ?") 461 | .setPositiveButton("确定", new DialogInterface.OnClickListener() { 462 | @Override 463 | public void onClick(DialogInterface dialog, int which) { 464 | planDbHelper = new PlanDatabase(context); 465 | SQLiteDatabase db = planDbHelper.getWritableDatabase(); 466 | db.delete("plans", null, null); 467 | db.execSQL("update sqlite_sequence set seq=0 where name='plans'"); //reset id to 1 468 | refreshListView(); 469 | } 470 | }).setNegativeButton("取消", new DialogInterface.OnClickListener() { 471 | @Override 472 | public void onClick(DialogInterface dialog, int which) { 473 | dialog.dismiss(); 474 | } 475 | }).create().show(); 476 | } 477 | break; 478 | } 479 | return super.onOptionsItemSelected(item); 480 | } 481 | 482 | //实时更新列表内容 483 | private void refreshListView(){ 484 | SharedPreferences sharedPreferences = androidx.preference.PreferenceManager.getDefaultSharedPreferences(this); 485 | BaseCrud op = new BaseCrud(context); 486 | op.open(); 487 | if (noteList.size() > 0) noteList.clear(); 488 | noteList.addAll(op.getAllNotes()); 489 | //排序 490 | if (sharedPreferences.getBoolean("reverseSort", false)) sortNotes(noteList, 2); 491 | else sortNotes(noteList, 1); 492 | op.close(); 493 | adapter.notifyDataSetChanged(); 494 | 495 | //备忘录 496 | com.example.notebook.Alarm.AlarmCrud op1 = new com.example.notebook.Alarm.AlarmCrud(context); 497 | op1.open(); 498 | if(planList.size() > 0) { 499 | cancelAlarms(planList);//删除所有闹钟 500 | planList.clear(); 501 | } 502 | planList.addAll(op1.getAllPlans()); 503 | startAlarms(planList);//添加所有新闹钟 504 | if (sharedPreferences.getBoolean("reverseSort", false)) sortPlans(planList, 2); 505 | else sortPlans(planList, 1); 506 | op1.close(); 507 | planAdapter.notifyDataSetChanged(); 508 | achievement.listen(); 509 | } 510 | 511 | //设置很多提醒 512 | private void startAlarms(List plans){ 513 | for(int i = 0; i < plans.size(); i++) { 514 | startAlarm(plans.get(i)); 515 | } 516 | } 517 | 518 | //设置提醒 519 | private void startAlarm(Plan p) { 520 | Calendar c = p.getPlanTime(); 521 | if(!c.before(Calendar.getInstance())) { 522 | Intent intent = new Intent(MainActivity.this, AlarmReceiver.class); 523 | intent.putExtra("title", p.getTitle()); 524 | intent.putExtra("content", p.getContent()); 525 | intent.putExtra("id", (int)p.getId()); 526 | PendingIntent pendingIntent = PendingIntent.getBroadcast(this, (int) p.getId(), intent, 0); 527 | alarmManager.setExact(AlarmManager.RTC_WAKEUP, c.getTimeInMillis(), pendingIntent); 528 | } 529 | } 530 | 531 | //取消提醒 532 | private void cancelAlarm(Plan p) { 533 | Intent intent = new Intent(this, AlarmReceiver.class); 534 | PendingIntent pendingIntent = PendingIntent.getBroadcast(this, (int)p.getId(), intent, 0); 535 | alarmManager.cancel(pendingIntent); 536 | } 537 | 538 | //取消很多提醒 539 | private void cancelAlarms(List plans){ 540 | for(int i = 0; i < plans.size(); i++) 541 | cancelAlarm(plans.get(i)); 542 | } 543 | 544 | @Override 545 | public void onResume(){ 546 | super.onResume(); 547 | Intent intent = getIntent(); 548 | if(intent!=null && intent.getIntExtra("mode", 0) == 1){ 549 | content_switch.setChecked(true); 550 | refreshLvVisibility(); 551 | } 552 | } 553 | 554 | //成就系统 555 | public class Achievement { 556 | private SharedPreferences sharedPreferences; 557 | private int noteNumber; 558 | private int wordNumber; 559 | private int noteLevel; 560 | private int wordLevel; 561 | 562 | public Achievement(Context context) { 563 | sharedPreferences = androidx.preference.PreferenceManager.getDefaultSharedPreferences(context); 564 | initPref(); 565 | getPref(); 566 | } 567 | 568 | private void getPref() { 569 | noteNumber = sharedPreferences.getInt("noteNumber", 0); 570 | wordNumber = sharedPreferences.getInt("wordNumber", 0); 571 | noteLevel = sharedPreferences.getInt("noteLevel", 0); 572 | wordLevel = sharedPreferences.getInt("wordLevel", 0); 573 | } 574 | 575 | private void initPref() { 576 | SharedPreferences.Editor editor = sharedPreferences.edit(); 577 | if (!sharedPreferences.contains("noteLevel")) { 578 | editor.putInt("noteLevel", 0); 579 | editor.commit(); 580 | if (!sharedPreferences.contains("wordLevel")) { 581 | editor.putInt("wordLevel", 0); 582 | editor.commit(); 583 | addCurrent(noteList); 584 | if (sharedPreferences.contains("maxRemainNumber")) { 585 | editor.remove("maxRemainNumber"); 586 | editor.commit(); 587 | } 588 | if (sharedPreferences.contains("remainNumber")){ 589 | editor.remove("remainNumber"); 590 | editor.commit(); 591 | } 592 | if (!sharedPreferences.contains("noteNumber")) { 593 | editor.putInt("noteNumber", 0); 594 | editor.commit(); 595 | addCurrent(noteList); 596 | if (!sharedPreferences.contains("wordNumber")) { 597 | editor.putInt("wordNumber", 0); 598 | editor.commit(); 599 | } 600 | } 601 | } 602 | } 603 | } 604 | 605 | //加入已写好的笔记 606 | private void addCurrent(List list) { 607 | SharedPreferences.Editor editor = sharedPreferences.edit(); 608 | int tempNN = list.size(); 609 | editor.putInt("noteNumber", tempNN); 610 | if (tempNN >= 1000) editor.putInt("noteLevel", 4); 611 | else if (tempNN >= 100) editor.putInt("noteLevel", 3); 612 | else if (tempNN >= 10) editor.putInt("noteLevel", 2); 613 | else if (tempNN >= 1) editor.putInt("noteLevel", 1); 614 | int wordCount = 0; 615 | for (int i = 0; i < list.size(); i++) { 616 | wordCount += list.get(i).getContent().length(); 617 | } 618 | editor.putInt("wordNumber", wordCount); 619 | if (wordCount >= 20000) editor.putInt("noteLevel", 5); 620 | else if (wordCount >= 5000) editor.putInt("noteLevel", 4); 621 | else if (wordCount >= 1000) editor.putInt("noteLevel", 3); 622 | else if (wordCount >= 500) editor.putInt("noteLevel", 2); 623 | else if (wordCount >= 100) editor.putInt("noteLevel", 1); 624 | editor.apply(); 625 | } 626 | 627 | //添加笔记 628 | public void addNote(String content) { 629 | SharedPreferences.Editor editor = sharedPreferences.edit(); 630 | noteNumber++; 631 | editor.putInt("noteNumber", noteNumber); 632 | wordNumber += content.length(); 633 | editor.putInt("wordNumber", wordNumber); 634 | editor.apply(); 635 | } 636 | 637 | //删除笔记 638 | public void deleteNote() { 639 | 640 | } 641 | 642 | //编辑笔记,修改字数 643 | public void editNote(String oldContent, String newContent) { 644 | if (newContent.length() > oldContent.length()) { 645 | SharedPreferences.Editor editor = sharedPreferences.edit(); 646 | wordNumber += (newContent.length() - oldContent.length()); 647 | editor.putInt("wordNumber", wordNumber); 648 | editor.apply(); 649 | } 650 | } 651 | 652 | //笔记数成就 653 | public void noteNumberAchievement(int num) { 654 | switch (num) { 655 | case 1: 656 | if (noteLevel == 0) announcement("🎉🎉🎉 第一步!", 1, num); 657 | break; 658 | case 10: 659 | if (noteLevel == 1) announcement("🎉🎉🎉 Keep going, and don't give up", 1, num); 660 | break; 661 | case 100: 662 | if (noteLevel == 2) announcement("🎉🎉🎉 This has been a long way...", 1, num); 663 | break; 664 | case 1000: 665 | if (noteLevel == 3) announcement("🎉🎉🎉 Final achievement! Well Done!", 1, num); 666 | break; 667 | } 668 | } 669 | 670 | //字数成就 671 | public void wordNumberAchievement(int num) { 672 | if (num > 20000 && wordLevel == 4) announcement("Final Achievement! 恭喜你!", 2, 20000); 673 | else if (num > 5000 && wordLevel == 3) 674 | announcement("A long story...", 2, 5000); 675 | else if (num > 1000 && wordLevel == 2) 676 | announcement("Double essays!", 2, 1000); 677 | else if (num > 500 && wordLevel == 1) 678 | announcement("You have written an essay!", 2, 500); 679 | else if (num > 100 && wordLevel == 0) 680 | announcement("Take it slow to create more possibilities!", 2, 100); 681 | } 682 | 683 | //对话框 684 | public void announcement(String message, int mode, int num) { 685 | new AlertDialog.Builder(MainActivity.this) 686 | .setTitle(annoucementTitle(mode, num)) 687 | .setMessage(message) 688 | .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { 689 | @Override 690 | public void onClick(DialogInterface dialog, int which) { 691 | dialog.dismiss(); 692 | } 693 | }) 694 | .create().show(); 695 | setState(mode); 696 | } 697 | 698 | //对话框标题 699 | public String annoucementTitle(int mode, int num) { 700 | switch (mode) { 701 | case 1: 702 | return "You have written " + num + " notes! "; 703 | case 2: 704 | return "You have written " + num + " words! "; 705 | case 3: 706 | return "You have " + num + " notes remaining visible!"; 707 | } 708 | return null; 709 | } 710 | 711 | public void setState(int mode) { 712 | //如果重复宣布,则将相应状态设置为true 713 | SharedPreferences.Editor editor = sharedPreferences.edit(); 714 | switch (mode) { 715 | case 1: 716 | noteLevel ++; 717 | editor.putInt("noteLevel", noteLevel); 718 | editor.commit(); 719 | break; 720 | case 2: 721 | wordLevel ++; 722 | editor.putInt("wordLevel", wordLevel); 723 | editor.commit(); 724 | break; 725 | } 726 | } 727 | 728 | //监听 729 | public void listen() { 730 | noteNumberAchievement(noteNumber); 731 | wordNumberAchievement(wordNumber); 732 | } 733 | } 734 | 735 | //主界面跳转编辑界面 736 | @Override 737 | public void onItemClick(AdapterView parent, View view, int position, long id) { 738 | switch (parent.getId()) { 739 | case R.id.lv: 740 | Note curNote = (Note) parent.getItemAtPosition(position); 741 | Intent intent = new Intent(MainActivity.this, EditActivity.class); 742 | intent.putExtra("content", curNote.getContent()); 743 | intent.putExtra("id", curNote.getId()); 744 | intent.putExtra("time", curNote.getTime()); 745 | intent.putExtra("mode", 3); 746 | intent.putExtra("tag", curNote.getTag()); 747 | startActivityForResult(intent, 1); 748 | break; 749 | case R.id.lv_plan: 750 | Plan curPlan = (Plan) parent.getItemAtPosition(position); 751 | Intent intent1 = new Intent(MainActivity.this, EditAlarmActivity.class); 752 | intent1.putExtra("title", curPlan.getTitle()); 753 | intent1.putExtra("content", curPlan.getContent()); 754 | intent1.putExtra("time", curPlan.getTime()); 755 | intent1.putExtra("mode", 1); 756 | intent1.putExtra("id", curPlan.getId()); 757 | startActivityForResult(intent1, 1); 758 | break; 759 | } 760 | } 761 | 762 | //长按删除日记 763 | @Override 764 | public boolean onItemLongClick(AdapterView parent, View view, int position, long id) { 765 | switch (parent.getId()) { 766 | case R.id.lv: 767 | final Note note = noteList.get(position); 768 | new AlertDialog.Builder(MainActivity.this) 769 | .setTitle("确定") 770 | .setMessage("确定要删除此条日记吗?") 771 | .setIcon(R.drawable.ic_baseline_keyboard_voice_24) 772 | .setPositiveButton("确定", new DialogInterface.OnClickListener() { 773 | @Override 774 | public void onClick(DialogInterface dialog, int which) { 775 | BaseCrud op = new BaseCrud(context); 776 | op.open(); 777 | op.removeNote(note); 778 | op.close(); 779 | refreshListView(); 780 | } 781 | }).setNegativeButton("取消", new DialogInterface.OnClickListener() { 782 | @Override 783 | public void onClick(DialogInterface dialog, int which) { 784 | dialog.dismiss(); 785 | } 786 | }).create().show(); 787 | break; 788 | case R.id.lv_plan: 789 | final Plan plan = planList.get(position); 790 | new AlertDialog.Builder(MainActivity.this) 791 | .setMessage("确定要删除此条备忘录吗?") 792 | .setPositiveButton("确定", new DialogInterface.OnClickListener() { 793 | @Override 794 | public void onClick(DialogInterface dialog, int which) { 795 | com.example.notebook.Alarm.AlarmCrud op = new com.example.notebook.Alarm.AlarmCrud(context); 796 | op.open(); 797 | op.removePlan(plan); 798 | op.close(); 799 | refreshListView(); 800 | } 801 | }).setNegativeButton("取消", new DialogInterface.OnClickListener() { 802 | @Override 803 | public void onClick(DialogInterface dialog, int which) { 804 | dialog.dismiss(); 805 | } 806 | }).create().show(); 807 | break; 808 | } 809 | return true; 810 | } 811 | 812 | //格式转换string -> milliseconds 813 | @RequiresApi(api = Build.VERSION_CODES.N) 814 | public long dateStrToSec(String date) throws ParseException, java.text.ParseException { 815 | SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 816 | long secTime = format.parse(date).getTime(); 817 | return secTime; 818 | } 819 | 820 | //转换当前的long值:1, 0, -1 821 | public int ChangeLong(Long l) { 822 | if (l > 0) return 1; 823 | else if (l < 0) return -1; 824 | else return 0; 825 | } 826 | 827 | //按时间排序笔记 828 | public void sortNotes(List noteList, final int mode) { 829 | Collections.sort(noteList, new Comparator() { 830 | @RequiresApi(api = Build.VERSION_CODES.N) 831 | @Override 832 | public int compare(Note o1, Note o2) { 833 | try { 834 | if (mode == 1) { 835 | return ChangeLong(dateStrToSec(o2.getTime()) - dateStrToSec(o1.getTime())); 836 | } 837 | else if (mode == 2) {//reverseSort 838 | return ChangeLong(dateStrToSec(o1.getTime()) - dateStrToSec(o2.getTime())); 839 | } 840 | } catch (ParseException | java.text.ParseException e) { 841 | e.printStackTrace(); 842 | } 843 | return 1; 844 | } 845 | }); 846 | } 847 | 848 | //按备忘录时间排序 849 | public void sortPlans(List planList, final int mode){ 850 | Collections.sort(planList, new Comparator() { 851 | @Override 852 | public int compare(Plan o1, Plan o2) { 853 | try { 854 | if (mode == 1) 855 | return ChangeLong(calStrToSec(o1.getTime()) - calStrToSec(o2.getTime())); 856 | else if (mode == 2) //reverseSort 857 | return ChangeLong(calStrToSec(o2.getTime()) - calStrToSec(o1.getTime())); 858 | } catch (java.text.ParseException e) { 859 | e.printStackTrace(); 860 | } 861 | return 1; 862 | } 863 | }); 864 | } 865 | public long calStrToSec(String date) throws java.text.ParseException { 866 | java.text.SimpleDateFormat format = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm"); 867 | long secTime = Objects.requireNonNull(format.parse(date)).getTime(); 868 | return secTime; 869 | } 870 | } -------------------------------------------------------------------------------- /app/src/main/java/com/example/notebook/MyIntentService.java: -------------------------------------------------------------------------------- 1 | package com.example.notebook; 2 | 3 | import android.app.IntentService; 4 | import android.content.Intent; 5 | import android.media.MediaPlayer; 6 | 7 | 8 | /** 9 | * An {@link IntentService} subclass for handling asynchronous task requests in 10 | * a service on a separate handler thread. 11 | *

12 | * TODO: Customize class - update intent actions and extra parameters. 13 | */ 14 | public class MyIntentService extends IntentService { 15 | // TODO: Rename actions, choose action names that describe tasks that this 16 | // IntentService can perform, e.g. ACTION_FETCH_NEW_ITEMS 17 | public static final String ACTION_FOO = "com.example.notebook.action.FOO"; 18 | public static final String ACTION_BAZ = "com.example.notebook.action.BAZ"; 19 | 20 | // action声明 这里有五个背景音乐 21 | public static final String ACTION_MUSIC_1 = "com.example.notebook.action.music1"; 22 | public static final String ACTION_MUSIC_2 = "com.example.notebook.action.music2"; 23 | public static final String ACTION_MUSIC_3 = "com.example.notebook.action.music3"; 24 | public static final String ACTION_MUSIC_4 = "com.example.notebook.action.music4"; 25 | public static final String ACTION_MUSIC_5 = "com.example.notebook.action.music5"; 26 | public static final String ACTION_MUSIC_6 = "com.example.notebook.action.music6"; 27 | 28 | // TODO: Rename parameters 29 | public static final String EXTRA_PARAM1 = "com.example.notebook.extra.PARAM1"; 30 | public static final String EXTRA_PARAM2 = "com.example.notebook.extra.PARAM2"; 31 | 32 | // 声明MediaPlayer对象 33 | private static MediaPlayer mediaPlayer; 34 | 35 | public MyIntentService() { 36 | super("MyIntentService"); 37 | } 38 | 39 | @Override 40 | protected void onHandleIntent(Intent intent) { 41 | final String action = intent.getAction(); 42 | if (intent != null) { 43 | if (ACTION_FOO.equals(action)) { 44 | final String param1 = intent.getStringExtra(EXTRA_PARAM1); 45 | final String param2 = intent.getStringExtra(EXTRA_PARAM2); 46 | handleActionFoo(param1, param2); 47 | } else if (ACTION_BAZ.equals(action)) { 48 | final String param1 = intent.getStringExtra(EXTRA_PARAM1); 49 | final String param2 = intent.getStringExtra(EXTRA_PARAM2); 50 | handleActionBaz(param1, param2); 51 | } 52 | 53 | // 根据intent设置的action来执行对应服务的操作 54 | if (ACTION_MUSIC_1.equals(action)){ 55 | handleActionMusic1(); 56 | }else if (ACTION_MUSIC_2.equals(action)){ 57 | handleActionMusic2(); 58 | }else if (ACTION_MUSIC_3.equals(action)){ 59 | handleActionMusic3(); 60 | }else if (ACTION_MUSIC_4.equals(action)){ 61 | handleActionMusic4(); 62 | }else if (ACTION_MUSIC_5.equals(action)){ 63 | handleActionMusic5(); 64 | }else if (ACTION_MUSIC_6.equals(action)){ 65 | handleActionMusic6(); 66 | } 67 | } 68 | } 69 | 70 | /** 71 | * 该服务执行的操作用来播放背景音乐 72 | */ 73 | private void handleActionMusic1() { 74 | if(mediaPlayer != null) mediaPlayer.stop(); 75 | // 根据音乐资源文件创建MediaPlayer对象 设置循环播放属性 开始播放 76 | mediaPlayer = MediaPlayer.create(this, R.raw.run); 77 | mediaPlayer.setLooping(true); 78 | mediaPlayer.start(); 79 | } 80 | private void handleActionMusic2() { 81 | if(mediaPlayer != null) mediaPlayer.stop(); 82 | // 根据音乐资源文件创建MediaPlayer对象 设置循环播放属性 开始播放 83 | mediaPlayer = MediaPlayer.create(this, R.raw.dream_wedding); 84 | mediaPlayer.setLooping(true); 85 | mediaPlayer.start(); 86 | } 87 | private void handleActionMusic3() { 88 | if(mediaPlayer != null) mediaPlayer.stop(); 89 | // 根据音乐资源文件创建MediaPlayer对象 设置循环播放属性 开始播放 90 | mediaPlayer = MediaPlayer.create(this, R.raw.be_quiet); 91 | mediaPlayer.setLooping(true); 92 | mediaPlayer.start(); 93 | } 94 | private void handleActionMusic4() { 95 | if(mediaPlayer != null) mediaPlayer.stop(); 96 | // 根据音乐资源文件创建MediaPlayer对象 设置循环播放属性 开始播放 97 | mediaPlayer = MediaPlayer.create(this, R.raw.girly_heart); 98 | mediaPlayer.setLooping(true); 99 | mediaPlayer.start(); 100 | } 101 | private void handleActionMusic5() { 102 | if(mediaPlayer != null) mediaPlayer.stop(); 103 | // 根据音乐资源文件创建MediaPlayer对象 设置循环播放属性 开始播放 104 | mediaPlayer = MediaPlayer.create(this, R.raw.sword_fairy); 105 | mediaPlayer.setLooping(true); 106 | mediaPlayer.start(); 107 | } 108 | private void handleActionMusic6() { 109 | if(mediaPlayer != null) mediaPlayer.stop(); 110 | // 根据音乐资源文件创建MediaPlayer对象 设置循环播放属性 开始播放 111 | mediaPlayer = MediaPlayer.create(this, R.raw.perfect_encounter); 112 | mediaPlayer.setLooping(true); 113 | mediaPlayer.start(); 114 | } 115 | 116 | 117 | /** 118 | * Handle action Foo in the provided background thread with the provided 119 | * parameters. 120 | */ 121 | private void handleActionFoo(String param1, String param2) { 122 | // TODO: Handle action Foo 123 | throw new UnsupportedOperationException("Not yet implemented"); 124 | } 125 | 126 | /** 127 | * Handle action Baz in the provided background thread with the provided 128 | * parameters. 129 | */ 130 | private void handleActionBaz(String param1, String param2) { 131 | // TODO: Handle action Baz 132 | throw new UnsupportedOperationException("Not yet implemented"); 133 | } 134 | } 135 | 136 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/notebook/Note.java: -------------------------------------------------------------------------------- 1 | package com.example.notebook; 2 | 3 | public class Note { 4 | private long id; 5 | private String content; 6 | private String time; 7 | private int tag; 8 | 9 | public Note() { 10 | } 11 | 12 | public Note(String content, String time, int tag) { 13 | this.content = content; 14 | this.time = time; 15 | this.tag = tag; 16 | } 17 | public long getId() { 18 | return id; 19 | } 20 | 21 | //返回笔记的内容 22 | public String getContent() { 23 | return content; 24 | } 25 | 26 | public String getTime() { 27 | return time; 28 | } 29 | 30 | public void setId(long id) { 31 | this.id = id; 32 | } 33 | 34 | public void setContent(String content) { 35 | this.content = content; 36 | } 37 | 38 | public void setTime(String time) { 39 | this.time = time; 40 | } 41 | 42 | 43 | public int getTag() { 44 | return tag; 45 | } 46 | 47 | public void setTag(int tag) { 48 | this.tag = tag; 49 | } 50 | 51 | @Override 52 | public String toString() { 53 | return content + "\n" + time.substring(5,16) + " "+ id; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/notebook/NoteAdapter.java: -------------------------------------------------------------------------------- 1 | package com.example.notebook; 2 | 3 | import android.content.Context; 4 | import android.text.TextUtils; 5 | import android.view.View; 6 | import android.view.ViewGroup; 7 | import android.widget.BaseAdapter; 8 | import android.widget.Filter; 9 | import android.widget.Filterable; 10 | import android.widget.TextView; 11 | 12 | import java.util.ArrayList; 13 | import java.util.List; 14 | 15 | public class NoteAdapter extends BaseAdapter implements Filterable { 16 | private Context mContext; 17 | 18 | private List backList;//用来备份原始数据 19 | private List noteList;//这个数据是会改变的,所以要有个变量来备份一下原始数据 20 | private MyFilter mFilter; 21 | 22 | public NoteAdapter(Context mContext, List noteList) { 23 | this.mContext = mContext; 24 | this.noteList = noteList; 25 | backList = noteList; 26 | } 27 | 28 | @Override 29 | public int getCount() { 30 | return noteList.size(); 31 | } 32 | 33 | @Override 34 | public Object getItem(int position) { 35 | return noteList.get(position); 36 | } 37 | 38 | @Override 39 | public long getItemId(int position) { 40 | return position; 41 | } 42 | 43 | @Override 44 | public View getView(int position, View convertView, ViewGroup parent) { 45 | mContext.setTheme(R.style.AppTheme); 46 | View v = View.inflate(mContext, R.layout.note_layout, null); 47 | TextView tv_content = v.findViewById(R.id.tv_content); 48 | TextView tv_time = v.findViewById(R.id.tv_time); 49 | 50 | //设置文本到TextView 51 | String allText = noteList.get(position).getContent(); 52 | tv_content.setText(allText); 53 | tv_time.setText(noteList.get(position).getTime()); 54 | 55 | //存储笔记到tag 56 | v.setTag(noteList.get(position).getId()); 57 | 58 | return v; 59 | } 60 | 61 | @Override 62 | public Filter getFilter() { 63 | if (mFilter ==null){ 64 | mFilter = new MyFilter(); 65 | } 66 | return mFilter; 67 | } 68 | 69 | 70 | class MyFilter extends Filter { 71 | //在performFiltering这个方法中定义过滤规则 72 | @Override 73 | protected FilterResults performFiltering(CharSequence charSequence) { 74 | FilterResults result = new FilterResults(); 75 | List list; 76 | if (TextUtils.isEmpty(charSequence)) { //当过滤的关键字为空的时候,则显示所有的数据 77 | list = backList; 78 | } else { //否则把符合条件的数据对象添加到集合中 79 | list = new ArrayList<>(); 80 | for (Note note : backList) { 81 | if (note.getContent().contains(charSequence)) { 82 | list.add(note); 83 | } 84 | 85 | } 86 | } 87 | result.values = list; //将得到的集合保存到FilterResults的value变量中 88 | result.count = list.size();//将集合的大小保存到FilterResults的count变量中 89 | 90 | return result; 91 | } 92 | //在publishResults方法中告诉适配器更新界面 93 | @Override 94 | protected void publishResults(CharSequence charSequence, FilterResults filterResults) { 95 | noteList = (List)filterResults.values; 96 | if (filterResults.count>0){ 97 | notifyDataSetChanged();//通知数据发生了改变 98 | }else { 99 | notifyDataSetInvalidated();//通知数据失效 100 | } 101 | } 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/notebook/NoteDatabase.java: -------------------------------------------------------------------------------- 1 | package com.example.notebook; 2 | 3 | import android.content.Context; 4 | import android.database.sqlite.SQLiteDatabase; 5 | import android.database.sqlite.SQLiteOpenHelper; 6 | 7 | 8 | public class NoteDatabase extends SQLiteOpenHelper { 9 | 10 | public static final String TABLE_NAME = "notes"; 11 | public static final String CONTENT = "content"; 12 | public static final String ID = "_id"; 13 | public static final String TIME = "time"; 14 | public static final String MODE = "mode"; 15 | 16 | public NoteDatabase(Context context){ 17 | super(context, "notes", null, 1); 18 | } 19 | 20 | @Override 21 | public void onCreate(SQLiteDatabase db) { 22 | db.execSQL("CREATE TABLE "+ TABLE_NAME 23 | + "(" 24 | + ID + " INTEGER PRIMARY KEY AUTOINCREMENT," 25 | + CONTENT + " TEXT NOT NULL," 26 | + TIME + " TEXT NOT NULL," 27 | + MODE + " INTEGER DEFAULT 1)" 28 | ); 29 | } 30 | 31 | @Override 32 | public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { 33 | 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /app/src/main/res/anim/in_lefttoright.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 8 | -------------------------------------------------------------------------------- /app/src/main/res/anim/in_righttoleft.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/anim/in_slow.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | -------------------------------------------------------------------------------- /app/src/main/res/anim/night_switch.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | -------------------------------------------------------------------------------- /app/src/main/res/anim/night_switch_over.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | -------------------------------------------------------------------------------- /app/src/main/res/anim/no.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /app/src/main/res/anim/out_lefttoright.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/anim/out_righttoleft.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 8 | -------------------------------------------------------------------------------- /app/src/main/res/anim/out_slow.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-v24/alarm_24.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Southpost/NoteBook/2182961b3922e4b0b65cee30e4d25fad3ce9abee/app/src/main/res/drawable-v24/alarm_24.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-v24/bgd.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Southpost/NoteBook/2182961b3922e4b0b65cee30e4d25fad3ce9abee/app/src/main/res/drawable-v24/bgd.jpg -------------------------------------------------------------------------------- /app/src/main/res/drawable-v24/ic_launcher_foreground.xml: -------------------------------------------------------------------------------- 1 | 7 | 8 | 9 | 15 | 18 | 21 | 22 | 23 | 24 | 30 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-v24/music_collection.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Southpost/NoteBook/2182961b3922e4b0b65cee30e4d25fad3ce9abee/app/src/main/res/drawable-v24/music_collection.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-v24/note_shape.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-v24/skin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Southpost/NoteBook/2182961b3922e4b0b65cee30e4d25fad3ce9abee/app/src/main/res/drawable-v24/skin.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-v24/tomato.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Southpost/NoteBook/2182961b3922e4b0b65cee30e4d25fad3ce9abee/app/src/main/res/drawable-v24/tomato.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_baseline_add_24.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_baseline_add_circle_outline_24.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_baseline_create_24.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_baseline_delete_24.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_baseline_keyboard_voice_24.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_baseline_library_music_24.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_baseline_list_24.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_baseline_menu_book_24.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_baseline_search_24.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_baseline_settings_24.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_create_24.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_delete_all_24.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_error_outline_black_24dp.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_keyboard_arrow_left_black_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_launcher_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 10 | 15 | 20 | 25 | 30 | 35 | 40 | 45 | 50 | 55 | 60 | 65 | 70 | 75 | 80 | 85 | 90 | 95 | 100 | 105 | 110 | 115 | 120 | 125 | 130 | 135 | 140 | 145 | 150 | 155 | 160 | 165 | 170 | 171 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_menu_24.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_menu_black_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_notifications_black_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/red_alarm_24dp.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/top_button_shap.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_edit.xml: -------------------------------------------------------------------------------- 1 | 2 | 12 | 13 | 22 | 23 | 30 | 31 | 35 |