diff --git a/SparrowNotes/.gitignore b/SparrowNotes/.gitignore
new file mode 100644
index 0000000..603b140
--- /dev/null
+++ b/SparrowNotes/.gitignore
@@ -0,0 +1,14 @@
+*.iml
+.gradle
+/local.properties
+/.idea/caches
+/.idea/libraries
+/.idea/modules.xml
+/.idea/workspace.xml
+/.idea/navEditor.xml
+/.idea/assetWizardSettings.xml
+.DS_Store
+/build
+/captures
+.externalNativeBuild
+.cxx
diff --git a/SparrowNotes/.idea/.gitignore b/SparrowNotes/.idea/.gitignore
new file mode 100644
index 0000000..26d3352
--- /dev/null
+++ b/SparrowNotes/.idea/.gitignore
@@ -0,0 +1,3 @@
+# Default ignored files
+/shelf/
+/workspace.xml
diff --git a/SparrowNotes/.idea/compiler.xml b/SparrowNotes/.idea/compiler.xml
new file mode 100644
index 0000000..fb7f4a8
--- /dev/null
+++ b/SparrowNotes/.idea/compiler.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/SparrowNotes/.idea/dbnavigator.xml b/SparrowNotes/.idea/dbnavigator.xml
new file mode 100644
index 0000000..e564949
--- /dev/null
+++ b/SparrowNotes/.idea/dbnavigator.xml
@@ -0,0 +1,514 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/SparrowNotes/.idea/deploymentTargetDropDown.xml b/SparrowNotes/.idea/deploymentTargetDropDown.xml
new file mode 100644
index 0000000..ad97315
--- /dev/null
+++ b/SparrowNotes/.idea/deploymentTargetDropDown.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/SparrowNotes/.idea/gradle.xml b/SparrowNotes/.idea/gradle.xml
new file mode 100644
index 0000000..a2d7c21
--- /dev/null
+++ b/SparrowNotes/.idea/gradle.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/SparrowNotes/.idea/jarRepositories.xml b/SparrowNotes/.idea/jarRepositories.xml
new file mode 100644
index 0000000..a5f05cd
--- /dev/null
+++ b/SparrowNotes/.idea/jarRepositories.xml
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/SparrowNotes/.idea/misc.xml b/SparrowNotes/.idea/misc.xml
new file mode 100644
index 0000000..bdd9278
--- /dev/null
+++ b/SparrowNotes/.idea/misc.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/SparrowNotes/app/.gitignore b/SparrowNotes/app/.gitignore
new file mode 100644
index 0000000..42afabf
--- /dev/null
+++ b/SparrowNotes/app/.gitignore
@@ -0,0 +1 @@
+/build
\ No newline at end of file
diff --git a/SparrowNotes/app/build.gradle b/SparrowNotes/app/build.gradle
new file mode 100644
index 0000000..22454f6
--- /dev/null
+++ b/SparrowNotes/app/build.gradle
@@ -0,0 +1,50 @@
+apply plugin: 'com.android.application'
+apply plugin: 'com.jakewharton.butterknife'
+
+android {
+ compileSdkVersion 29
+ buildToolsVersion "29.0.3"
+
+ defaultConfig {
+ applicationId "com.example.sparrownotes"
+ minSdkVersion 19
+ targetSdkVersion 29
+ versionCode 1
+ versionName "1.0"
+
+ testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
+ }
+
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
+ }
+ }
+ // ButterKnife requires Java 8
+ compileOptions {
+ sourceCompatibility JavaVersion.VERSION_1_8
+ targetCompatibility JavaVersion.VERSION_1_8
+ }
+}
+
+dependencies {
+ implementation fileTree(dir: "libs", include: ["*.jar"])
+ implementation 'androidx.appcompat:appcompat:1.1.0'
+ implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
+ implementation 'com.google.android.material:material:1.1.0'
+ // 黄油刀
+ implementation 'com.jakewharton:butterknife:10.2.1'
+ implementation fileTree(dir: 'libs', include: ['*.aar', '*.jar'], exclude: [])
+ implementation 'androidx.legacy:legacy-support-v4:1.0.0'
+ // 圆形头像
+ implementation 'de.hdodenhof:circleimageview:3.1.0'
+ // 黄油刀
+ annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.1'
+ testImplementation 'junit:junit:4.12'
+ androidTestImplementation 'androidx.test.ext:junit:1.1.1'
+ androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
+ // Glide 图片加载框架
+ implementation 'com.github.bumptech.glide:glide:3.7.0'
+
+}
\ No newline at end of file
diff --git a/SparrowNotes/app/libs/ormlite-android-5.1.jar b/SparrowNotes/app/libs/ormlite-android-5.1.jar
new file mode 100644
index 0000000..ae5ef53
Binary files /dev/null and b/SparrowNotes/app/libs/ormlite-android-5.1.jar differ
diff --git a/SparrowNotes/app/libs/ormlite-core-5.1.jar b/SparrowNotes/app/libs/ormlite-core-5.1.jar
new file mode 100644
index 0000000..9490c44
Binary files /dev/null and b/SparrowNotes/app/libs/ormlite-core-5.1.jar differ
diff --git a/SparrowNotes/app/proguard-rules.pro b/SparrowNotes/app/proguard-rules.pro
new file mode 100644
index 0000000..481bb43
--- /dev/null
+++ b/SparrowNotes/app/proguard-rules.pro
@@ -0,0 +1,21 @@
+# Add project specific ProGuard rules here.
+# You can control the set of applied configuration files using the
+# proguardFiles setting in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+# public *;
+#}
+
+# Uncomment this to preserve the line number information for
+# debugging stack traces.
+#-keepattributes SourceFile,LineNumberTable
+
+# If you keep the line number information, uncomment this to
+# hide the original source file name.
+#-renamesourcefileattribute SourceFile
\ No newline at end of file
diff --git a/SparrowNotes/app/src/androidTest/java/com/example/sparrownotes/ExampleInstrumentedTest.java b/SparrowNotes/app/src/androidTest/java/com/example/sparrownotes/ExampleInstrumentedTest.java
new file mode 100644
index 0000000..5f40d34
--- /dev/null
+++ b/SparrowNotes/app/src/androidTest/java/com/example/sparrownotes/ExampleInstrumentedTest.java
@@ -0,0 +1,26 @@
+package com.example.sparrownotes;
+
+import android.content.Context;
+
+import androidx.test.platform.app.InstrumentationRegistry;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import static org.junit.Assert.*;
+
+/**
+ * Instrumented test, which will execute on an Android device.
+ *
+ * @see Testing documentation
+ */
+@RunWith(AndroidJUnit4.class)
+public class ExampleInstrumentedTest {
+ @Test
+ public void useAppContext() {
+ // Context of the app under test.
+ Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
+ assertEquals("com.example.sparrownotes", appContext.getPackageName());
+ }
+}
\ No newline at end of file
diff --git a/SparrowNotes/app/src/main/AndroidManifest.xml b/SparrowNotes/app/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..807223b
--- /dev/null
+++ b/SparrowNotes/app/src/main/AndroidManifest.xml
@@ -0,0 +1,28 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/SparrowNotes/app/src/main/java/com/example/sparrownotes/FindPwdActivity.java b/SparrowNotes/app/src/main/java/com/example/sparrownotes/FindPwdActivity.java
new file mode 100644
index 0000000..aad4996
--- /dev/null
+++ b/SparrowNotes/app/src/main/java/com/example/sparrownotes/FindPwdActivity.java
@@ -0,0 +1,180 @@
+package com.example.sparrownotes;
+
+import android.content.Intent;
+import android.os.Bundle;
+import android.text.method.HideReturnsTransformationMethod;
+import android.text.method.PasswordTransformationMethod;
+import android.util.Log;
+import android.view.View;
+import android.widget.Button;
+import android.widget.CheckBox;
+import android.widget.EditText;
+import android.widget.Toast;
+
+import androidx.appcompat.app.AppCompatActivity;
+
+import com.example.sparrownotes.bean.UserBean;
+import com.example.sparrownotes.dao.*;
+import com.example.sparrownotes.util.Constant;
+
+import java.util.List;
+import java.util.regex.Matcher;
+
+import butterknife.BindView;
+import butterknife.ButterKnife;
+import butterknife.OnClick;
+
+/**
+ * 找回密码
+ */
+public class FindPwdActivity extends AppCompatActivity {
+
+ @BindView(R.id.btn_confirm_find)
+ Button btnConfirmFind;
+ @BindView(R.id.btn_reset_find)
+ Button btnResetFind;
+ @BindView(R.id.edit_confirm_pwd_find)
+ EditText editConfirmPwdFind;
+ @BindView(R.id.edit_password_find)
+ EditText editPasswordFind;
+ @BindView(R.id.edit_email_find)
+ EditText editEmailFind;
+ @BindView(R.id.check_hide_pwd_find)
+ CheckBox checkHidePwdFind;
+ @BindView(R.id.check_hide_pwd_find2)
+ CheckBox checkHidePwdFind2;
+
+ private static final String TAG = "FindPwdActivity";
+ private UserDao userDao;
+ private String textPassword;
+ private String textConfirmPwd;
+ private String textEmail;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_find_pwd);
+ ButterKnife.bind(this);
+ userDao = new UserDao(this);
+ }
+
+ @OnClick({R.id.btn_confirm_find, R.id.btn_reset_find, R.id.check_hide_pwd_find, R.id.check_hide_pwd_find2})
+ public void onViewClicked(View view) {
+ switch (view.getId()) {
+ case R.id.btn_confirm_find:
+ // 检查非空
+ if (isNotEmpty()) {
+ // 获得用户输入
+ getEditText();
+ // 检查邮箱格式
+ if (checkEmail()) {
+ // 检查两次输入的密码是否一致
+ if (comparePwd()) {
+ // 更新密码
+ if (updatePwdFromDB()) {
+ // 跳转登录界面
+ Intent intent = new Intent(FindPwdActivity.this, MainActivity.class);
+ startActivity(intent);
+ FindPwdActivity.this.finish();
+ }
+ } else {
+ Toast.makeText(this, "两次输入的密码不一致", Toast.LENGTH_SHORT).show();
+ }
+ } else {
+ Toast.makeText(this, "邮箱格式错误", Toast.LENGTH_SHORT).show();
+ }
+ } else {
+ Toast.makeText(this, "邮箱或密码不能为空", Toast.LENGTH_SHORT).show();
+ }
+ break;
+ case R.id.btn_reset_find:
+ // 清空输入
+ editPasswordFind.setText("");
+ editConfirmPwdFind.setText("");
+ editEmailFind.setText("");
+ break;
+ case R.id.check_hide_pwd_find:
+ if (checkHidePwdFind.isChecked()) {
+ // 将密码显示出来
+ editPasswordFind.setTransformationMethod(HideReturnsTransformationMethod.getInstance());
+ } else {
+ // 隐藏密码
+ editPasswordFind.setTransformationMethod(PasswordTransformationMethod.getInstance());
+ }
+ // 将光标移动到文本最后
+ editPasswordFind.setSelection(editPasswordFind.getText().toString().length());
+ break;
+ case R.id.check_hide_pwd_find2:
+ if (checkHidePwdFind2.isChecked()) {
+ // 将密码显示出来
+ editConfirmPwdFind.setTransformationMethod(HideReturnsTransformationMethod.getInstance());
+ } else {
+ // 隐藏密码
+ editConfirmPwdFind.setTransformationMethod(PasswordTransformationMethod.getInstance());
+ }
+ // 将光标移动到文本最后
+ editConfirmPwdFind.setSelection(editConfirmPwdFind.getText().toString().length());
+ break;
+ default:
+ break;
+ }
+ }
+
+ /**
+ * 检验输入非空
+ *
+ * @return
+ */
+ public boolean isNotEmpty() {
+ return !"".equals(editPasswordFind.getText().toString()) &&
+ !"".equals(editConfirmPwdFind.getText().toString()) &&
+ !"".equals(editEmailFind.getText().toString());
+ }
+
+ /**
+ * 从控件中得到输入值
+ */
+ public void getEditText() {
+ textPassword = editPasswordFind.getText().toString();
+ textConfirmPwd = editConfirmPwdFind.getText().toString();
+ textEmail = editEmailFind.getText().toString();
+ Log.d(TAG, "getEditText: " + textEmail);
+ }
+
+ /**
+ * 检查邮箱格式
+ *
+ * @return
+ */
+ public boolean checkEmail() {
+ Matcher emailMatcher = Constant.EMAIL_PATTERN.matcher(textEmail);
+ return emailMatcher.matches();
+ }
+
+ /**
+ * 验证两次输入的密码是否一致
+ *
+ * @return
+ */
+ public boolean comparePwd() {
+ return textPassword.equals(textConfirmPwd);
+ }
+
+ /**
+ * 修改数据库中的密码
+ *
+ * @return 邮箱是否存在
+ */
+ public boolean updatePwdFromDB() {
+ List userBeans = userDao.queryForWhat("email", textEmail);
+ if (userBeans.size() != 0) {
+ UserBean user = userBeans.get(0);
+ user.setPassword(textPassword);
+ userDao.update(user);
+ return true;
+ } else {
+ Toast.makeText(this, "邮箱错误", Toast.LENGTH_SHORT).show();
+ return false;
+ }
+ }
+}
\ No newline at end of file
diff --git a/SparrowNotes/app/src/main/java/com/example/sparrownotes/HomeActivity.java b/SparrowNotes/app/src/main/java/com/example/sparrownotes/HomeActivity.java
new file mode 100644
index 0000000..5ad6303
--- /dev/null
+++ b/SparrowNotes/app/src/main/java/com/example/sparrownotes/HomeActivity.java
@@ -0,0 +1,280 @@
+package com.example.sparrownotes;
+
+import android.content.Intent;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.Handler;
+
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.CompoundButton;
+import android.widget.RadioButton;
+import android.widget.RadioGroup;
+import android.widget.TextView;
+
+import androidx.annotation.NonNull;
+import androidx.appcompat.app.ActionBar;
+import androidx.appcompat.app.AppCompatActivity;
+import androidx.appcompat.widget.Toolbar;
+import androidx.core.view.GravityCompat;
+import androidx.drawerlayout.widget.DrawerLayout;
+import androidx.fragment.app.Fragment;
+import androidx.fragment.app.FragmentManager;
+import androidx.fragment.app.FragmentTransaction;
+
+import com.example.sparrownotes.bean.UserBean;
+import com.example.sparrownotes.dao.*;
+import com.example.sparrownotes.fragment.AddFragment;
+import com.example.sparrownotes.fragment.AllFragment;
+import com.example.sparrownotes.fragment.TopFragment;
+import com.example.sparrownotes.util.Constant;
+import com.example.sparrownotes.util.DialogUtil;
+import com.example.sparrownotes.util.SharedPreferenceUtil;
+import com.google.android.material.navigation.NavigationView;
+
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.List;
+
+import butterknife.BindView;
+import butterknife.ButterKnife;
+import butterknife.OnCheckedChanged;
+
+
+/**
+ * 主页
+ */
+public class HomeActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener {
+
+ @BindView(R.id.toolbar)
+ Toolbar toolbar;
+ @BindView(R.id.btn_top)
+ RadioButton btnTop;
+ @BindView(R.id.btn_add)
+ RadioButton btnAdd;
+ @BindView(R.id.btn_all)
+ RadioButton btnAll;
+ @BindView(R.id.dock_radio_group)
+ RadioGroup dockRadioGroup;
+ @BindView(R.id.drawer_layout)
+ DrawerLayout drawerLayout;
+ @BindView(R.id.nav_view)
+ NavigationView navView;
+
+ private static final String TAG = "HomeActivity";
+ ActionBar actionBar;
+ Fragment fragment;
+ FragmentManager manager = getSupportFragmentManager();
+ FragmentTransaction transaction = manager.beginTransaction();
+ SharedPreferenceUtil spu;
+ private UserDao userDao;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_home);
+ ButterKnife.bind(this);
+ userDao = new UserDao(this);
+ spu = SharedPreferenceUtil.getInstance(this);
+ initView();
+ }
+
+ /**
+ * 初始化控件
+ */
+ public void initView() {
+ // 工具栏
+ toolbar.setTitle(R.string.app_name);
+ setTitleCenter(toolbar);
+ setSupportActionBar(toolbar);
+ actionBar = getSupportActionBar();
+ if (actionBar != null) {
+ actionBar.setDisplayHomeAsUpEnabled(true);
+ actionBar.setHomeAsUpIndicator(R.drawable.icon_setting);
+ }
+ // 抽屉
+ ViewGroup.LayoutParams params = navView.getLayoutParams();
+ params.width = getResources().getDisplayMetrics().widthPixels / 2;
+ navView.setLayoutParams(params);
+ navView.setNavigationItemSelectedListener(this);
+ // 抽屉中的header
+ View headerView = navView.getHeaderView(0);
+ TextView textUserName = headerView.findViewById(R.id.header_user_name);
+ TextView textEmail = headerView.findViewById(R.id.header_email);
+ textUserName.setText(spu.getString(Constant.USER_NAME));
+ textEmail.setText(getEmail());
+ // 默认加载置顶Fragment
+ fragment = new TopFragment();
+ transaction.replace(R.id.view_pager, fragment, Constant.TOP_TAG);
+ transaction.commit();
+ }
+
+ /**
+ * 单选按钮监听器 用来切换Fragment
+ *
+ * @param view
+ * @param isChanged
+ */
+ @OnCheckedChanged({R.id.btn_add, R.id.btn_all, R.id.btn_top})
+ public void onCheckedChanged(CompoundButton view, boolean isChanged) {
+ transaction = manager.beginTransaction();
+ switch (view.getId()) {
+ case R.id.btn_top:
+ if (isChanged) {
+ fragment = new TopFragment();
+ transaction.replace(R.id.view_pager, fragment, Constant.TOP_TAG);
+ transaction.commit();
+ Constant.PAGE_STATE = "top";
+ }
+ break;
+ case R.id.btn_add:
+ if (isChanged) {
+ fragment = new AddFragment();
+ transaction.replace(R.id.view_pager, fragment, Constant.ADD_TAG);
+ transaction.commit();
+ }
+ break;
+ case R.id.btn_all:
+ if (isChanged) {
+ fragment = new AllFragment();
+ transaction.replace(R.id.view_pager, fragment, Constant.LIST_TAG);
+ transaction.commit();
+ Constant.PAGE_STATE = "all";
+ }
+ break;
+ default:
+ break;
+ }
+ }
+
+ /**
+ * 获得登录用户的邮箱
+ *
+ * @return
+ */
+ public String getEmail() {
+ List userBeans = userDao
+ .queryByUserNameAndPassword(spu.getString(Constant.USER_NAME), spu.getString(Constant.PASSWORD));
+ return userBeans.get(0).getEmail();
+ }
+
+ /**
+ * 抽屉中菜单的点击事件
+ *
+ * @param item
+ * @return
+ */
+ @Override
+ public boolean onNavigationItemSelected(@NonNull MenuItem item) {
+ drawerLayout.closeDrawers();
+ switch (item.getItemId()) {
+ case R.id.nav_change_pwd:
+ DialogUtil.editInfoDialog(this, spu.getInt(Constant.USER_ID));
+ break;
+ case R.id.nav_dismiss:
+ DialogUtil.dismissDialog(this, spu.getInt(Constant.USER_ID));
+ break;
+ case R.id.nav_exit:
+ spu.putBoolean(Constant.AUTO_LOGIN, false);
+ Intent intent = new Intent(HomeActivity.this, MainActivity.class);
+ startActivity(intent);
+ finish();
+ break;
+
+ default:
+ break;
+ }
+ return true;
+ }
+
+ /**
+ * ToolBar的menu
+ *
+ * @param menu
+ * @return
+ */
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ getMenuInflater().inflate(R.menu.toolbar_menu, menu);
+ setIconsVisible(menu, true);
+ return true;
+ }
+
+ /**
+ * 重写ToolBar上菜单点击事件
+ * 按照条件查找
+ *
+ * @param item
+ * @return
+ */
+ @Override
+ public boolean onOptionsItemSelected(@NonNull MenuItem item) {
+ switch (item.getItemId()) {
+ case R.id.search_title:
+ DialogUtil.searchTitleDialog(this);
+ break;
+ case R.id.search_content:
+ DialogUtil.searchContentDialog(this);
+ break;
+ case R.id.search_category:
+ DialogUtil.searchCategoryDialog(this);
+ break;
+ case android.R.id.home:
+ drawerLayout.openDrawer(GravityCompat.START);
+ break;
+ default:
+ break;
+ }
+ return true;
+ }
+
+ /**
+ * ToolBar标题居中
+ *
+ * @param toolbar
+ */
+ public void setTitleCenter(Toolbar toolbar) {
+ String title = "title";
+ final CharSequence originalTitle = toolbar.getTitle();
+ toolbar.setTitle(title);
+ for (int i = 0; i < toolbar.getChildCount(); i++) {
+ View view = toolbar.getChildAt(i);
+ if (view instanceof TextView) {
+ TextView textView = (TextView) view;
+ if (title.equals(textView.getText())) {
+ textView.setGravity(Gravity.CENTER);
+ Toolbar.LayoutParams params = new Toolbar.LayoutParams(Toolbar.LayoutParams.WRAP_CONTENT, Toolbar.LayoutParams.MATCH_PARENT);
+ params.gravity = Gravity.CENTER;
+ textView.setLayoutParams(params);
+ }
+ }
+ toolbar.setTitle(originalTitle);
+ }
+ }
+
+ /**
+ * menu显示图标
+ *
+ * @param menu
+ * @param flag
+ */
+ private void setIconsVisible(Menu menu, boolean flag) {
+ // 判断menu是否为空
+ if (menu != null) {
+ try {
+ // 如果不为空,就反射拿到menu的setOptionalIconsVisible方法
+ Method method = menu.getClass().getDeclaredMethod("setOptionalIconsVisible", Boolean.TYPE);
+ // 暴力访问该方法
+ method.setAccessible(true);
+ // 调用该方法显示icon
+ method.invoke(menu, flag);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/SparrowNotes/app/src/main/java/com/example/sparrownotes/MainActivity.java b/SparrowNotes/app/src/main/java/com/example/sparrownotes/MainActivity.java
new file mode 100644
index 0000000..ebeeac2
--- /dev/null
+++ b/SparrowNotes/app/src/main/java/com/example/sparrownotes/MainActivity.java
@@ -0,0 +1,205 @@
+package com.example.sparrownotes;
+
+import android.content.Intent;
+import android.os.Bundle;
+import android.text.method.HideReturnsTransformationMethod;
+import android.text.method.PasswordTransformationMethod;
+import android.view.View;
+import android.widget.Button;
+import android.widget.CheckBox;
+import android.widget.EditText;
+import android.widget.ImageView;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import androidx.appcompat.app.AppCompatActivity;
+
+import com.example.sparrownotes.bean.UserBean;
+import com.example.sparrownotes.dao.*;
+import com.example.sparrownotes.util.Constant;
+import com.example.sparrownotes.util.SharedPreferenceUtil;
+
+import java.util.List;
+
+import butterknife.BindView;
+import butterknife.ButterKnife;
+import butterknife.OnClick;
+
+/**
+ * 登录页面
+ */
+public class MainActivity extends AppCompatActivity {
+
+ @BindView(R.id.img_icon)
+ ImageView imgIcon;
+ @BindView(R.id.check_auto_login)
+ CheckBox checkAutoLogin;
+ @BindView(R.id.check_remember_pwd)
+ CheckBox checkRememberPwd;
+ @BindView(R.id.text_forget_pwd)
+ TextView textForgetPwd;
+ @BindView(R.id.btn_login)
+ Button btnLogin;
+ @BindView(R.id.edit_username)
+ EditText editUsername;
+ @BindView(R.id.edit_password)
+ EditText editPassword;
+ @BindView(R.id.text_register)
+ TextView textRegister;
+ @BindView(R.id.check_hide_pwd)
+ CheckBox checkHidePwd;
+
+ private static final String TAG = "MainActivity";
+ private UserDao userDao;
+ private String textUserName;
+ private String textPassword;
+
+ private static boolean REMEMBER_PWD = false;
+ private static boolean AUTO_LOGIN = false;
+ SharedPreferenceUtil spu;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_main);
+ ButterKnife.bind(this);
+ userDao = new UserDao(this);
+ spu = SharedPreferenceUtil.getInstance(this);
+ }
+
+ @Override
+ protected void onStart() {
+ super.onStart();
+ Intent intent = getIntent();
+ // 如果注册过
+ if (intent.getBooleanExtra(Constant.HAS_REGISTERED, false)) {
+ intent.removeExtra(Constant.HAS_REGISTERED);
+ editUsername.setText(spu.getString(Constant.USER_NAME));
+ editPassword.setText(spu.getString(Constant.PASSWORD));
+ } else {
+ // 如果勾选记住密码
+ if (spu.getBoolean(Constant.REMEMBER_PWD)) {
+ checkRememberPwd.setChecked(true);
+ editUsername.setText(spu.getString(Constant.USER_NAME));
+ editPassword.setText(spu.getString(Constant.PASSWORD));
+ } else {
+ editUsername.setText("");
+ editPassword.setText("");
+ }
+ // 如果勾选自动登录
+ if (spu.getBoolean(Constant.AUTO_LOGIN)) {
+ checkAutoLogin.setChecked(true);
+ Intent intentLogin = new Intent(MainActivity.this, HomeActivity.class);
+ startActivity(intentLogin);
+ }
+ }
+ }
+
+ @OnClick({R.id.check_auto_login, R.id.check_remember_pwd, R.id.btn_login, R.id.text_forget_pwd, R.id.text_register, R.id.check_hide_pwd})
+ public void onViewClicked(View view) {
+ switch (view.getId()) {
+ case R.id.check_auto_login:
+ // 勾选自动登录时自动勾选记住密码
+ if (checkAutoLogin.isChecked()) {
+ checkRememberPwd.setChecked(true);
+ AUTO_LOGIN = true;
+ REMEMBER_PWD = true;
+ } else {
+ AUTO_LOGIN = false;
+ }
+ break;
+ case R.id.check_remember_pwd:
+ // 勾掉记住密码时自动勾掉自动登录
+ if (!checkRememberPwd.isChecked()) {
+ checkAutoLogin.setChecked(false);
+ AUTO_LOGIN = false;
+ REMEMBER_PWD = false;
+ } else {
+ REMEMBER_PWD = true;
+ }
+ break;
+ case R.id.btn_login:
+ // 检查非空
+ if (isNotEmpty()) {
+ // 获得用户输入
+ getEditText();
+ // 检查用户名密码
+ if (checkUser()) {
+ // 存入sp 用于接下来页面的显示
+ spu.putBoolean(Constant.REMEMBER_PWD, REMEMBER_PWD);
+ spu.putBoolean(Constant.AUTO_LOGIN, AUTO_LOGIN);
+ spu.putString(Constant.USER_NAME, textUserName);
+ spu.putString(Constant.PASSWORD, textPassword);
+ spu.putInt(Constant.USER_ID, getUserID());
+ Intent intentLogin = new Intent(MainActivity.this, HomeActivity.class);
+ startActivity(intentLogin);
+ finish();
+ } else {
+ Toast.makeText(this, "用户名或密码错误", Toast.LENGTH_SHORT).show();
+ }
+ } else {
+ Toast.makeText(this, "用户名或密码不能为空", Toast.LENGTH_SHORT).show();
+ }
+ break;
+ case R.id.text_forget_pwd:
+ // 忘记密码
+ Intent intentFind = new Intent(MainActivity.this, FindPwdActivity.class);
+ startActivity(intentFind);
+ break;
+ case R.id.text_register:
+ // 注册
+ Intent intentRegister = new Intent(MainActivity.this, RegisterActivity.class);
+ startActivity(intentRegister);
+ break;
+ case R.id.check_hide_pwd:
+ if (checkHidePwd.isChecked()) {
+ // 将密码显示出来
+ editPassword.setTransformationMethod(HideReturnsTransformationMethod.getInstance());
+ } else {
+ // 隐藏密码
+ editPassword.setTransformationMethod(PasswordTransformationMethod.getInstance());
+ }
+ // 将光标移动到文本最后
+ editPassword.setSelection(editPassword.getText().toString().length());
+ break;
+ default:
+ break;
+ }
+ }
+
+ /**
+ * 检验输入非空
+ *
+ * @return
+ */
+ public boolean isNotEmpty() {
+ return !"".equals(editUsername.getText().toString()) &&
+ !"".equals(editPassword.getText().toString());
+ }
+
+ /**
+ * 从控件中得到输入值
+ */
+ public void getEditText() {
+ textUserName = editUsername.getText().toString();
+ textPassword = editPassword.getText().toString();
+ }
+
+ /**
+ * 验证用户名密码
+ */
+ public boolean checkUser() {
+ List userBeans = userDao.queryByUserNameAndPassword(textUserName, textPassword);
+ return userBeans.size() != 0;
+ }
+
+ /**
+ * 获得用户ID
+ *
+ * @return
+ */
+ public int getUserID() {
+ List userBeans = userDao.queryByUserNameAndPassword(textUserName, textPassword);
+ return userBeans.get(0).getUserID();
+ }
+}
\ No newline at end of file
diff --git a/SparrowNotes/app/src/main/java/com/example/sparrownotes/RegisterActivity.java b/SparrowNotes/app/src/main/java/com/example/sparrownotes/RegisterActivity.java
new file mode 100644
index 0000000..afdf07c
--- /dev/null
+++ b/SparrowNotes/app/src/main/java/com/example/sparrownotes/RegisterActivity.java
@@ -0,0 +1,203 @@
+package com.example.sparrownotes;
+
+import android.content.Intent;
+import android.os.Bundle;
+import android.text.method.HideReturnsTransformationMethod;
+import android.text.method.PasswordTransformationMethod;
+import android.util.Log;
+import android.view.View;
+import android.widget.Button;
+import android.widget.CheckBox;
+import android.widget.EditText;
+import android.widget.Toast;
+
+import androidx.appcompat.app.AppCompatActivity;
+
+import com.example.sparrownotes.bean.UserBean;
+import com.example.sparrownotes.dao.*;
+import com.example.sparrownotes.util.Constant;
+import com.example.sparrownotes.util.SharedPreferenceUtil;
+
+import java.util.List;
+import java.util.regex.Matcher;
+
+import butterknife.BindView;
+import butterknife.ButterKnife;
+import butterknife.OnClick;
+
+/**
+ * 注册页面
+ */
+public class RegisterActivity extends AppCompatActivity {
+
+ @BindView(R.id.btn_register)
+ Button btnRegister;
+ @BindView(R.id.btn_reset)
+ Button btnReset;
+ @BindView(R.id.check_hide_pwd_reg)
+ CheckBox checkHidePwdReg;
+ @BindView(R.id.check_hide_pwd_reg2)
+ CheckBox checkHidePwdReg2;
+ @BindView(R.id.edit_username_reg)
+ EditText editUsernameReg;
+ @BindView(R.id.edit_confirm_pwd_reg)
+ EditText editConfirmPwdReg;
+ @BindView(R.id.edit_email_reg)
+ EditText editEmailReg;
+ @BindView(R.id.edit_password_reg)
+ EditText editPasswordReg;
+
+ SharedPreferenceUtil spu;
+ private static final String TAG = "RegisterActivity";
+ private UserDao userDao;
+ private String textUserName;
+ private String textPassword;
+ private String textConfirmPwd;
+ private String textEmail;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_register);
+ ButterKnife.bind(this);
+ userDao = new UserDao(this);
+ spu = SharedPreferenceUtil.getInstance(this);
+ }
+
+ @OnClick({R.id.btn_register, R.id.btn_reset, R.id.check_hide_pwd_reg, R.id.check_hide_pwd_reg2})
+ public void onViewClicked(View view) {
+ switch (view.getId()) {
+ case R.id.btn_register:
+ // 检验非空
+ if (isNotEmpty()) {
+ // 获得用户输入
+ getEditText();
+ // 检验密码
+ if (comparePwd()) {
+ // 检查邮箱格式
+ if (checkEmail()) {
+ // 检查邮箱是否可用
+ if (checkOnlyEmail()) {
+ insertUserIntoDB();
+ queryAll();
+ Intent intent = new Intent(RegisterActivity.this, MainActivity.class);
+ intent.putExtra(Constant.HAS_REGISTERED, true);
+ startActivity(intent);
+ finish();
+ } else {
+ Toast.makeText(this, "邮箱已经被使用", Toast.LENGTH_SHORT).show();
+ }
+ } else {
+ Toast.makeText(this, "邮箱格式错误", Toast.LENGTH_SHORT).show();
+ }
+ } else {
+ Toast.makeText(this, "两次输入的密码不一致", Toast.LENGTH_SHORT).show();
+ }
+ } else {
+ Toast.makeText(this, "用户名或密码不能为空", Toast.LENGTH_SHORT).show();
+ }
+ break;
+ case R.id.btn_reset:
+ editUsernameReg.setText("");
+ editPasswordReg.setText("");
+ editConfirmPwdReg.setText("");
+ editEmailReg.setText("");
+ break;
+ case R.id.check_hide_pwd_reg:
+ if (checkHidePwdReg.isChecked()) {
+ // 将密码显示出来
+ editPasswordReg.setTransformationMethod(HideReturnsTransformationMethod.getInstance());
+ } else {
+ // 隐藏密码
+ editPasswordReg.setTransformationMethod(PasswordTransformationMethod.getInstance());
+ }
+ // 将光标移动到文本最后
+ editPasswordReg.setSelection(editPasswordReg.getText().toString().length());
+ break;
+ case R.id.check_hide_pwd_reg2:
+ if (checkHidePwdReg2.isChecked()) {
+ // 将密码显示出来
+ editConfirmPwdReg.setTransformationMethod(HideReturnsTransformationMethod.getInstance());
+ } else {
+ // 隐藏密码
+ editConfirmPwdReg.setTransformationMethod(PasswordTransformationMethod.getInstance());
+ }
+ // 将光标移动到文本最后
+ editConfirmPwdReg.setSelection(editConfirmPwdReg.getText().toString().length());
+ break;
+ default:
+ break;
+ }
+ }
+
+ /**
+ * 检验输入非空
+ *
+ * @return
+ */
+ public boolean isNotEmpty() {
+ return !"".equals(editUsernameReg.getText().toString()) &&
+ !"".equals(editPasswordReg.getText().toString()) &&
+ !"".equals(editConfirmPwdReg.getText().toString());
+ }
+
+ /**
+ * 从控件中得到输入值
+ */
+ public void getEditText() {
+ textUserName = editUsernameReg.getText().toString();
+ textPassword = editPasswordReg.getText().toString();
+ textConfirmPwd = editConfirmPwdReg.getText().toString();
+ textEmail = editEmailReg.getText().toString();
+ }
+
+ /**
+ * 检查邮箱是否可用
+ *
+ * @return
+ */
+ public boolean checkOnlyEmail() {
+ List userBeans = userDao.queryForWhat("email", textEmail);
+ return userBeans.size() == 0;
+ }
+
+ /**
+ * 验证两次输入的密码是否一致
+ *
+ * @return
+ */
+ public boolean comparePwd() {
+ return textPassword.equals(textConfirmPwd);
+ }
+
+ /**
+ * 检查邮箱格式
+ *
+ * @return
+ */
+ public boolean checkEmail() {
+ Matcher emailMatcher = Constant.EMAIL_PATTERN.matcher(textEmail);
+ return emailMatcher.matches();
+ }
+
+ /**
+ * 向数据库表插入数据
+ */
+ public void insertUserIntoDB() {
+ UserBean userBean = new UserBean(textUserName, textPassword, textEmail);
+ userDao.insert(userBean);
+ // 同时存到SP中
+ spu.putString(Constant.USER_NAME, textUserName);
+ spu.putString(Constant.PASSWORD, textPassword);
+ }
+
+ /**
+ * 查询表中所有数据
+ */
+ public void queryAll() {
+ List userBeans = userDao.queryAll();
+ for (int i = 0; i < userBeans.size(); i++) {
+ Log.d(TAG, "queryAll: " + userBeans.get(i).toString());
+ }
+ }
+}
\ No newline at end of file
diff --git a/SparrowNotes/app/src/main/java/com/example/sparrownotes/bean/NoteBean.java b/SparrowNotes/app/src/main/java/com/example/sparrownotes/bean/NoteBean.java
new file mode 100644
index 0000000..13cfae1
--- /dev/null
+++ b/SparrowNotes/app/src/main/java/com/example/sparrownotes/bean/NoteBean.java
@@ -0,0 +1,136 @@
+package com.example.sparrownotes.bean;
+
+import com.j256.ormlite.field.DatabaseField;
+import com.j256.ormlite.table.DatabaseTable;
+
+/**
+ * 笔记实体类
+ * noteID 笔记ID 主键
+ * title 标题
+ * content 内容
+ * category 类别
+ * time 创建时间
+ * imgResource 图片资源(int)
+ * isTop 是否置顶
+ */
+@DatabaseTable(tableName = "tb_note")
+public class NoteBean {
+
+ @DatabaseField(generatedId = true, columnName = "note_id")
+ private int noteID;
+
+ @DatabaseField(columnName = "user_id")
+ private int userID;
+
+ @DatabaseField(defaultValue = "无标题")
+ private String title;
+
+ @DatabaseField(defaultValue = "空")
+ private String content;
+
+ @DatabaseField(defaultValue = "未分类")
+ private String category;
+
+ @DatabaseField(defaultValue = "未知")
+ private String time;
+
+ @DatabaseField(columnName = "img_resource")
+ private int imgResource;
+
+ @DatabaseField(defaultValue = "0", columnName = "is_top")
+ private String isTop;
+
+ public NoteBean() {
+ }
+
+ public NoteBean(int userID, String title, String content, String category, String time) {
+ this.userID = userID;
+ this.title = title;
+ this.content = content;
+ this.category = category;
+ this.time = time;
+ }
+
+ public NoteBean(int userID, String title, String content, String category, String time, int imgResource) {
+ this.userID = userID;
+ this.title = title;
+ this.content = content;
+ this.category = category;
+ this.time = time;
+ this.imgResource = imgResource;
+ }
+
+ @Override
+ public String toString() {
+ return "NoteBean{" +
+ "noteID=" + noteID +
+ "userID=" + userID +
+ ", title='" + title + '\'' +
+ ", content='" + content + '\'' +
+ ", category='" + category + '\'' +
+ ", time='" + time + '\'' +
+ ", imgResource='" + imgResource + '\'' +
+ ", isTop='" + isTop + '\'' +
+ '}';
+ }
+
+ public int getUserID() {
+ return userID;
+ }
+
+ public void setUserID(int userID) {
+ this.userID = userID;
+ }
+
+ public String getTop() {
+ return isTop;
+ }
+
+ public void setTop(String isTop) {
+ this.isTop = isTop;
+ }
+
+ public int getNoteID() {
+ return noteID;
+ }
+
+ public String getTitle() {
+ return title;
+ }
+
+ public void setTitle(String title) {
+ this.title = title;
+ }
+
+ public String getContent() {
+ return content;
+ }
+
+ public void setContent(String content) {
+ this.content = content;
+ }
+
+ public String getCategory() {
+ return category;
+ }
+
+ public void setCategory(String category) {
+ this.category = category;
+ }
+
+ public String getTime() {
+ return time;
+ }
+
+ public void setTime(String time) {
+ this.time = time;
+ }
+
+ public int getImgResource() {
+ return imgResource;
+ }
+
+ public void setImgResource(int imgResource) {
+ this.imgResource = imgResource;
+ }
+}
diff --git a/SparrowNotes/app/src/main/java/com/example/sparrownotes/bean/UserBean.java b/SparrowNotes/app/src/main/java/com/example/sparrownotes/bean/UserBean.java
new file mode 100644
index 0000000..c792e04
--- /dev/null
+++ b/SparrowNotes/app/src/main/java/com/example/sparrownotes/bean/UserBean.java
@@ -0,0 +1,74 @@
+package com.example.sparrownotes.bean;
+
+import com.j256.ormlite.field.DatabaseField;
+import com.j256.ormlite.table.DatabaseTable;
+
+/**
+ * 用户实体类
+ * userID 用户ID
+ * userName 用户名
+ * password 密码
+ * email 邮箱
+ */
+@DatabaseTable(tableName = "tb_user")
+public class UserBean {
+
+ @DatabaseField(generatedId = true, columnName = "user_id")
+ private int userID;
+
+ @DatabaseField(columnName = "user_name")
+ private String userName;
+
+ @DatabaseField
+ private String password;
+
+ @DatabaseField
+ private String email;
+
+ public UserBean() {
+ }
+
+ public UserBean(String userName, String password, String email) {
+ this.userName = userName;
+ this.password = password;
+ this.email = email;
+ }
+
+ @Override
+ public String toString() {
+ return "UserBean{" +
+ "userID=" + userID +
+ ", userName='" + userName + '\'' +
+ ", password='" + password + '\'' +
+ ", email='" + email + '\'' +
+ '}';
+ }
+
+ public int getUserID() {
+ return userID;
+ }
+
+ public String getUserName() {
+ return userName;
+ }
+
+ public void setUserName(String userName) {
+ this.userName = userName;
+ }
+
+ public String getPassword() {
+ return password;
+ }
+
+ public void setPassword(String password) {
+ this.password = password;
+ }
+
+ public String getEmail() {
+ return email;
+ }
+
+ public void setEmail(String email) {
+ this.email = email;
+ }
+}
diff --git a/SparrowNotes/app/src/main/java/com/example/sparrownotes/bean/adapter/MyPagerAdapter.java b/SparrowNotes/app/src/main/java/com/example/sparrownotes/bean/adapter/MyPagerAdapter.java
new file mode 100644
index 0000000..b5a00da
--- /dev/null
+++ b/SparrowNotes/app/src/main/java/com/example/sparrownotes/bean/adapter/MyPagerAdapter.java
@@ -0,0 +1,44 @@
+package com.example.sparrownotes.bean.adapter;
+
+import android.view.View;
+import android.view.ViewGroup;
+
+import androidx.annotation.NonNull;
+import androidx.viewpager.widget.PagerAdapter;
+
+import java.util.List;
+
+/**
+ * ViewPager适配器
+ */
+public class MyPagerAdapter extends PagerAdapter {
+
+ private List views;
+
+ public MyPagerAdapter(List views) {
+ this.views = views;
+ }
+
+ @NonNull
+ @Override
+ public Object instantiateItem(@NonNull ViewGroup container, int position) {
+ View view = views.get(position);
+ container.addView(view);
+ return view;
+ }
+
+ @Override
+ public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) {
+ container.removeView(views.get(position));
+ }
+
+ @Override
+ public int getCount() {
+ return views.size();
+ }
+
+ @Override
+ public boolean isViewFromObject(@NonNull View view, @NonNull Object object) {
+ return view == object;
+ }
+}
diff --git a/SparrowNotes/app/src/main/java/com/example/sparrownotes/bean/adapter/NoteAdapter.java b/SparrowNotes/app/src/main/java/com/example/sparrownotes/bean/adapter/NoteAdapter.java
new file mode 100644
index 0000000..50383a7
--- /dev/null
+++ b/SparrowNotes/app/src/main/java/com/example/sparrownotes/bean/adapter/NoteAdapter.java
@@ -0,0 +1,221 @@
+package com.example.sparrownotes.bean.adapter;
+
+import android.annotation.SuppressLint;
+import android.content.Context;
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ImageView;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import androidx.annotation.NonNull;
+import androidx.appcompat.view.menu.MenuPopupHelper;
+import androidx.appcompat.widget.PopupMenu;
+import androidx.recyclerview.widget.RecyclerView;
+
+import com.bumptech.glide.Glide;
+import com.example.sparrownotes.R;
+import com.example.sparrownotes.bean.NoteBean;
+import com.example.sparrownotes.dao.*;
+import com.example.sparrownotes.util.Constant;
+import com.example.sparrownotes.util.DialogUtil;
+import com.example.sparrownotes.util.SharedPreferenceUtil;
+
+import java.lang.reflect.Field;
+import java.util.List;
+
+/**
+ * RecyclerView适配器
+ */
+public class NoteAdapter extends RecyclerView.Adapter {
+ private List notesList;
+ private Context context;
+ private NoteDao noteDao;
+ SharedPreferenceUtil spu;
+
+ static class ViewHolder extends RecyclerView.ViewHolder {
+ View noteView;
+ View itemLayout;
+ ImageView itemCateImage;
+ ImageView itemMenu;
+ TextView itemTitle;
+ TextView itemId;
+ TextView itemContent;
+ TextView itemTime;
+ TextView itemCategory;
+
+ public ViewHolder(@NonNull View itemView) {
+ super(itemView);
+ noteView = itemView;
+ itemId = itemView.findViewById(R.id.item_id);
+ itemTitle = itemView.findViewById(R.id.item_title);
+ itemContent = itemView.findViewById(R.id.item_content);
+ itemCategory = itemView.findViewById(R.id.item_category);
+ itemTime = itemView.findViewById(R.id.item_time);
+ itemMenu = itemView.findViewById(R.id.item_menu);
+ itemLayout = itemView.findViewById(R.id.item_layout);
+ itemCateImage = itemView.findViewById(R.id.item_cate_img);
+ }
+ }
+
+ public NoteAdapter(List notesList, Context context) {
+ this.notesList = notesList;
+ this.context = context;
+ noteDao = new NoteDao(context);
+ spu = SharedPreferenceUtil.getInstance(context);
+ }
+
+ @SuppressLint("RestrictedApi")
+ @NonNull
+ @Override
+ public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
+ View view = LayoutInflater.from(parent.getContext())
+ .inflate(R.layout.note_item, parent, false);
+ final ViewHolder holder = new ViewHolder(view);
+
+ holder.itemMenu.setOnClickListener(v -> {
+ // 根据页面显示不同的菜单
+ if ("all".equals(Constant.PAGE_STATE)) {
+ PopupMenu popupMenu = new PopupMenu(v.getContext(), v, Gravity.RIGHT);
+ popupMenu.getMenuInflater().inflate(R.menu.item_menu_all, popupMenu.getMenu());
+ // 弹出式菜单的菜单项点击事件
+ popupMenu.setOnMenuItemClickListener(item -> {
+ switch (item.getItemId()) {
+ case R.id.delete_all:
+ // 删除
+ removeData(holder.getAdapterPosition());
+ Toast.makeText(v.getContext(), "删除成功", Toast.LENGTH_SHORT).show();
+ break;
+ case R.id.top_all:
+ //置顶
+ setTop(holder.getAdapterPosition());
+ Toast.makeText(v.getContext(), "已置顶", Toast.LENGTH_SHORT).show();
+ break;
+ case R.id.edit_all:
+ //编辑
+ DialogUtil.editNoteDialog(context, notesList.get(holder.getAdapterPosition()).getNoteID());
+ break;
+ default:
+ break;
+ }
+ return false;
+ });
+ setIconsVisible(popupMenu, true);
+ popupMenu.show();
+ } else {
+ PopupMenu popupMenu = new PopupMenu(v.getContext(), v, Gravity.RIGHT);
+ popupMenu.getMenuInflater().inflate(R.menu.item_menu_top, popupMenu.getMenu());
+ // 弹出式菜单的菜单项点击事件
+ popupMenu.setOnMenuItemClickListener(item -> {
+ switch (item.getItemId()) {
+ case R.id.delete_top:
+ // 删除
+ removeData(holder.getAdapterPosition());
+ Toast.makeText(v.getContext(), "删除成功", Toast.LENGTH_SHORT).show();
+ break;
+ case R.id.top_top:
+ // 取消置顶
+ notSetTop(holder.getAdapterPosition());
+ Toast.makeText(v.getContext(), "取消置顶", Toast.LENGTH_SHORT).show();
+ break;
+ case R.id.edit_top:
+ // 编辑
+ DialogUtil.editNoteDialog(context, notesList.get(holder.getAdapterPosition()).getNoteID());
+ break;
+ default:
+ break;
+ }
+ return false;
+ });
+ // 使弹出菜单的图标可见
+ setIconsVisible(popupMenu, true);
+ popupMenu.show();
+ }
+ });
+ return holder;
+ }
+
+ @Override
+ public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
+ NoteBean noteItem = notesList.get(position);
+ holder.itemId.setText(String.valueOf(noteItem.getNoteID()));
+ holder.itemTitle.setText(noteItem.getTitle());
+ holder.itemContent.setText(noteItem.getContent());
+ holder.itemCategory.setText(noteItem.getCategory());
+ holder.itemTime.setText(noteItem.getTime());
+ int imgResource = noteItem.getImgResource();
+ /*
+ * 通过Glide获取图片资源
+ * 这里本来做的是获取tomcat中的图片url, 考虑到每次运行都要启动tomcat
+ * 就改成了本地的方式
+ * 等到交作业的时候再弄一个网络的版本
+ */
+ Glide.with(context).load(imgResource).into(holder.itemCateImage);
+ }
+
+ @Override
+ public int getItemCount() {
+ return notesList.size();
+ }
+
+ /**
+ * 删除一条数据
+ *
+ * @param position
+ */
+ public void removeData(int position) {
+ // 从数据库删除
+ noteDao.delete(notesList.get(position).getNoteID());
+ // 从List中删除
+ notesList.remove(position);
+ notifyItemRemoved(position);
+ }
+
+ /**
+ * 修改一条数据(置顶)
+ *
+ * @param position
+ */
+ public void setTop(int position) {
+ NoteBean noteItem = noteDao.queryById(notesList.get(position).getNoteID(), spu.getInt(Constant.USER_ID));
+ noteItem.setTop("1");
+ noteDao.update(noteItem);
+ notifyDataSetChanged();
+ }
+
+ /**
+ * 修改一条数据(取消置顶)
+ *
+ * @param position
+ */
+ public void notSetTop(int position) {
+ NoteBean noteItem = noteDao.queryById(notesList.get(position).getNoteID(), spu.getInt(Constant.USER_ID));
+ noteItem.setTop("0");
+ noteDao.update(noteItem);
+ notesList.remove(position);
+ notifyDataSetChanged();
+ }
+
+ /**
+ * menu显示图标
+ *
+ * @param popupMenu
+ * @param flag
+ */
+ @SuppressLint("RestrictedApi")
+ private void setIconsVisible(PopupMenu popupMenu, boolean flag) {
+ //判断menu是否为空
+ if (popupMenu != null) {
+ try {
+ Field field = popupMenu.getClass().getDeclaredField("mPopup");
+ field.setAccessible(true);
+ MenuPopupHelper mHelper = (MenuPopupHelper) field.get(popupMenu);
+ mHelper.setForceShowIcon(flag);
+ } catch (IllegalAccessException | NoSuchFieldException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+}
diff --git a/SparrowNotes/app/src/main/java/com/example/sparrownotes/dao/NoteDao.java b/SparrowNotes/app/src/main/java/com/example/sparrownotes/dao/NoteDao.java
new file mode 100644
index 0000000..4b6806f
--- /dev/null
+++ b/SparrowNotes/app/src/main/java/com/example/sparrownotes/dao/NoteDao.java
@@ -0,0 +1,210 @@
+package com.example.sparrownotes.dao;
+
+import android.content.Context;
+
+import com.example.sparrownotes.bean.NoteBean;
+import com.example.sparrownotes.util.DBHelper;
+import com.j256.ormlite.dao.Dao;
+
+import java.sql.SQLException;
+import java.util.List;
+
+/**
+ * 笔记操作类
+ *
+ * @author Horsen
+ */
+public class NoteDao {
+ private Dao dao;
+
+ public NoteDao(Context context) {
+ try {
+ this.dao = DBHelper.getInstance(context).getDao(NoteBean.class);
+ } catch (SQLException e) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * 创建数据
+ *
+ * @param data 数据
+ */
+ public void create(NoteBean data) {
+ try {
+ dao.createOrUpdate(data);
+ } catch (SQLException e) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * 创建数据集合
+ *
+ * @param datas 数据集合
+ */
+ public void createList(List datas) {
+ try {
+ dao.create(datas);
+ } catch (SQLException e) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * 向note表中添加一条数据
+ * create:插入一条数据或集合
+ * createIfNotExists:如果不存在则插入
+ * createOrUpdate:如果指定id则更新
+ *
+ * @param data
+ */
+ public void insert(NoteBean data) {
+ try {
+ dao.createIfNotExists(data);
+ } catch (SQLException e) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * 通过id删除指定数据
+ *
+ * @param id
+ */
+ public void delete(int id) {
+ try {
+ dao.deleteById(id);
+ } catch (SQLException e) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * 删除表中的一条数据
+ *
+ * @param data
+ */
+ public void delete(NoteBean data) {
+ try {
+ dao.delete(data);
+ } catch (SQLException e) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * 删除表中数据集合
+ *
+ * @param datas
+ */
+ public void deleteList(List datas) {
+ try {
+ dao.delete(datas);
+ } catch (SQLException e) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * 清空数据
+ */
+ public void deleteAll() {
+ try {
+ dao.delete(dao.queryForAll());
+ } catch (Exception e) {
+ }
+ }
+
+ /**
+ * 修改表中的一条数据
+ *
+ * @param data
+ */
+ public void update(NoteBean data) {
+ try {
+ dao.update(data);
+ } catch (SQLException e) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * 查询表中的所有数据
+ *
+ * @return 返回查询结果集
+ */
+ public List queryAll(int userID) {
+ List notes = null;
+ try {
+ notes = dao.queryBuilder()
+ .orderBy("note_id", false)
+ .where().eq("user_id", userID)
+ .query();
+ } catch (SQLException e) {
+ e.printStackTrace();
+ }
+ return notes;
+ }
+
+ /**
+ * 根据ID取出笔记信息
+ *
+ * @param id
+ * @return
+ */
+ public NoteBean queryById(int id, int userID) {
+ NoteBean note = null;
+ try {
+ note = dao.queryBuilder()
+ .where().eq("note_id", id)
+ .and().eq("user_id", userID)
+ .queryForFirst();
+ } catch (SQLException e) {
+ e.printStackTrace();
+ }
+ return note;
+ }
+
+ /**
+ * 通过列名和数据查找
+ *
+ * @param columnName 列名
+ * @param data 数据
+ * @return
+ */
+ public List queryForWhat(String columnName, String data, int userID) {
+ List notes = null;
+ try {
+ notes = dao.queryBuilder()
+ .orderBy("note_id", false)
+ .where().eq(columnName, data)
+ .and().eq("user_id", userID)
+ .query();
+ } catch (SQLException e) {
+ e.printStackTrace();
+ }
+ return notes;
+ }
+
+ /**
+ * 模糊查询
+ *
+ * @param columnName
+ * @param data
+ * @return
+ */
+ public List queryLikeWhat(String columnName, String data, int userID) {
+ List notes = null;
+ try {
+ notes = dao.queryBuilder()
+ .orderBy("note_id", false)
+ .where().like(columnName, "%" + data + "%")
+ .and().eq("user_id", userID)
+ .query();
+ } catch (SQLException e) {
+ e.printStackTrace();
+ }
+ return notes;
+ }
+}
diff --git a/SparrowNotes/app/src/main/java/com/example/sparrownotes/dao/UserDao.java b/SparrowNotes/app/src/main/java/com/example/sparrownotes/dao/UserDao.java
new file mode 100644
index 0000000..6f68736
--- /dev/null
+++ b/SparrowNotes/app/src/main/java/com/example/sparrownotes/dao/UserDao.java
@@ -0,0 +1,200 @@
+package com.example.sparrownotes.dao;
+
+import android.content.Context;
+
+import com.example.sparrownotes.bean.UserBean;
+import com.example.sparrownotes.util.DBHelper;
+import com.j256.ormlite.dao.Dao;
+
+import java.sql.SQLException;
+import java.util.List;
+
+/**
+ * 用户操作类
+ *
+ * @author Horsen
+ */
+public class UserDao {
+ private Dao dao;
+
+ public UserDao(Context context) {
+ try {
+ this.dao = DBHelper.getInstance(context).getDao(UserBean.class);
+ } catch (SQLException e) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * 创建数据
+ *
+ * @param data 数据
+ */
+ public void create(UserBean data) {
+ try {
+ dao.createOrUpdate(data);
+ } catch (SQLException e) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * 创建数据集合
+ *
+ * @param datas 数据集合
+ */
+ public void createList(List datas) {
+ try {
+ dao.create(datas);
+ } catch (SQLException e) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * 向user表中添加一条数据
+ * create:插入一条数据或集合
+ * createIfNotExists:如果不存在则插入
+ * createOrUpdate:如果指定id则更新
+ *
+ * @param data
+ */
+ public void insert(UserBean data) {
+ try {
+ dao.createIfNotExists(data);
+ } catch (SQLException e) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * 通过id删除指定数据
+ *
+ * @param id
+ */
+ public void delete(int id) {
+ try {
+ dao.deleteById(id);
+ } catch (SQLException e) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * 删除表中的一条数据
+ *
+ * @param data
+ */
+ public void delete(UserBean data) {
+ try {
+ dao.delete(data);
+ } catch (SQLException e) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * 删除表中数据集合
+ *
+ * @param datas
+ */
+ public void deleteList(List datas) {
+ try {
+ dao.delete(datas);
+ } catch (SQLException e) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * 清空数据
+ */
+ public void deleteAll() {
+ try {
+ dao.delete(dao.queryForAll());
+ } catch (Exception e) {
+ }
+ }
+
+ /**
+ * 修改表中的一条数据
+ *
+ * @param data
+ */
+ public void update(UserBean data) {
+ try {
+ dao.update(data);
+ } catch (SQLException e) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * 查询表中的所有数据
+ *
+ * @return 返回查询结果集
+ */
+ public List queryAll() {
+ List users = null;
+ try {
+ users = dao.queryForAll();
+ } catch (SQLException e) {
+ e.printStackTrace();
+ }
+ return users;
+ }
+
+ /**
+ * 根据ID取出用户信息
+ *
+ * @param id
+ * @return
+ */
+ public UserBean queryById(int id) {
+ UserBean user = null;
+ try {
+ user = dao.queryForId(id);
+ } catch (SQLException e) {
+ e.printStackTrace();
+ }
+ return user;
+ }
+
+ /**
+ * 通过列名和数据查找
+ *
+ * @param columnName 列名
+ * @param data 数据
+ * @return
+ */
+ public List queryForWhat(String columnName, String data) {
+ List users = null;
+ try {
+ users = dao.queryForEq(columnName, data);
+ } catch (SQLException e) {
+ e.printStackTrace();
+ }
+ return users;
+ }
+
+ /**
+ * 通过条件查询集合
+ *
+ * @param userName 用户名
+ * @param password 密码
+ * @return
+ */
+ public List queryByUserNameAndPassword(String userName, String password) {
+ List users = null;
+ try {
+ users = dao.queryBuilder()
+ .orderBy("user_id", true)
+ .where().eq("user_name", userName)
+ .and().eq("password", password)
+ .query();
+ } catch (SQLException e) {
+ e.printStackTrace();
+ }
+ return users;
+ }
+}
diff --git a/SparrowNotes/app/src/main/java/com/example/sparrownotes/fragment/AddFragment.java b/SparrowNotes/app/src/main/java/com/example/sparrownotes/fragment/AddFragment.java
new file mode 100644
index 0000000..5871455
--- /dev/null
+++ b/SparrowNotes/app/src/main/java/com/example/sparrownotes/fragment/AddFragment.java
@@ -0,0 +1,322 @@
+package com.example.sparrownotes.fragment;
+
+import android.os.Bundle;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ImageView;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import androidx.annotation.Nullable;
+import androidx.fragment.app.Fragment;
+
+import com.example.sparrownotes.R;
+import com.example.sparrownotes.bean.adapter.MyPagerAdapter;
+import com.example.sparrownotes.bean.NoteBean;
+import com.example.sparrownotes.dao.*;
+import com.example.sparrownotes.util.Constant;
+import com.example.sparrownotes.util.NoScrollViewPager;
+import com.example.sparrownotes.util.SharedPreferenceUtil;
+
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+import butterknife.BindView;
+import butterknife.ButterKnife;
+import butterknife.OnClick;
+import butterknife.Unbinder;
+
+/**
+ * 增加note的页面
+ */
+public class AddFragment extends Fragment {
+
+ @BindView(R.id.view_pager_add)
+ NoScrollViewPager viewPager;
+ @BindView(R.id.text_reset)
+ TextView textReset;
+ @BindView(R.id.text_save)
+ TextView textSave;
+ @BindView(R.id.img_account)
+ ImageView imgAccount;
+ @BindView(R.id.img_date)
+ ImageView imgDate;
+ @BindView(R.id.img_link)
+ ImageView imgLink;
+ @BindView(R.id.img_bill)
+ ImageView imgBill;
+ @BindView(R.id.img_location)
+ ImageView imgLocation;
+ @BindView(R.id.img_mood)
+ ImageView imgMood;
+ @BindView(R.id.img_note)
+ ImageView imgNote;
+ @BindView(R.id.img_question)
+ ImageView imgQuestion;
+
+ TextView[] textViews = new TextView[5];
+ String title = "", content = "";
+ int imgResource;
+ View[] views = new View[8];
+ int index = 0;
+ private Unbinder unbinder;
+ private String category = "";
+ private static final String TAG = "AddFragment";
+ private List viewList = new ArrayList<>();
+ private NoteDao noteDao;
+ SharedPreferenceUtil spu = SharedPreferenceUtil.getInstance(getActivity());
+
+ public AddFragment() {}
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+ View view = inflater.inflate(R.layout.fragment_add, container, false);
+ // 返回一个Unbinder值(进行解绑),注意这里的this不能使用getActivity()
+ unbinder = ButterKnife.bind(this, view);
+ return view;
+ }
+
+ @Override
+ public void onActivityCreated(@Nullable Bundle savedInstanceState) {
+ super.onActivityCreated(savedInstanceState);
+ noteDao = new NoteDao(getActivity());
+ initView();
+ // 置顶默认类型
+ category = getString(R.string.note);
+ }
+
+ public void initView() {
+ LayoutInflater inflater = LayoutInflater.from(getActivity());
+ // 创建不同的添加页面
+ for (int i = 0; i < Constant.LAYOUTS.length; i++) {
+ views[i] = inflater.inflate(Constant.LAYOUTS[i], null);
+ viewList.add(views[i]);
+ }
+ MyPagerAdapter adapter = new MyPagerAdapter(viewList);
+ viewPager.setOffscreenPageLimit(viewList.size());
+ viewPager.setAdapter(adapter);
+ }
+
+ /**
+ * 存入数据库
+ */
+ public void insertNoteIntoDB(String category) {
+ getTitleAndContents(category);
+ NoteBean noteBean = new NoteBean(spu.getInt(Constant.USER_ID),title, content, category, "创建于 " + getToday(), imgResource);
+ noteDao.insert(noteBean);
+ }
+
+ /**
+ * 点击分类图标, 显示不同的添加页面 通过ViewPager
+ *
+ * @param view 布局
+ */
+ @OnClick({R.id.text_reset, R.id.text_save, R.id.img_account, R.id.img_date, R.id.img_link, R.id.img_bill, R.id.img_location, R.id.img_mood, R.id.img_note, R.id.img_question})
+ public void onViewClicked(View view) {
+ switch (view.getId()) {
+ case R.id.text_reset:
+ // 清空输入
+ clearTitleAndContents(category);
+ break;
+ case R.id.text_save:
+ // 保存输入
+ insertNoteIntoDB(category);
+ clearTitleAndContents(category);
+ Toast.makeText(getContext(), "添加成功", Toast.LENGTH_SHORT).show();
+ break;
+ case R.id.img_note:
+ category = getString(R.string.note);
+ index = 0;
+ break;
+ case R.id.img_link:
+ category = getString(R.string.link);
+ index = 1;
+ break;
+ case R.id.img_location:
+ category = getString(R.string.location);
+ index = 2;
+ break;
+ case R.id.img_bill:
+ category = getString(R.string.bill);
+ index = 3;
+ break;
+ case R.id.img_date:
+ category = getString(R.string.date);
+ index = 4;
+ break;
+ case R.id.img_mood:
+ category = getString(R.string.mood);
+ index = 5;
+ break;
+ case R.id.img_account:
+ category = getString(R.string.account);
+ index = 6;
+ break;
+ case R.id.img_question:
+ category = getString(R.string.question);
+ index = 7;
+ break;
+ default:
+ break;
+ }
+ viewPager.setCurrentItem(index);
+ }
+
+ /**
+ * 获得今天的日期
+ *
+ * @return
+ */
+ public String getToday() {
+ // 日期格式
+ SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy.MM.dd");
+ //获取当前时间
+ Date date = new Date(System.currentTimeMillis());
+ return simpleDateFormat.format(date);
+ }
+
+ /**
+ * 获取天数差
+ *
+ * @param today 今天
+ * @param someday 某一天
+ * @return
+ */
+ public String getDayDistance(String today, String someday) {
+ try {
+ SimpleDateFormat todayFormat = new SimpleDateFormat("yyyy.MM.dd");
+ SimpleDateFormat somedayFormat = new SimpleDateFormat("yyyy年MM月dd日");
+ long todayTime = todayFormat.parse(today).getTime();
+ long somedayTime = somedayFormat.parse(someday).getTime();
+ Log.d(TAG, "getDayDistance: " + todayTime);
+ Log.d(TAG, "getDayDistance: " + somedayTime);
+ // 获得毫秒差 除以 1000*3600*24 得到天数差
+ long distance = (todayTime - somedayTime) / (1000 * 3600 * 24);
+ // 根据正负判断日期在前还是在后
+ if (distance >= 0) {
+ return "\n距今已经 " + distance + " 天";
+ }
+ return "\n距今还有 " + (somedayTime - todayTime) / (1000 * 3600 * 24) + " 天";
+ } catch (ParseException e) {
+ e.printStackTrace();
+ }
+ return "这个日期...不对吧";
+ }
+
+ /**
+ * onDestroyView中进行解绑操作
+ */
+ @Override
+ public void onDestroyView() {
+ super.onDestroyView();
+ unbinder.unbind();
+ }
+
+ /**
+ * 通过传入的类型 获得标题和内容
+ *
+ * @param category 类型
+ */
+ public void getTitleAndContents(String category) {
+ textViews[0] = views[index].findViewById(R.id.title);
+ title = textViews[0].getText().toString().trim();
+ switch (category) {
+ case "便签":
+ case "链接":
+ case "位置":
+ case "心情":
+ textViews[1] = views[index].findViewById(R.id.content_1);
+ content = textViews[1].getText().toString().trim();
+ break;
+ case "消费":
+ textViews[1] = views[index].findViewById(R.id.year);
+ textViews[2] = views[index].findViewById(R.id.month);
+ textViews[3] = views[index].findViewById(R.id.day);
+ textViews[4] = views[index].findViewById(R.id.content_2);
+ content = "时间:" + textViews[1].getText().toString().trim() + "年"
+ + textViews[2].getText().toString().trim() + "月"
+ + textViews[3].getText().toString().trim() + "日"
+ + "\n消费:" + textViews[4].getText().toString().trim() + "元";
+ break;
+ case "日子":
+ textViews[1] = views[index].findViewById(R.id.year);
+ textViews[2] = views[index].findViewById(R.id.month);
+ textViews[3] = views[index].findViewById(R.id.day);
+ String date = textViews[1].getText().toString().trim() + "年"
+ + textViews[2].getText().toString().trim() + "月"
+ + textViews[3].getText().toString().trim() + "日";
+ content = date + getDayDistance(getToday(), date);
+ break;
+ case "账户":
+ textViews[1] = views[index].findViewById(R.id.content_1);
+ textViews[2] = views[index].findViewById(R.id.content_2);
+ content = "账户:" + textViews[1].getText().toString().trim()
+ + "\n密码:" + textViews[2].getText().toString().trim();
+ break;
+ case "三省":
+ textViews[1] = views[index].findViewById(R.id.content_1);
+ textViews[2] = views[index].findViewById(R.id.content_2);
+ title = "学习否:" + textViews[0].getText().toString().trim();
+ content = "学几时:" + textViews[1].getText().toString().trim()
+ + "\n学之何:" + textViews[2].getText().toString().trim();
+ break;
+ default:
+ break;
+ }
+ imgResource = Constant.IMG_RESOURCES[index];
+ }
+
+ /**
+ * 清空标题和内容
+ *
+ * @param category 类型
+ */
+ public void clearTitleAndContents(String category) {
+ textViews[0] = views[index].findViewById(R.id.title);
+ title = textViews[0].getText().toString().trim();
+ switch (category) {
+ case "便签":
+ case "链接":
+ case "位置":
+ case "心情":
+ textViews[1] = views[index].findViewById(R.id.content_1);
+ for (int i = 0; i < 2; i++) {
+ textViews[i].setText("");
+ }
+ break;
+ case "消费":
+ textViews[1] = views[index].findViewById(R.id.year);
+ textViews[2] = views[index].findViewById(R.id.month);
+ textViews[3] = views[index].findViewById(R.id.day);
+ textViews[4] = views[index].findViewById(R.id.content_2);
+ for (int i = 0; i < 5; i++) {
+ textViews[i].setText("");
+ }
+ break;
+ case "日子":
+ textViews[1] = views[index].findViewById(R.id.year);
+ textViews[2] = views[index].findViewById(R.id.month);
+ textViews[3] = views[index].findViewById(R.id.day);
+ for (int i = 0; i < 4; i++) {
+ textViews[i].setText("");
+ }
+ break;
+ case "账户":
+ case "三省":
+ textViews[1] = views[index].findViewById(R.id.content_1);
+ textViews[2] = views[index].findViewById(R.id.content_2);
+ for (int i = 0; i < 3; i++) {
+ textViews[i].setText("");
+ }
+ break;
+ default:
+ break;
+ }
+ }
+}
\ No newline at end of file
diff --git a/SparrowNotes/app/src/main/java/com/example/sparrownotes/fragment/AllFragment.java b/SparrowNotes/app/src/main/java/com/example/sparrownotes/fragment/AllFragment.java
new file mode 100644
index 0000000..c9e2d31
--- /dev/null
+++ b/SparrowNotes/app/src/main/java/com/example/sparrownotes/fragment/AllFragment.java
@@ -0,0 +1,115 @@
+package com.example.sparrownotes.fragment;
+
+import android.annotation.SuppressLint;
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+
+import androidx.annotation.Nullable;
+import androidx.fragment.app.Fragment;
+import androidx.recyclerview.widget.LinearLayoutManager;
+import androidx.recyclerview.widget.RecyclerView;
+import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
+
+import com.example.sparrownotes.R;
+import com.example.sparrownotes.bean.adapter.NoteAdapter;
+import com.example.sparrownotes.bean.NoteBean;
+import com.example.sparrownotes.dao.*;
+import com.example.sparrownotes.util.Constant;
+import com.example.sparrownotes.util.SharedPreferenceUtil;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * 显示所有note
+ */
+public class AllFragment extends Fragment {
+ RecyclerView recyclerView;
+ SwipeRefreshLayout swipeRefresh;
+ NoteAdapter adapter;
+ private List notesList = new ArrayList<>();
+ private NoteDao noteDao;
+ SharedPreferenceUtil spu = SharedPreferenceUtil.getInstance(getActivity());
+
+ public AllFragment() {
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+ return inflater.inflate(R.layout.fragment_all, container, false);
+ }
+
+ @Override
+ public void onActivityCreated(@Nullable Bundle savedInstanceState) {
+ super.onActivityCreated(savedInstanceState);
+ noteDao = new NoteDao(getActivity());
+ initData();
+ initView();
+ }
+
+ /**
+ * 初始化界面
+ */
+ @SuppressLint("ResourceAsColor")
+ public void initView() {
+ // 下拉刷新组件
+ swipeRefresh = getActivity().findViewById(R.id.swipe_refresh_all);
+ swipeRefresh.setColorSchemeColors(R.color.colorPrimary);
+ swipeRefresh.setOnRefreshListener(this::refreshNotes);
+ // 替代ListView
+ recyclerView = getActivity().findViewById(R.id.recycler_view_all);
+ LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity());
+ recyclerView.setLayoutManager(layoutManager);
+ adapter = new NoteAdapter(notesList, getActivity());
+ recyclerView.setAdapter(adapter);
+ adapter.notifyDataSetChanged();
+ }
+
+ /**
+ * 初始化数据
+ */
+ public void initData() {
+ List noteBeams = noteDao.queryAll(spu.getInt(Constant.USER_ID));
+ notesList.addAll(noteBeams);
+ }
+
+ /**
+ * 更新数据
+ */
+ public void updateData() {
+ notesList.clear();
+ // 获得sp中的查询条件 更新数据源
+ String column = spu.getString(Constant.SEARCH_FOR_WHAT);
+ String value = spu.getString(Constant.SEARCH_VALUE);
+ if (column != "" && value != "") {
+ List noteBeans = noteDao.queryLikeWhat(column, value,spu.getInt(Constant.USER_ID));
+ notesList.addAll(noteBeans);
+ // 用后即删
+ spu.removeKey(Constant.SEARCH_FOR_WHAT);
+ spu.removeKey(Constant.SEARCH_VALUE);
+ } else {
+ initData();
+ }
+ adapter.notifyDataSetChanged();
+ }
+
+ /**
+ * 下拉刷新
+ */
+ public void refreshNotes() {
+ new Thread(() -> {
+ try {
+ Thread.sleep(500);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ getActivity().runOnUiThread(() -> {
+ updateData();
+ swipeRefresh.setRefreshing(false);
+ });
+ }).start();
+ }
+}
\ No newline at end of file
diff --git a/SparrowNotes/app/src/main/java/com/example/sparrownotes/fragment/TopFragment.java b/SparrowNotes/app/src/main/java/com/example/sparrownotes/fragment/TopFragment.java
new file mode 100644
index 0000000..6a78d1b
--- /dev/null
+++ b/SparrowNotes/app/src/main/java/com/example/sparrownotes/fragment/TopFragment.java
@@ -0,0 +1,162 @@
+package com.example.sparrownotes.fragment;
+
+import android.annotation.SuppressLint;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.TextView;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.fragment.app.Fragment;
+import androidx.recyclerview.widget.LinearLayoutManager;
+import androidx.recyclerview.widget.RecyclerView;
+import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
+
+import com.example.sparrownotes.R;
+import com.example.sparrownotes.bean.adapter.NoteAdapter;
+import com.example.sparrownotes.bean.NoteBean;
+import com.example.sparrownotes.dao.*;
+import com.example.sparrownotes.util.Constant;
+import com.example.sparrownotes.util.SharedPreferenceUtil;
+
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * 显示置顶note
+ */
+public class TopFragment extends Fragment {
+
+ RecyclerView recyclerView;
+ SwipeRefreshLayout swipeRefresh;
+ NoteAdapter adapter;
+ TextView textTime, textGreeting;
+ private List notesList = new ArrayList<>();
+ private static final String TAG = "TopFragment";
+ private NoteDao noteDao;
+ SharedPreferenceUtil spu = SharedPreferenceUtil.getInstance(getActivity());
+
+ public TopFragment() {
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+ return inflater.inflate(R.layout.fragment_top, container, false);
+ }
+
+ @Override
+ public void onActivityCreated(@Nullable Bundle savedInstanceState) {
+ super.onActivityCreated(savedInstanceState);
+ noteDao = new NoteDao(getActivity());
+ initData();
+ initView();
+ updateData();
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+ // 发送消息 更新时间
+ handler.sendEmptyMessage(Constant.UPDATE_TIME);
+ }
+
+ @Override
+ public void onPause() {
+ super.onPause();
+ // 停止更新时间
+ handler.removeCallbacksAndMessages(null);
+ }
+
+ /**
+ * 初始化界面
+ */
+ @SuppressLint("ResourceAsColor")
+ public void initView() {
+ // 下拉刷新组件
+ swipeRefresh = getActivity().findViewById(R.id.swipe_refresh_top);
+ swipeRefresh.setColorSchemeColors(R.color.colorPrimary);
+ swipeRefresh.setOnRefreshListener(this::refreshNotes);
+ // 代替ListView
+ recyclerView = getActivity().findViewById(R.id.recycler_view_top);
+ LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity());
+ recyclerView.setLayoutManager(layoutManager);
+ adapter = new NoteAdapter(notesList, getActivity());
+ recyclerView.setAdapter(adapter);
+ textTime = getActivity().findViewById(R.id.text_time);
+ textGreeting = getActivity().findViewById(R.id.text_greeting);
+ }
+
+ /**
+ * 初始化数据
+ */
+ public void initData() {
+ List noteBeans = noteDao.queryForWhat("is_top", "1", spu.getInt(Constant.USER_ID));
+ notesList.addAll(noteBeans);
+ }
+
+ /**
+ * 更新数据(假更新)
+ */
+ public void updateData() {
+ notesList.clear();
+ initData();
+ adapter.notifyDataSetChanged();
+ }
+
+ /**
+ * 下拉刷新
+ */
+ public void refreshNotes() {
+ new Thread(() -> {
+ try {
+ Thread.sleep(500);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ getActivity().runOnUiThread(() -> {
+ updateData();
+ swipeRefresh.setRefreshing(false);
+ });
+ }).start();
+ }
+
+ /**
+ * 获得今天的日期
+ *
+ * @return 日期字符串
+ */
+ public String getToday() {
+ // 日期格式
+ SimpleDateFormat weekFormat = new SimpleDateFormat("EEEE");
+ SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy年MM月dd日");
+ SimpleDateFormat timeFormat = new SimpleDateFormat("HH:mm:ss");
+ //获取当前时间
+ Date dateTime = new Date(System.currentTimeMillis());
+ String week = weekFormat.format(dateTime);
+ String date = dateFormat.format(dateTime);
+ String time = timeFormat.format(dateTime);
+ return week + "\n" + date + "\n" + time;
+ }
+
+ /**
+ * 实现主线程和子线程之间的通信
+ * 通知时间更新
+ */
+ @SuppressLint("HandlerLeak")
+ private Handler handler = new Handler() {
+ @Override
+ public void handleMessage(@NonNull Message msg) {
+ if (msg.what == Constant.UPDATE_TIME) {
+ textTime.setText(getToday());
+ sendEmptyMessageDelayed(Constant.UPDATE_TIME, 1000);
+ }
+ }
+ };
+}
\ No newline at end of file
diff --git a/SparrowNotes/app/src/main/java/com/example/sparrownotes/util/Constant.java b/SparrowNotes/app/src/main/java/com/example/sparrownotes/util/Constant.java
new file mode 100644
index 0000000..adeae71
--- /dev/null
+++ b/SparrowNotes/app/src/main/java/com/example/sparrownotes/util/Constant.java
@@ -0,0 +1,41 @@
+package com.example.sparrownotes.util;
+
+import com.example.sparrownotes.R;
+
+import java.util.regex.Pattern;
+
+public class Constant {
+ // 数据库名和版本号
+ public static final String DB_NAME = "sparrow.db";
+ public static final int DB_VERSION = 1;
+ // 用来判断邮箱格式的正则表达式
+ public static final String EMAIL_REGEX = "^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\\.[a-zA-Z0-9_-]+)+$";
+ public static final Pattern EMAIL_PATTERN = Pattern.compile(EMAIL_REGEX);
+ // 用来存储用户登录操作的键
+ public static final String HAS_REGISTERED = "has_registered";
+ public static final String REMEMBER_PWD = "remember_pwd";
+ public static final String AUTO_LOGIN = "auto_login";
+ public static final String USER_NAME = "user_name";
+ public static final String PASSWORD = "password";
+ public static final String USER_ID = "userId";
+ // 用来标记fragment的键
+ public static final String TOP_TAG = "top";
+ public static final String ADD_TAG = "add";
+ public static final String LIST_TAG = "list";
+ // 标记当前显示的页面
+ public static String PAGE_STATE = "top";
+ // 用来更新时间的消息
+ public static final int UPDATE_TIME = 1;
+ // 网络地址前后缀
+ public static final String PREFIX_URL = "http://192.168.0.110:8080/sparrow_notes/cate_";
+ public static final String SUFFIX_URL = ".png";
+ // 存储查找条件的键
+ public static final String SEARCH_FOR_WHAT = "what";
+ public static final String SEARCH_VALUE = "value";
+ // 不同的添加布局 图片地址 图片资源(int)
+ public static final int[] LAYOUTS = {R.layout.add_note, R.layout.add_link, R.layout.add_location, R.layout.add_bill,
+ R.layout.add_date, R.layout.add_mood, R.layout.add_account, R.layout.add_question};
+ public static final String[] IMG_URLS = {"note", "link", "location", "bill", "date", "mood", "account", "question"};
+ public static final int[] IMG_RESOURCES = {R.drawable.cate_note, R.drawable.cate_link, R.drawable.cate_location,
+ R.drawable.cate_bill, R.drawable.cate_date, R.drawable.cate_mood, R.drawable.cate_account, R.drawable.cate_question};
+}
diff --git a/SparrowNotes/app/src/main/java/com/example/sparrownotes/util/DBHelper.java b/SparrowNotes/app/src/main/java/com/example/sparrownotes/util/DBHelper.java
new file mode 100644
index 0000000..5bf18fc
--- /dev/null
+++ b/SparrowNotes/app/src/main/java/com/example/sparrownotes/util/DBHelper.java
@@ -0,0 +1,109 @@
+package com.example.sparrownotes.util;
+
+import android.content.Context;
+import android.database.sqlite.SQLiteDatabase;
+import android.util.ArrayMap;
+
+import com.example.sparrownotes.bean.NoteBean;
+import com.example.sparrownotes.bean.UserBean;
+import com.example.sparrownotes.util.Constant;
+import com.j256.ormlite.android.apptools.OrmLiteSqliteOpenHelper;
+import com.j256.ormlite.dao.Dao;
+import com.j256.ormlite.support.ConnectionSource;
+import com.j256.ormlite.table.TableUtils;
+
+import java.sql.SQLException;
+
+/**
+ * 数据库帮助类
+ */
+@SuppressWarnings("AlibabaRemoveCommentedCode")
+public class DBHelper extends OrmLiteSqliteOpenHelper {
+ /**
+ * 防止多线程同时操作, 实现单例模式, 并锁定线程
+ * 数组存储App中所有的Dao对象的Map集合
+ */
+ private static DBHelper dbHelper = null;
+ private ArrayMap daos = new ArrayMap<>();
+
+ public static synchronized DBHelper getInstance(Context context) {
+ if (dbHelper == null) {
+ synchronized (DBHelper.class) {
+ if (dbHelper == null) {
+ dbHelper = new DBHelper(context);
+ }
+ }
+ }
+ return dbHelper;
+ }
+
+ private DBHelper(Context context) {
+ super(context, Constant.DB_NAME, null, Constant.DB_VERSION);
+ }
+
+ /**
+ * 包含创建表的语句
+ *
+ * @param sqLiteDatabase
+ * @param connectionSource
+ */
+ @Override
+ public void onCreate(SQLiteDatabase sqLiteDatabase, ConnectionSource connectionSource) {
+ try {
+ TableUtils.createTable(connectionSource, UserBean.class);
+ TableUtils.createTable(connectionSource, NoteBean.class);
+ } catch (SQLException e) {
+ e.printStackTrace();
+ }
+
+ }
+
+ /**
+ * 包含新建表的语句
+ * 就是删了再创罢了
+ *
+ * @param sqLiteDatabase
+ * @param connectionSource
+ * @param i
+ * @param i1
+ */
+ @Override
+ public void onUpgrade(SQLiteDatabase sqLiteDatabase, ConnectionSource connectionSource, int i, int i1) {
+ try {
+ TableUtils.dropTable(connectionSource, UserBean.class, false);
+ TableUtils.dropTable(connectionSource, NoteBean.class, false);
+ onCreate(sqLiteDatabase, connectionSource);
+ } catch (SQLException e) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * 根据传入的Dao路径获取这个Dao的单例对象, 要么从daos中获取, 要么新建一个存入daos
+ */
+ @Override
+ public synchronized Dao getDao(Class clazz) throws SQLException {
+ Dao dao = null;
+ String className = clazz.getSimpleName();
+ if (daos.containsKey(className)) {
+ dao = daos.get(className);
+ }
+ if (dao == null) {
+ dao = super.getDao(clazz);
+ daos.put(className, dao);
+ }
+ return dao;
+ }
+
+ /**
+ * 释放资源
+ */
+ @Override
+ public void close() {
+ super.close();
+ for (String key : daos.keySet()) {
+ Dao dao = daos.get(key);
+ dao = null;
+ }
+ }
+}
diff --git a/SparrowNotes/app/src/main/java/com/example/sparrownotes/util/DialogUtil.java b/SparrowNotes/app/src/main/java/com/example/sparrownotes/util/DialogUtil.java
new file mode 100644
index 0000000..a5ea92a
--- /dev/null
+++ b/SparrowNotes/app/src/main/java/com/example/sparrownotes/util/DialogUtil.java
@@ -0,0 +1,228 @@
+package com.example.sparrownotes.util;
+
+import android.app.AlertDialog;
+import android.content.Context;
+import android.content.Intent;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.EditText;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import com.example.sparrownotes.MainActivity;
+import com.example.sparrownotes.R;
+import com.example.sparrownotes.bean.NoteBean;
+import com.example.sparrownotes.bean.UserBean;
+import com.example.sparrownotes.dao.*;
+
+/**
+ * 自定义对话框
+ *
+ */
+public class DialogUtil {
+ /**
+ * 查找标题消息框
+ *
+ * @param context 上下文
+ */
+ public static void searchTitleDialog(Context context) {
+ SharedPreferenceUtil spu = SharedPreferenceUtil.getInstance(context);
+ // 获得布局管理器
+ LayoutInflater inflater = LayoutInflater.from(context);
+ // 将布局转换成View
+ View view = inflater.inflate(R.layout.search_title_dialog, null);
+ final EditText editText = view.findViewById(R.id.edit);
+ AlertDialog.Builder builder = new AlertDialog.Builder(context);
+ builder.setTitle("按标题查找")
+ .setView(view)
+ .setIcon(R.drawable.search_icon_title)
+ .setPositiveButton("确定", (dialog, which) -> {
+ // 搜索条件传入sp
+ spu.putString(Constant.SEARCH_FOR_WHAT, "title");
+ spu.putString(Constant.SEARCH_VALUE, editText.getText().toString());
+ // 提醒用户下拉刷新
+ Toast.makeText(context, "下拉刷新", Toast.LENGTH_SHORT).show();
+ })
+ .setNegativeButton("取消", (dialog, which) -> {
+ });
+ builder.create().show();
+ }
+
+ /**
+ * 查找内容消息框
+ *
+ * @param context 上下文
+ */
+ public static void searchContentDialog(Context context) {
+ SharedPreferenceUtil spu = SharedPreferenceUtil.getInstance(context);
+ // 获得布局管理器
+ LayoutInflater inflater = LayoutInflater.from(context);
+ // 将布局转换成View
+ View view = inflater.inflate(R.layout.search_content_dialog, null);
+ final EditText editText = view.findViewById(R.id.edit);
+ AlertDialog.Builder builder = new AlertDialog.Builder(context);
+ builder.setTitle("按内容查找")
+ .setView(view)
+ .setIcon(R.drawable.search_icon_content)
+ .setPositiveButton("确定", (dialog, which) -> {
+ // 搜索条件传入sp
+ spu.putString(Constant.SEARCH_FOR_WHAT, "content");
+ spu.putString(Constant.SEARCH_VALUE, editText.getText().toString());
+ // 提醒用户下拉刷新
+ Toast.makeText(context, "下拉刷新", Toast.LENGTH_SHORT).show();
+ })
+ .setNegativeButton("取消", (dialog, which) -> {
+ });
+ builder.create().show();
+ }
+
+ /**
+ * 查找分类消息框
+ *
+ * @param context
+ */
+ public static void searchCategoryDialog(final Context context) {
+ SharedPreferenceUtil spu = SharedPreferenceUtil.getInstance(context);
+ final String[] categories = new String[]{"便签", "链接", "位置", "消费", "日子", "心情", "账户", "三省"};
+ final String[] category = new String[1];
+ AlertDialog.Builder builder = new AlertDialog.Builder(context);
+ builder.setTitle("按分类查找")
+ .setIcon(R.drawable.search_icon_category)
+ .setSingleChoiceItems(categories, 0, (dialog, which) -> category[0] = categories[which])
+ .setPositiveButton("确认", (dialog, which) -> {
+ // 搜索条件传入sp
+ spu.putString(Constant.SEARCH_FOR_WHAT, "category");
+ spu.putString(Constant.SEARCH_VALUE, category[0]);
+ // 提醒用户下拉刷新
+ Toast.makeText(context, "下拉刷新", Toast.LENGTH_SHORT).show();
+ })
+ .setNegativeButton("取消", null)
+ .show();
+ }
+
+ /**
+ * 修改note消息框
+ *
+ * @param context
+ */
+ public static void editNoteDialog(final Context context, int noteID) {
+ SharedPreferenceUtil spu = SharedPreferenceUtil.getInstance(context);
+ NoteDao noteDao = new NoteDao(context);
+ NoteBean noteItem = noteDao.queryById(noteID, spu.getInt(Constant.USER_ID));
+ // 获得布局管理器
+ LayoutInflater inflater = LayoutInflater.from(context);
+ // 将布局转换成View
+ View view = inflater.inflate(R.layout.edit_note_dialog, null);
+ final EditText editTile, editContent;
+ editTile = view.findViewById(R.id.edit_title);
+ editContent = view.findViewById(R.id.edit_content);
+ // 将原本的值显示出来
+ editTile.setText(noteItem.getTitle());
+ editContent.setText(noteItem.getContent());
+ AlertDialog.Builder builder = new AlertDialog.Builder(context);
+ builder.setTitle("编辑")
+ .setView(view)
+ .setIcon(R.drawable.icon_edit)
+ .setPositiveButton("确认", (dialog, which) -> {
+ // 将用户输入存入数据库
+ noteItem.setTitle(editTile.getText().toString().trim());
+ noteItem.setContent(editContent.getText().toString().trim());
+ noteDao.update(noteItem);
+ // 提醒用户下拉刷新
+ Toast.makeText(context, "下拉刷新", Toast.LENGTH_SHORT).show();
+ })
+ .setNegativeButton("取消", null)
+ .show();
+ }
+
+ /**
+ * 修改信息
+ *
+ * @param context
+ */
+ public static void editInfoDialog(final Context context, int userID) {
+ SharedPreferenceUtil spu = SharedPreferenceUtil.getInstance(context);
+ UserDao userDao = new UserDao(context);
+ UserBean userItem = userDao.queryById(userID);
+ // 获得布局管理器
+ LayoutInflater inflater = LayoutInflater.from(context);
+ // 将布局转换成View
+ View view = inflater.inflate(R.layout.edit_info_dialog, null);
+ final EditText editUsername, editPassword, editEmail;
+ editUsername = view.findViewById(R.id.edit_username_info);
+ editPassword = view.findViewById(R.id.edit_password_info);
+ editEmail = view.findViewById(R.id.edit_email_info);
+ // 将原本的值显示出来
+ editUsername.setText(userItem.getUserName());
+ editPassword.setText(userItem.getPassword());
+ editEmail.setText(userItem.getEmail());
+ AlertDialog.Builder builder = new AlertDialog.Builder(context);
+ builder.setTitle("修改信息")
+ .setView(view)
+ .setIcon(R.drawable.icon_gear)
+ .setPositiveButton("确认", (dialog, which) -> {
+ // 将用户输入存入数据库
+ userItem.setUserName(editUsername.getText().toString().trim());
+ userItem.setPassword(editPassword.getText().toString().trim());
+ userItem.setEmail(editEmail.getText().toString().trim());
+ userDao.update(userItem);
+ // 跳转回登录页面并且清除勾选
+ spu.putBoolean(Constant.AUTO_LOGIN, false);
+ spu.putBoolean(Constant.REMEMBER_PWD, false);
+ Intent intent = new Intent(context, MainActivity.class);
+ context.startActivity(intent);
+ })
+ .setNegativeButton("取消", null)
+ .show();
+ }
+
+ /**
+ * 修改问候语
+ * 实现失败了 功能砍掉了 方法先留着
+ *
+ * @param context
+ */
+ public static void editGreetingDialog(final Context context) {
+ // 获得布局管理器
+ LayoutInflater inflater = LayoutInflater.from(context);
+ // 将布局转换成View
+ View view = inflater.inflate(R.layout.edit_greeting_dialog, null);
+ final EditText editText;
+ final TextView textView;
+ editText = view.findViewById(R.id.edit);
+ AlertDialog.Builder builder = new AlertDialog.Builder(context);
+ builder.setTitle("修改问候语")
+ .setView(view)
+ .setIcon(R.drawable.icon_smile)
+ .setPositiveButton("确认", (dialog, which) -> {
+
+ editText.getText().toString();
+ })
+ .setNegativeButton("取消", null)
+ .show();
+ }
+
+ /**
+ * 注销账户
+ *
+ * @param context
+ */
+ public static void dismissDialog(final Context context, int userID) {
+ SharedPreferenceUtil spu = SharedPreferenceUtil.getInstance(context);
+ UserDao userDao = new UserDao(context);
+ AlertDialog.Builder builder = new AlertDialog.Builder(context);
+ builder.setTitle("提示")
+ .setMessage("是否要注销账户")
+ .setIcon(R.drawable.icon_warning)
+ .setPositiveButton("确认", (dialog, which) -> {
+ userDao.delete(userID);
+ // 跳转回登录页面并且清除勾选
+ spu.putBoolean(Constant.AUTO_LOGIN, false);
+ spu.putBoolean(Constant.REMEMBER_PWD, false);
+ Intent intent = new Intent(context, MainActivity.class);
+ context.startActivity(intent);
+ })
+ .setNegativeButton("取消", null)
+ .show();
+ }
+}
diff --git a/SparrowNotes/app/src/main/java/com/example/sparrownotes/util/NoScrollViewPager.java b/SparrowNotes/app/src/main/java/com/example/sparrownotes/util/NoScrollViewPager.java
new file mode 100644
index 0000000..0bd059c
--- /dev/null
+++ b/SparrowNotes/app/src/main/java/com/example/sparrownotes/util/NoScrollViewPager.java
@@ -0,0 +1,39 @@
+package com.example.sparrownotes.util;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.view.MotionEvent;
+
+import androidx.viewpager.widget.ViewPager;
+
+/**
+ * 自定义ViewPager 将滑动翻页取消
+ */
+public class NoScrollViewPager extends ViewPager {
+ /**
+ * true表示可以滑动,false不能滑动
+ */
+ private boolean isPagingEnabled = false;
+
+ public NoScrollViewPager(Context context) {
+ super(context);
+ }
+
+ public NoScrollViewPager(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ @Override
+ public boolean onTouchEvent(MotionEvent event) {
+ return this.isPagingEnabled && super.onTouchEvent(event);
+ }
+
+ @Override
+ public boolean onInterceptTouchEvent(MotionEvent event) {
+ return this.isPagingEnabled && super.onInterceptTouchEvent(event);
+ }
+
+ public void setPagerEnabled(boolean enabled) {
+ this.isPagingEnabled = enabled;
+ }
+}
\ No newline at end of file
diff --git a/SparrowNotes/app/src/main/java/com/example/sparrownotes/util/SharedPreferenceUtil.java b/SparrowNotes/app/src/main/java/com/example/sparrownotes/util/SharedPreferenceUtil.java
new file mode 100644
index 0000000..eac683e
--- /dev/null
+++ b/SparrowNotes/app/src/main/java/com/example/sparrownotes/util/SharedPreferenceUtil.java
@@ -0,0 +1,161 @@
+package com.example.sparrownotes.util;
+
+import android.annotation.SuppressLint;
+import android.content.Context;
+import android.content.SharedPreferences;
+
+/**
+ * 以键值对的方式提供本地文件存储
+ */
+public class SharedPreferenceUtil {
+ /**
+ * 文件名
+ */
+ private static final String NAME = "sparrow_share";
+ private Context context;
+ private SharedPreferences.Editor editor;
+ private SharedPreferences share;
+ private static SharedPreferenceUtil sharedPreferenceUtil;
+
+ /**
+ * 构造方法获取SharedPreferences
+ *
+ * @param context 上下文
+ */
+ @SuppressLint("CommitPrefEdits")
+ private SharedPreferenceUtil(Context context) {
+ this.context = context;
+ if (context != null) {
+ share = context.getSharedPreferences(NAME, Context.MODE_PRIVATE);
+ editor = share.edit();
+ }
+ }
+
+ public static SharedPreferenceUtil getInstance(Context con) {
+ if (sharedPreferenceUtil == null) {
+ sharedPreferenceUtil = new SharedPreferenceUtil(con);
+ }
+ return sharedPreferenceUtil;
+ }
+
+ /**
+ * 保存String类型的数据
+ *
+ * @param key 键名称
+ * @param value 保存的值
+ */
+ public void putString(String key, String value) {
+ if (null == value) {
+ value = "";
+ }
+ editor.putString(key, value);
+ editor.apply();
+ }
+
+ /**
+ * 保存int类型的数据
+ *
+ * @param key 键名称
+ * @param value 保存的值
+ * @return
+ */
+ public void putInt(String key, int value) {
+ editor.putInt(key, value);
+ editor.apply();
+ }
+
+ /**
+ * 保存Float类型的数据
+ *
+ * @param key 键名称
+ * @param value 保存的值
+ */
+ public void putFloat(String key, float value) {
+ editor.putFloat(key, value);
+ editor.apply();
+ }
+
+ /**
+ * 保存boolean类型的数据
+ *
+ * @param key 键名称
+ * @param value 保存的值
+ */
+ public void putBoolean(String key, boolean value) {
+ editor.putBoolean(key, value);
+ editor.apply();
+ }
+
+ /**
+ * 保存Long类型的数据
+ *
+ * @param key 键名称
+ * @param value 保存的值
+ */
+ public void putLong(String key, long value) {
+ editor.putLong(key, value);
+ editor.apply();
+ }
+
+
+ /**
+ * 获取String类型的数据
+ *
+ * @param key 键名称
+ */
+ public String getString(String key) {
+ return share.getString(key, "");
+ }
+
+ /**
+ * 获取int类型的数据
+ *
+ * @param key 键名称
+ * @return 返回的int型数据
+ */
+ public int getInt(String key) {
+ return share.getInt(key, 0);
+ }
+
+ /**
+ * 获取Float类型的数据
+ *
+ * @param key 键名称
+ * @return 返回的float型数据
+ */
+ public float getFloat(String key) {
+ return share.getFloat(key, 0.00f);
+ }
+
+ /**
+ * 获取Long类型的数据
+ *
+ * @param key 键名称
+ * @return 返回的long型数据
+ */
+ public long getLong(String key) {
+ return share.getLong(key, 0);
+ }
+
+ /**
+ * 获取boolean类型的数据
+ *
+ * @param key 键名称
+ * @return 返回的boolean型数据
+ */
+ public boolean getBoolean(String key) {
+ return share.getBoolean(key, false);
+ }
+
+ /**
+ * 删除不需要的数据
+ *
+ * @param key 键名称
+ */
+ public void removeKey(String key) {
+ editor.remove(key);
+ editor.apply();
+ }
+
+
+}
\ No newline at end of file
diff --git a/SparrowNotes/app/src/main/res/anim/from_left.xml b/SparrowNotes/app/src/main/res/anim/from_left.xml
new file mode 100644
index 0000000..9e9f330
--- /dev/null
+++ b/SparrowNotes/app/src/main/res/anim/from_left.xml
@@ -0,0 +1,7 @@
+
+
+
+
\ No newline at end of file
diff --git a/SparrowNotes/app/src/main/res/anim/from_right.xml b/SparrowNotes/app/src/main/res/anim/from_right.xml
new file mode 100644
index 0000000..fb93e43
--- /dev/null
+++ b/SparrowNotes/app/src/main/res/anim/from_right.xml
@@ -0,0 +1,7 @@
+
+
+
+
\ No newline at end of file
diff --git a/SparrowNotes/app/src/main/res/anim/to_left.xml b/SparrowNotes/app/src/main/res/anim/to_left.xml
new file mode 100644
index 0000000..96d8caf
--- /dev/null
+++ b/SparrowNotes/app/src/main/res/anim/to_left.xml
@@ -0,0 +1,7 @@
+
+
+
+
\ No newline at end of file
diff --git a/SparrowNotes/app/src/main/res/anim/to_right.xml b/SparrowNotes/app/src/main/res/anim/to_right.xml
new file mode 100644
index 0000000..efeb18c
--- /dev/null
+++ b/SparrowNotes/app/src/main/res/anim/to_right.xml
@@ -0,0 +1,7 @@
+
+
+
+
\ No newline at end of file
diff --git a/SparrowNotes/app/src/main/res/drawable-v24/ic_launcher_foreground.xml b/SparrowNotes/app/src/main/res/drawable-v24/ic_launcher_foreground.xml
new file mode 100644
index 0000000..2b068d1
--- /dev/null
+++ b/SparrowNotes/app/src/main/res/drawable-v24/ic_launcher_foreground.xml
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/SparrowNotes/app/src/main/res/drawable-xhdpi/cate_account.png b/SparrowNotes/app/src/main/res/drawable-xhdpi/cate_account.png
new file mode 100644
index 0000000..64b7e23
Binary files /dev/null and b/SparrowNotes/app/src/main/res/drawable-xhdpi/cate_account.png differ
diff --git a/SparrowNotes/app/src/main/res/drawable-xhdpi/cate_bill.png b/SparrowNotes/app/src/main/res/drawable-xhdpi/cate_bill.png
new file mode 100644
index 0000000..eb3a163
Binary files /dev/null and b/SparrowNotes/app/src/main/res/drawable-xhdpi/cate_bill.png differ
diff --git a/SparrowNotes/app/src/main/res/drawable-xhdpi/cate_date.png b/SparrowNotes/app/src/main/res/drawable-xhdpi/cate_date.png
new file mode 100644
index 0000000..469e232
Binary files /dev/null and b/SparrowNotes/app/src/main/res/drawable-xhdpi/cate_date.png differ
diff --git a/SparrowNotes/app/src/main/res/drawable-xhdpi/cate_link.png b/SparrowNotes/app/src/main/res/drawable-xhdpi/cate_link.png
new file mode 100644
index 0000000..86ab08c
Binary files /dev/null and b/SparrowNotes/app/src/main/res/drawable-xhdpi/cate_link.png differ
diff --git a/SparrowNotes/app/src/main/res/drawable-xhdpi/cate_location.png b/SparrowNotes/app/src/main/res/drawable-xhdpi/cate_location.png
new file mode 100644
index 0000000..ddfe697
Binary files /dev/null and b/SparrowNotes/app/src/main/res/drawable-xhdpi/cate_location.png differ
diff --git a/SparrowNotes/app/src/main/res/drawable-xhdpi/cate_mood.png b/SparrowNotes/app/src/main/res/drawable-xhdpi/cate_mood.png
new file mode 100644
index 0000000..8a43061
Binary files /dev/null and b/SparrowNotes/app/src/main/res/drawable-xhdpi/cate_mood.png differ
diff --git a/SparrowNotes/app/src/main/res/drawable-xhdpi/cate_na.png b/SparrowNotes/app/src/main/res/drawable-xhdpi/cate_na.png
new file mode 100644
index 0000000..4bf2237
Binary files /dev/null and b/SparrowNotes/app/src/main/res/drawable-xhdpi/cate_na.png differ
diff --git a/SparrowNotes/app/src/main/res/drawable-xhdpi/cate_note.png b/SparrowNotes/app/src/main/res/drawable-xhdpi/cate_note.png
new file mode 100644
index 0000000..3c30b4d
Binary files /dev/null and b/SparrowNotes/app/src/main/res/drawable-xhdpi/cate_note.png differ
diff --git a/SparrowNotes/app/src/main/res/drawable-xhdpi/cate_question.png b/SparrowNotes/app/src/main/res/drawable-xhdpi/cate_question.png
new file mode 100644
index 0000000..9c1d047
Binary files /dev/null and b/SparrowNotes/app/src/main/res/drawable-xhdpi/cate_question.png differ
diff --git a/SparrowNotes/app/src/main/res/drawable-xhdpi/dock_add_fill.png b/SparrowNotes/app/src/main/res/drawable-xhdpi/dock_add_fill.png
new file mode 100644
index 0000000..a782f99
Binary files /dev/null and b/SparrowNotes/app/src/main/res/drawable-xhdpi/dock_add_fill.png differ
diff --git a/SparrowNotes/app/src/main/res/drawable-xhdpi/dock_add_line.png b/SparrowNotes/app/src/main/res/drawable-xhdpi/dock_add_line.png
new file mode 100644
index 0000000..63820bb
Binary files /dev/null and b/SparrowNotes/app/src/main/res/drawable-xhdpi/dock_add_line.png differ
diff --git a/SparrowNotes/app/src/main/res/drawable-xhdpi/dock_list_fill.png b/SparrowNotes/app/src/main/res/drawable-xhdpi/dock_list_fill.png
new file mode 100644
index 0000000..56e284c
Binary files /dev/null and b/SparrowNotes/app/src/main/res/drawable-xhdpi/dock_list_fill.png differ
diff --git a/SparrowNotes/app/src/main/res/drawable-xhdpi/dock_list_line.png b/SparrowNotes/app/src/main/res/drawable-xhdpi/dock_list_line.png
new file mode 100644
index 0000000..e62075a
Binary files /dev/null and b/SparrowNotes/app/src/main/res/drawable-xhdpi/dock_list_line.png differ
diff --git a/SparrowNotes/app/src/main/res/drawable-xhdpi/dock_me_fill.png b/SparrowNotes/app/src/main/res/drawable-xhdpi/dock_me_fill.png
new file mode 100644
index 0000000..8d33a46
Binary files /dev/null and b/SparrowNotes/app/src/main/res/drawable-xhdpi/dock_me_fill.png differ
diff --git a/SparrowNotes/app/src/main/res/drawable-xhdpi/dock_me_line.png b/SparrowNotes/app/src/main/res/drawable-xhdpi/dock_me_line.png
new file mode 100644
index 0000000..2444eb2
Binary files /dev/null and b/SparrowNotes/app/src/main/res/drawable-xhdpi/dock_me_line.png differ
diff --git a/SparrowNotes/app/src/main/res/drawable-xhdpi/dock_top_fill.png b/SparrowNotes/app/src/main/res/drawable-xhdpi/dock_top_fill.png
new file mode 100644
index 0000000..cff4201
Binary files /dev/null and b/SparrowNotes/app/src/main/res/drawable-xhdpi/dock_top_fill.png differ
diff --git a/SparrowNotes/app/src/main/res/drawable-xhdpi/dock_top_line.png b/SparrowNotes/app/src/main/res/drawable-xhdpi/dock_top_line.png
new file mode 100644
index 0000000..57b4cd3
Binary files /dev/null and b/SparrowNotes/app/src/main/res/drawable-xhdpi/dock_top_line.png differ
diff --git a/SparrowNotes/app/src/main/res/drawable-xhdpi/icon_clock.png b/SparrowNotes/app/src/main/res/drawable-xhdpi/icon_clock.png
new file mode 100644
index 0000000..8e9a854
Binary files /dev/null and b/SparrowNotes/app/src/main/res/drawable-xhdpi/icon_clock.png differ
diff --git a/SparrowNotes/app/src/main/res/drawable-xhdpi/icon_coin.png b/SparrowNotes/app/src/main/res/drawable-xhdpi/icon_coin.png
new file mode 100644
index 0000000..40680a4
Binary files /dev/null and b/SparrowNotes/app/src/main/res/drawable-xhdpi/icon_coin.png differ
diff --git a/SparrowNotes/app/src/main/res/drawable-xhdpi/icon_content.png b/SparrowNotes/app/src/main/res/drawable-xhdpi/icon_content.png
new file mode 100644
index 0000000..45fa710
Binary files /dev/null and b/SparrowNotes/app/src/main/res/drawable-xhdpi/icon_content.png differ
diff --git a/SparrowNotes/app/src/main/res/drawable-xhdpi/icon_earth.png b/SparrowNotes/app/src/main/res/drawable-xhdpi/icon_earth.png
new file mode 100644
index 0000000..e4fa3d6
Binary files /dev/null and b/SparrowNotes/app/src/main/res/drawable-xhdpi/icon_earth.png differ
diff --git a/SparrowNotes/app/src/main/res/drawable-xhdpi/icon_email.png b/SparrowNotes/app/src/main/res/drawable-xhdpi/icon_email.png
new file mode 100644
index 0000000..e8bfc01
Binary files /dev/null and b/SparrowNotes/app/src/main/res/drawable-xhdpi/icon_email.png differ
diff --git a/SparrowNotes/app/src/main/res/drawable-xhdpi/icon_heart.png b/SparrowNotes/app/src/main/res/drawable-xhdpi/icon_heart.png
new file mode 100644
index 0000000..d516782
Binary files /dev/null and b/SparrowNotes/app/src/main/res/drawable-xhdpi/icon_heart.png differ
diff --git a/SparrowNotes/app/src/main/res/drawable-xhdpi/icon_lock.png b/SparrowNotes/app/src/main/res/drawable-xhdpi/icon_lock.png
new file mode 100644
index 0000000..e8a8f75
Binary files /dev/null and b/SparrowNotes/app/src/main/res/drawable-xhdpi/icon_lock.png differ
diff --git a/SparrowNotes/app/src/main/res/drawable-xhdpi/icon_pin.png b/SparrowNotes/app/src/main/res/drawable-xhdpi/icon_pin.png
new file mode 100644
index 0000000..851c131
Binary files /dev/null and b/SparrowNotes/app/src/main/res/drawable-xhdpi/icon_pin.png differ
diff --git a/SparrowNotes/app/src/main/res/drawable-xhdpi/icon_question.png b/SparrowNotes/app/src/main/res/drawable-xhdpi/icon_question.png
new file mode 100644
index 0000000..5553aff
Binary files /dev/null and b/SparrowNotes/app/src/main/res/drawable-xhdpi/icon_question.png differ
diff --git a/SparrowNotes/app/src/main/res/drawable-xhdpi/icon_title.png b/SparrowNotes/app/src/main/res/drawable-xhdpi/icon_title.png
new file mode 100644
index 0000000..0a7ed79
Binary files /dev/null and b/SparrowNotes/app/src/main/res/drawable-xhdpi/icon_title.png differ
diff --git a/SparrowNotes/app/src/main/res/drawable-xhdpi/icon_user.png b/SparrowNotes/app/src/main/res/drawable-xhdpi/icon_user.png
new file mode 100644
index 0000000..2444eb2
Binary files /dev/null and b/SparrowNotes/app/src/main/res/drawable-xhdpi/icon_user.png differ
diff --git a/SparrowNotes/app/src/main/res/drawable-xhdpi/icon_warning.png b/SparrowNotes/app/src/main/res/drawable-xhdpi/icon_warning.png
new file mode 100644
index 0000000..bfdd150
Binary files /dev/null and b/SparrowNotes/app/src/main/res/drawable-xhdpi/icon_warning.png differ
diff --git a/SparrowNotes/app/src/main/res/drawable-xhdpi/moon2.png b/SparrowNotes/app/src/main/res/drawable-xhdpi/moon2.png
new file mode 100644
index 0000000..f08573b
Binary files /dev/null and b/SparrowNotes/app/src/main/res/drawable-xhdpi/moon2.png differ
diff --git a/SparrowNotes/app/src/main/res/drawable-xxhdpi/bg.png b/SparrowNotes/app/src/main/res/drawable-xxhdpi/bg.png
new file mode 100644
index 0000000..6854b97
Binary files /dev/null and b/SparrowNotes/app/src/main/res/drawable-xxhdpi/bg.png differ
diff --git a/SparrowNotes/app/src/main/res/drawable-xxhdpi/hmbg.png b/SparrowNotes/app/src/main/res/drawable-xxhdpi/hmbg.png
new file mode 100644
index 0000000..77cbb91
Binary files /dev/null and b/SparrowNotes/app/src/main/res/drawable-xxhdpi/hmbg.png differ
diff --git a/SparrowNotes/app/src/main/res/drawable-xxhdpi/home_background.png b/SparrowNotes/app/src/main/res/drawable-xxhdpi/home_background.png
new file mode 100644
index 0000000..6029ff0
Binary files /dev/null and b/SparrowNotes/app/src/main/res/drawable-xxhdpi/home_background.png differ
diff --git a/SparrowNotes/app/src/main/res/drawable-xxhdpi/icon_delete.png b/SparrowNotes/app/src/main/res/drawable-xxhdpi/icon_delete.png
new file mode 100644
index 0000000..22b2944
Binary files /dev/null and b/SparrowNotes/app/src/main/res/drawable-xxhdpi/icon_delete.png differ
diff --git a/SparrowNotes/app/src/main/res/drawable-xxhdpi/icon_dismiss.png b/SparrowNotes/app/src/main/res/drawable-xxhdpi/icon_dismiss.png
new file mode 100644
index 0000000..e0f2cb7
Binary files /dev/null and b/SparrowNotes/app/src/main/res/drawable-xxhdpi/icon_dismiss.png differ
diff --git a/SparrowNotes/app/src/main/res/drawable-xxhdpi/icon_edit.png b/SparrowNotes/app/src/main/res/drawable-xxhdpi/icon_edit.png
new file mode 100644
index 0000000..a78394b
Binary files /dev/null and b/SparrowNotes/app/src/main/res/drawable-xxhdpi/icon_edit.png differ
diff --git a/SparrowNotes/app/src/main/res/drawable-xxhdpi/icon_exit.png b/SparrowNotes/app/src/main/res/drawable-xxhdpi/icon_exit.png
new file mode 100644
index 0000000..8d35b18
Binary files /dev/null and b/SparrowNotes/app/src/main/res/drawable-xxhdpi/icon_exit.png differ
diff --git a/SparrowNotes/app/src/main/res/drawable-xxhdpi/icon_gear.png b/SparrowNotes/app/src/main/res/drawable-xxhdpi/icon_gear.png
new file mode 100644
index 0000000..99a7272
Binary files /dev/null and b/SparrowNotes/app/src/main/res/drawable-xxhdpi/icon_gear.png differ
diff --git a/SparrowNotes/app/src/main/res/drawable-xxhdpi/icon_github.png b/SparrowNotes/app/src/main/res/drawable-xxhdpi/icon_github.png
new file mode 100644
index 0000000..775647a
Binary files /dev/null and b/SparrowNotes/app/src/main/res/drawable-xxhdpi/icon_github.png differ
diff --git a/SparrowNotes/app/src/main/res/drawable-xxhdpi/icon_glass.png b/SparrowNotes/app/src/main/res/drawable-xxhdpi/icon_glass.png
new file mode 100644
index 0000000..6e0dbad
Binary files /dev/null and b/SparrowNotes/app/src/main/res/drawable-xxhdpi/icon_glass.png differ
diff --git a/SparrowNotes/app/src/main/res/drawable-xxhdpi/icon_glass_white.png b/SparrowNotes/app/src/main/res/drawable-xxhdpi/icon_glass_white.png
new file mode 100644
index 0000000..64991c4
Binary files /dev/null and b/SparrowNotes/app/src/main/res/drawable-xxhdpi/icon_glass_white.png differ
diff --git a/SparrowNotes/app/src/main/res/drawable-xxhdpi/icon_menu.png b/SparrowNotes/app/src/main/res/drawable-xxhdpi/icon_menu.png
new file mode 100644
index 0000000..6c951fe
Binary files /dev/null and b/SparrowNotes/app/src/main/res/drawable-xxhdpi/icon_menu.png differ
diff --git a/SparrowNotes/app/src/main/res/drawable-xxhdpi/icon_setting.png b/SparrowNotes/app/src/main/res/drawable-xxhdpi/icon_setting.png
new file mode 100644
index 0000000..eda642e
Binary files /dev/null and b/SparrowNotes/app/src/main/res/drawable-xxhdpi/icon_setting.png differ
diff --git a/SparrowNotes/app/src/main/res/drawable-xxhdpi/icon_smile.png b/SparrowNotes/app/src/main/res/drawable-xxhdpi/icon_smile.png
new file mode 100644
index 0000000..41a3d23
Binary files /dev/null and b/SparrowNotes/app/src/main/res/drawable-xxhdpi/icon_smile.png differ
diff --git a/SparrowNotes/app/src/main/res/drawable-xxhdpi/icon_top.png b/SparrowNotes/app/src/main/res/drawable-xxhdpi/icon_top.png
new file mode 100644
index 0000000..57b4cd3
Binary files /dev/null and b/SparrowNotes/app/src/main/res/drawable-xxhdpi/icon_top.png differ
diff --git a/SparrowNotes/app/src/main/res/drawable-xxhdpi/moon.png b/SparrowNotes/app/src/main/res/drawable-xxhdpi/moon.png
new file mode 100644
index 0000000..7db1b50
Binary files /dev/null and b/SparrowNotes/app/src/main/res/drawable-xxhdpi/moon.png differ
diff --git a/SparrowNotes/app/src/main/res/drawable-xxhdpi/search_icon_category.png b/SparrowNotes/app/src/main/res/drawable-xxhdpi/search_icon_category.png
new file mode 100644
index 0000000..f12824b
Binary files /dev/null and b/SparrowNotes/app/src/main/res/drawable-xxhdpi/search_icon_category.png differ
diff --git a/SparrowNotes/app/src/main/res/drawable-xxhdpi/search_icon_content.png b/SparrowNotes/app/src/main/res/drawable-xxhdpi/search_icon_content.png
new file mode 100644
index 0000000..45fa710
Binary files /dev/null and b/SparrowNotes/app/src/main/res/drawable-xxhdpi/search_icon_content.png differ
diff --git a/SparrowNotes/app/src/main/res/drawable-xxhdpi/search_icon_title.png b/SparrowNotes/app/src/main/res/drawable-xxhdpi/search_icon_title.png
new file mode 100644
index 0000000..0a7ed79
Binary files /dev/null and b/SparrowNotes/app/src/main/res/drawable-xxhdpi/search_icon_title.png differ
diff --git a/SparrowNotes/app/src/main/res/drawable-xxhdpi/user_logo.png b/SparrowNotes/app/src/main/res/drawable-xxhdpi/user_logo.png
new file mode 100644
index 0000000..0476fb1
Binary files /dev/null and b/SparrowNotes/app/src/main/res/drawable-xxhdpi/user_logo.png differ
diff --git a/SparrowNotes/app/src/main/res/drawable-xxhdpi/wallpaper.jpg b/SparrowNotes/app/src/main/res/drawable-xxhdpi/wallpaper.jpg
new file mode 100644
index 0000000..77ff7cb
Binary files /dev/null and b/SparrowNotes/app/src/main/res/drawable-xxhdpi/wallpaper.jpg differ
diff --git a/SparrowNotes/app/src/main/res/drawable/btn_cancel_normal.xml b/SparrowNotes/app/src/main/res/drawable/btn_cancel_normal.xml
new file mode 100644
index 0000000..00d49eb
--- /dev/null
+++ b/SparrowNotes/app/src/main/res/drawable/btn_cancel_normal.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/SparrowNotes/app/src/main/res/drawable/btn_cancel_selector.xml b/SparrowNotes/app/src/main/res/drawable/btn_cancel_selector.xml
new file mode 100644
index 0000000..1ce3494
--- /dev/null
+++ b/SparrowNotes/app/src/main/res/drawable/btn_cancel_selector.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/SparrowNotes/app/src/main/res/drawable/btn_login_normal.xml b/SparrowNotes/app/src/main/res/drawable/btn_login_normal.xml
new file mode 100644
index 0000000..9f3de95
--- /dev/null
+++ b/SparrowNotes/app/src/main/res/drawable/btn_login_normal.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/SparrowNotes/app/src/main/res/drawable/btn_login_pressed.xml b/SparrowNotes/app/src/main/res/drawable/btn_login_pressed.xml
new file mode 100644
index 0000000..657ad59
--- /dev/null
+++ b/SparrowNotes/app/src/main/res/drawable/btn_login_pressed.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/SparrowNotes/app/src/main/res/drawable/btn_login_selector.xml b/SparrowNotes/app/src/main/res/drawable/btn_login_selector.xml
new file mode 100644
index 0000000..46300e1
--- /dev/null
+++ b/SparrowNotes/app/src/main/res/drawable/btn_login_selector.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/SparrowNotes/app/src/main/res/drawable/check_hide_pwd_selector.xml b/SparrowNotes/app/src/main/res/drawable/check_hide_pwd_selector.xml
new file mode 100644
index 0000000..5635595
--- /dev/null
+++ b/SparrowNotes/app/src/main/res/drawable/check_hide_pwd_selector.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/SparrowNotes/app/src/main/res/drawable/dock_add_selector.xml b/SparrowNotes/app/src/main/res/drawable/dock_add_selector.xml
new file mode 100644
index 0000000..82f7595
--- /dev/null
+++ b/SparrowNotes/app/src/main/res/drawable/dock_add_selector.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/SparrowNotes/app/src/main/res/drawable/dock_list_selector.xml b/SparrowNotes/app/src/main/res/drawable/dock_list_selector.xml
new file mode 100644
index 0000000..780755a
--- /dev/null
+++ b/SparrowNotes/app/src/main/res/drawable/dock_list_selector.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/SparrowNotes/app/src/main/res/drawable/dock_top_selector.xml b/SparrowNotes/app/src/main/res/drawable/dock_top_selector.xml
new file mode 100644
index 0000000..6fec5ba
--- /dev/null
+++ b/SparrowNotes/app/src/main/res/drawable/dock_top_selector.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/SparrowNotes/app/src/main/res/drawable/eye_closed.png b/SparrowNotes/app/src/main/res/drawable/eye_closed.png
new file mode 100644
index 0000000..6e9fe73
Binary files /dev/null and b/SparrowNotes/app/src/main/res/drawable/eye_closed.png differ
diff --git a/SparrowNotes/app/src/main/res/drawable/eye_open.png b/SparrowNotes/app/src/main/res/drawable/eye_open.png
new file mode 100644
index 0000000..e01471d
Binary files /dev/null and b/SparrowNotes/app/src/main/res/drawable/eye_open.png differ
diff --git a/SparrowNotes/app/src/main/res/drawable/ic_launcher_background.xml b/SparrowNotes/app/src/main/res/drawable/ic_launcher_background.xml
new file mode 100644
index 0000000..07d5da9
--- /dev/null
+++ b/SparrowNotes/app/src/main/res/drawable/ic_launcher_background.xml
@@ -0,0 +1,170 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/SparrowNotes/app/src/main/res/drawable/icon_sparrow.png b/SparrowNotes/app/src/main/res/drawable/icon_sparrow.png
new file mode 100644
index 0000000..add1f56
Binary files /dev/null and b/SparrowNotes/app/src/main/res/drawable/icon_sparrow.png differ
diff --git a/SparrowNotes/app/src/main/res/drawable/item_background.xml b/SparrowNotes/app/src/main/res/drawable/item_background.xml
new file mode 100644
index 0000000..3d9ab75
--- /dev/null
+++ b/SparrowNotes/app/src/main/res/drawable/item_background.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/SparrowNotes/app/src/main/res/layout/activity_find_pwd.xml b/SparrowNotes/app/src/main/res/layout/activity_find_pwd.xml
new file mode 100644
index 0000000..bd421f9
--- /dev/null
+++ b/SparrowNotes/app/src/main/res/layout/activity_find_pwd.xml
@@ -0,0 +1,187 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/SparrowNotes/app/src/main/res/layout/activity_home.xml b/SparrowNotes/app/src/main/res/layout/activity_home.xml
new file mode 100644
index 0000000..e7a6606
--- /dev/null
+++ b/SparrowNotes/app/src/main/res/layout/activity_home.xml
@@ -0,0 +1,129 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/SparrowNotes/app/src/main/res/layout/activity_main.xml b/SparrowNotes/app/src/main/res/layout/activity_main.xml
new file mode 100644
index 0000000..1bfbef3
--- /dev/null
+++ b/SparrowNotes/app/src/main/res/layout/activity_main.xml
@@ -0,0 +1,240 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/SparrowNotes/app/src/main/res/layout/activity_register.xml b/SparrowNotes/app/src/main/res/layout/activity_register.xml
new file mode 100644
index 0000000..3380ba1
--- /dev/null
+++ b/SparrowNotes/app/src/main/res/layout/activity_register.xml
@@ -0,0 +1,216 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/SparrowNotes/app/src/main/res/layout/add_account.xml b/SparrowNotes/app/src/main/res/layout/add_account.xml
new file mode 100644
index 0000000..eabd643
--- /dev/null
+++ b/SparrowNotes/app/src/main/res/layout/add_account.xml
@@ -0,0 +1,130 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/SparrowNotes/app/src/main/res/layout/add_bill.xml b/SparrowNotes/app/src/main/res/layout/add_bill.xml
new file mode 100644
index 0000000..a480547
--- /dev/null
+++ b/SparrowNotes/app/src/main/res/layout/add_bill.xml
@@ -0,0 +1,189 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/SparrowNotes/app/src/main/res/layout/add_date.xml b/SparrowNotes/app/src/main/res/layout/add_date.xml
new file mode 100644
index 0000000..c1c7a55
--- /dev/null
+++ b/SparrowNotes/app/src/main/res/layout/add_date.xml
@@ -0,0 +1,150 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/SparrowNotes/app/src/main/res/layout/add_link.xml b/SparrowNotes/app/src/main/res/layout/add_link.xml
new file mode 100644
index 0000000..cd5ace3
--- /dev/null
+++ b/SparrowNotes/app/src/main/res/layout/add_link.xml
@@ -0,0 +1,101 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/SparrowNotes/app/src/main/res/layout/add_location.xml b/SparrowNotes/app/src/main/res/layout/add_location.xml
new file mode 100644
index 0000000..6bbe887
--- /dev/null
+++ b/SparrowNotes/app/src/main/res/layout/add_location.xml
@@ -0,0 +1,95 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/SparrowNotes/app/src/main/res/layout/add_mood.xml b/SparrowNotes/app/src/main/res/layout/add_mood.xml
new file mode 100644
index 0000000..c576132
--- /dev/null
+++ b/SparrowNotes/app/src/main/res/layout/add_mood.xml
@@ -0,0 +1,95 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/SparrowNotes/app/src/main/res/layout/add_note.xml b/SparrowNotes/app/src/main/res/layout/add_note.xml
new file mode 100644
index 0000000..5216d05
--- /dev/null
+++ b/SparrowNotes/app/src/main/res/layout/add_note.xml
@@ -0,0 +1,95 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/SparrowNotes/app/src/main/res/layout/add_question.xml b/SparrowNotes/app/src/main/res/layout/add_question.xml
new file mode 100644
index 0000000..ac8ab37
--- /dev/null
+++ b/SparrowNotes/app/src/main/res/layout/add_question.xml
@@ -0,0 +1,130 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/SparrowNotes/app/src/main/res/layout/edit_greeting_dialog.xml b/SparrowNotes/app/src/main/res/layout/edit_greeting_dialog.xml
new file mode 100644
index 0000000..76e95da
--- /dev/null
+++ b/SparrowNotes/app/src/main/res/layout/edit_greeting_dialog.xml
@@ -0,0 +1,46 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/SparrowNotes/app/src/main/res/layout/edit_info_dialog.xml b/SparrowNotes/app/src/main/res/layout/edit_info_dialog.xml
new file mode 100644
index 0000000..973990d
--- /dev/null
+++ b/SparrowNotes/app/src/main/res/layout/edit_info_dialog.xml
@@ -0,0 +1,131 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/SparrowNotes/app/src/main/res/layout/edit_note_dialog.xml b/SparrowNotes/app/src/main/res/layout/edit_note_dialog.xml
new file mode 100644
index 0000000..1542cf9
--- /dev/null
+++ b/SparrowNotes/app/src/main/res/layout/edit_note_dialog.xml
@@ -0,0 +1,96 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/SparrowNotes/app/src/main/res/layout/fragment_add.xml b/SparrowNotes/app/src/main/res/layout/fragment_add.xml
new file mode 100644
index 0000000..db401a5
--- /dev/null
+++ b/SparrowNotes/app/src/main/res/layout/fragment_add.xml
@@ -0,0 +1,320 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/SparrowNotes/app/src/main/res/layout/fragment_all.xml b/SparrowNotes/app/src/main/res/layout/fragment_all.xml
new file mode 100644
index 0000000..bc3ed7e
--- /dev/null
+++ b/SparrowNotes/app/src/main/res/layout/fragment_all.xml
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/SparrowNotes/app/src/main/res/layout/fragment_top.xml b/SparrowNotes/app/src/main/res/layout/fragment_top.xml
new file mode 100644
index 0000000..7c9c5ff
--- /dev/null
+++ b/SparrowNotes/app/src/main/res/layout/fragment_top.xml
@@ -0,0 +1,113 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/SparrowNotes/app/src/main/res/layout/nav_header.xml b/SparrowNotes/app/src/main/res/layout/nav_header.xml
new file mode 100644
index 0000000..d78d8ec
--- /dev/null
+++ b/SparrowNotes/app/src/main/res/layout/nav_header.xml
@@ -0,0 +1,77 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/SparrowNotes/app/src/main/res/layout/note_item.xml b/SparrowNotes/app/src/main/res/layout/note_item.xml
new file mode 100644
index 0000000..8f7e836
--- /dev/null
+++ b/SparrowNotes/app/src/main/res/layout/note_item.xml
@@ -0,0 +1,166 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/SparrowNotes/app/src/main/res/layout/search_content_dialog.xml b/SparrowNotes/app/src/main/res/layout/search_content_dialog.xml
new file mode 100644
index 0000000..5e5b62d
--- /dev/null
+++ b/SparrowNotes/app/src/main/res/layout/search_content_dialog.xml
@@ -0,0 +1,43 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/SparrowNotes/app/src/main/res/layout/search_title_dialog.xml b/SparrowNotes/app/src/main/res/layout/search_title_dialog.xml
new file mode 100644
index 0000000..07a2814
--- /dev/null
+++ b/SparrowNotes/app/src/main/res/layout/search_title_dialog.xml
@@ -0,0 +1,43 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/SparrowNotes/app/src/main/res/menu/item_menu_all.xml b/SparrowNotes/app/src/main/res/menu/item_menu_all.xml
new file mode 100644
index 0000000..d26fc46
--- /dev/null
+++ b/SparrowNotes/app/src/main/res/menu/item_menu_all.xml
@@ -0,0 +1,15 @@
+
+
\ No newline at end of file
diff --git a/SparrowNotes/app/src/main/res/menu/item_menu_top.xml b/SparrowNotes/app/src/main/res/menu/item_menu_top.xml
new file mode 100644
index 0000000..0728c93
--- /dev/null
+++ b/SparrowNotes/app/src/main/res/menu/item_menu_top.xml
@@ -0,0 +1,15 @@
+
+
\ No newline at end of file
diff --git a/SparrowNotes/app/src/main/res/menu/nav_menu.xml b/SparrowNotes/app/src/main/res/menu/nav_menu.xml
new file mode 100644
index 0000000..0c761f0
--- /dev/null
+++ b/SparrowNotes/app/src/main/res/menu/nav_menu.xml
@@ -0,0 +1,21 @@
+
+
\ No newline at end of file
diff --git a/SparrowNotes/app/src/main/res/menu/search_menu.xml b/SparrowNotes/app/src/main/res/menu/search_menu.xml
new file mode 100644
index 0000000..c327296
--- /dev/null
+++ b/SparrowNotes/app/src/main/res/menu/search_menu.xml
@@ -0,0 +1,15 @@
+
+
\ No newline at end of file
diff --git a/SparrowNotes/app/src/main/res/menu/toolbar_menu.xml b/SparrowNotes/app/src/main/res/menu/toolbar_menu.xml
new file mode 100644
index 0000000..67f7b42
--- /dev/null
+++ b/SparrowNotes/app/src/main/res/menu/toolbar_menu.xml
@@ -0,0 +1,19 @@
+
+
\ No newline at end of file
diff --git a/SparrowNotes/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/SparrowNotes/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
new file mode 100644
index 0000000..eca70cf
--- /dev/null
+++ b/SparrowNotes/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/SparrowNotes/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/SparrowNotes/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
new file mode 100644
index 0000000..eca70cf
--- /dev/null
+++ b/SparrowNotes/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/SparrowNotes/app/src/main/res/mipmap-hdpi/ic_launcher.png b/SparrowNotes/app/src/main/res/mipmap-hdpi/ic_launcher.png
new file mode 100644
index 0000000..a571e60
Binary files /dev/null and b/SparrowNotes/app/src/main/res/mipmap-hdpi/ic_launcher.png differ
diff --git a/SparrowNotes/app/src/main/res/mipmap-hdpi/ic_launcher_round.png b/SparrowNotes/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
new file mode 100644
index 0000000..61da551
Binary files /dev/null and b/SparrowNotes/app/src/main/res/mipmap-hdpi/ic_launcher_round.png differ
diff --git a/SparrowNotes/app/src/main/res/mipmap-mdpi/ic_launcher.png b/SparrowNotes/app/src/main/res/mipmap-mdpi/ic_launcher.png
new file mode 100644
index 0000000..c41dd28
Binary files /dev/null and b/SparrowNotes/app/src/main/res/mipmap-mdpi/ic_launcher.png differ
diff --git a/SparrowNotes/app/src/main/res/mipmap-mdpi/ic_launcher_round.png b/SparrowNotes/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
new file mode 100644
index 0000000..db5080a
Binary files /dev/null and b/SparrowNotes/app/src/main/res/mipmap-mdpi/ic_launcher_round.png differ
diff --git a/SparrowNotes/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/SparrowNotes/app/src/main/res/mipmap-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..6dba46d
Binary files /dev/null and b/SparrowNotes/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ
diff --git a/SparrowNotes/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png b/SparrowNotes/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
new file mode 100644
index 0000000..da31a87
Binary files /dev/null and b/SparrowNotes/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png differ
diff --git a/SparrowNotes/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/SparrowNotes/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000..15ac681
Binary files /dev/null and b/SparrowNotes/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ
diff --git a/SparrowNotes/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png b/SparrowNotes/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
new file mode 100644
index 0000000..b216f2d
Binary files /dev/null and b/SparrowNotes/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png differ
diff --git a/SparrowNotes/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/SparrowNotes/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
new file mode 100644
index 0000000..f25a419
Binary files /dev/null and b/SparrowNotes/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ
diff --git a/SparrowNotes/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png b/SparrowNotes/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
new file mode 100644
index 0000000..e96783c
Binary files /dev/null and b/SparrowNotes/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png differ
diff --git a/SparrowNotes/app/src/main/res/values/colors.xml b/SparrowNotes/app/src/main/res/values/colors.xml
new file mode 100644
index 0000000..b2c26a7
--- /dev/null
+++ b/SparrowNotes/app/src/main/res/values/colors.xml
@@ -0,0 +1,22 @@
+
+
+ @color/dock
+ #212121
+ #212121
+ #212121
+ #F6F6F6
+ #FFFFFF
+ @color/colorAccent
+ #5A5A5A
+ @color/grey
+ #757575
+ #EEEEEE
+ @color/colorAccent
+
+ #18D6A1
+ #FFCA28
+ #9C79FD
+ #42A5F5
+ #FF1744
+ #D44D44
+
\ No newline at end of file
diff --git a/SparrowNotes/app/src/main/res/values/dimens.xml b/SparrowNotes/app/src/main/res/values/dimens.xml
new file mode 100644
index 0000000..c3993d2
--- /dev/null
+++ b/SparrowNotes/app/src/main/res/values/dimens.xml
@@ -0,0 +1,6 @@
+
+
+ 23sp
+ 18sp
+ 18sp
+
\ No newline at end of file
diff --git a/SparrowNotes/app/src/main/res/values/strings.xml b/SparrowNotes/app/src/main/res/values/strings.xml
new file mode 100644
index 0000000..b2f9209
--- /dev/null
+++ b/SparrowNotes/app/src/main/res/values/strings.xml
@@ -0,0 +1,29 @@
+
+ 月亮笔记
+ 200
+ 编辑
+ 置顶
+ 取消置顶
+ 删除
+ 全部
+ 新建
+ 清空
+ 保存
+ 注册
+ 登录
+
+ 账户
+ 日子
+ 位置
+ 链接
+ 便签
+ 三省
+ 消费
+ 心情
+
+ 收 集
+ 你 零 碎
+ 的 信 息
+ 确定
+ 夜晚悄悄记录下自己的记忆碎片
+
\ No newline at end of file
diff --git a/SparrowNotes/app/src/main/res/values/styles.xml b/SparrowNotes/app/src/main/res/values/styles.xml
new file mode 100644
index 0000000..71fe3f4
--- /dev/null
+++ b/SparrowNotes/app/src/main/res/values/styles.xml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/SparrowNotes/app/src/test/java/com/example/sparrownotes/ExampleUnitTest.java b/SparrowNotes/app/src/test/java/com/example/sparrownotes/ExampleUnitTest.java
new file mode 100644
index 0000000..6f53a4e
--- /dev/null
+++ b/SparrowNotes/app/src/test/java/com/example/sparrownotes/ExampleUnitTest.java
@@ -0,0 +1,17 @@
+package com.example.sparrownotes;
+
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+/**
+ * Example local unit test, which will execute on the development machine (host).
+ *
+ * @see Testing documentation
+ */
+public class ExampleUnitTest {
+ @Test
+ public void addition_isCorrect() {
+ assertEquals(4, 2 + 2);
+ }
+}
\ No newline at end of file
diff --git a/SparrowNotes/build.gradle b/SparrowNotes/build.gradle
new file mode 100644
index 0000000..a741891
--- /dev/null
+++ b/SparrowNotes/build.gradle
@@ -0,0 +1,24 @@
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
+buildscript {
+ repositories {
+ google()
+ jcenter()
+ }
+ dependencies {
+ classpath 'com.android.tools.build:gradle:4.2.2'
+ classpath 'com.jakewharton:butterknife-gradle-plugin:10.2.1'
+ // NOTE: Do not place your application dependencies here; they belong
+ // in the individual module build.gradle files
+ }
+}
+
+allprojects {
+ repositories {
+ google()
+ jcenter()
+ }
+}
+
+task clean(type: Delete) {
+ delete rootProject.buildDir
+}
\ No newline at end of file
diff --git a/SparrowNotes/gradle.properties b/SparrowNotes/gradle.properties
new file mode 100644
index 0000000..c52ac9b
--- /dev/null
+++ b/SparrowNotes/gradle.properties
@@ -0,0 +1,19 @@
+# Project-wide Gradle settings.
+# IDE (e.g. Android Studio) users:
+# Gradle settings configured through the IDE *will override*
+# any settings specified in this file.
+# For more details on how to configure your build environment visit
+# http://www.gradle.org/docs/current/userguide/build_environment.html
+# Specifies the JVM arguments used for the daemon process.
+# The setting is particularly useful for tweaking memory settings.
+org.gradle.jvmargs=-Xmx2048m
+# When configured, Gradle will run in incubating parallel mode.
+# This option should only be used with decoupled projects. More details, visit
+# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
+# org.gradle.parallel=true
+# AndroidX package structure to make it clearer which packages are bundled with the
+# Android operating system, and which are packaged with your app"s APK
+# https://developer.android.com/topic/libraries/support-library/androidx-rn
+android.useAndroidX=true
+# Automatically convert third-party libraries to use AndroidX
+android.enableJetifier=true
\ No newline at end of file
diff --git a/SparrowNotes/gradle/wrapper/gradle-wrapper.jar b/SparrowNotes/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000..f6b961f
Binary files /dev/null and b/SparrowNotes/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/SparrowNotes/gradle/wrapper/gradle-wrapper.properties b/SparrowNotes/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..dae96d3
--- /dev/null
+++ b/SparrowNotes/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Wed Jun 15 16:00:10 CST 2022
+distributionBase=GRADLE_USER_HOME
+distributionUrl=https\://services.gradle.org/distributions/gradle-6.7.1-bin.zip
+distributionPath=wrapper/dists
+zipStorePath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
diff --git a/SparrowNotes/gradlew b/SparrowNotes/gradlew
new file mode 100644
index 0000000..cccdd3d
--- /dev/null
+++ b/SparrowNotes/gradlew
@@ -0,0 +1,172 @@
+#!/usr/bin/env sh
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn () {
+ echo "$*"
+}
+
+die () {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+ NONSTOP* )
+ nonstop=true
+ ;;
+esac
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+ JAVACMD=`cygpath --unix "$JAVACMD"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=$((i+1))
+ done
+ case $i in
+ (0) set -- ;;
+ (1) set -- "$args0" ;;
+ (2) set -- "$args0" "$args1" ;;
+ (3) set -- "$args0" "$args1" "$args2" ;;
+ (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Escape application args
+save () {
+ for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
+ echo " "
+}
+APP_ARGS=$(save "$@")
+
+# Collect all arguments for the java command, following the shell quoting and substitution rules
+eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
+
+# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
+if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
+ cd "$(dirname "$0")"
+fi
+
+exec "$JAVACMD" "$@"
diff --git a/SparrowNotes/gradlew.bat b/SparrowNotes/gradlew.bat
new file mode 100644
index 0000000..f955316
--- /dev/null
+++ b/SparrowNotes/gradlew.bat
@@ -0,0 +1,84 @@
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS=
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto init
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto init
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:init
+@rem Get command-line arguments, handling Windows variants
+
+if not "%OS%" == "Windows_NT" goto win9xME_args
+
+:win9xME_args
+@rem Slurp the command line arguments.
+set CMD_LINE_ARGS=
+set _SKIP=2
+
+:win9xME_args_slurp
+if "x%~1" == "x" goto execute
+
+set CMD_LINE_ARGS=%*
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/SparrowNotes/settings.gradle b/SparrowNotes/settings.gradle
new file mode 100644
index 0000000..eef2fe5
--- /dev/null
+++ b/SparrowNotes/settings.gradle
@@ -0,0 +1,2 @@
+include ':app'
+rootProject.name = "SparrowNotes"
\ No newline at end of file