commit f71b5d2de0813a8d3c09da2c40973fd500c33a2c Author: liuyx Date: Mon May 29 00:06:22 2023 +0800 Init diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..2b75303 --- /dev/null +++ b/.gitignore @@ -0,0 +1,13 @@ +*.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 diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..49f7b87 --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,52 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/compiler.xml b/.idea/compiler.xml new file mode 100644 index 0000000..fb7f4a8 --- /dev/null +++ b/.idea/compiler.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/dbnavigator.xml b/.idea/dbnavigator.xml new file mode 100644 index 0000000..7083124 --- /dev/null +++ b/.idea/dbnavigator.xml @@ -0,0 +1,554 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
\ No newline at end of file diff --git a/.idea/dictionaries/hp.xml b/.idea/dictionaries/hp.xml new file mode 100644 index 0000000..43986f4 --- /dev/null +++ b/.idea/dictionaries/hp.xml @@ -0,0 +1,7 @@ + + + + annoucement + + + \ No newline at end of file diff --git a/.idea/encodings.xml b/.idea/encodings.xml new file mode 100644 index 0000000..15a15b2 --- /dev/null +++ b/.idea/encodings.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..6e5389e --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,20 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/jarRepositories.xml b/.idea/jarRepositories.xml new file mode 100644 index 0000000..8067770 --- /dev/null +++ b/.idea/jarRepositories.xml @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..860da66 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..35eb1dd --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..a23ee67 --- /dev/null +++ b/README.md @@ -0,0 +1,3 @@ +# 简言 + +一款简单的记录文字的软件 diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..61cbe59 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,39 @@ +apply plugin: 'com.android.application' + +android { + signingConfigs { +// debug { +// storeFile file('D:\\apppp\\Android Studio\\_key_directory\\keystore.jks') +// storePassword '951225tyb' +// keyAlias = 'piggynote' +// keyPassword '951225tyb' +// } + } + compileSdkVersion 33 + defaultConfig { + applicationId "cc.liuyx.note" + minSdkVersion 23 + targetSdkVersion 33 + versionCode 3 + versionName "1.3" + testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" + } + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + implementation 'com.android.support:appcompat-v7:28.0.0' + implementation 'com.android.support.constraint:constraint-layout:2.0.0-beta2' + testImplementation 'junit:junit:4.13-beta-3' + androidTestImplementation 'com.android.support.test:runner:1.0.2' + androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' + implementation 'com.android.support:design:28.0.0' + implementation 'org.greenrobot:eventbus:3.0.0' + implementation 'com.githang:status-bar-compat:0.7' +} diff --git a/app/piggy.png b/app/piggy.png new file mode 100644 index 0000000..e34865a Binary files /dev/null and b/app/piggy.png differ diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..f1b4245 --- /dev/null +++ b/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 diff --git a/app/release/app-release.apk b/app/release/app-release.apk new file mode 100644 index 0000000..e13d751 Binary files /dev/null and b/app/release/app-release.apk differ diff --git a/app/release/app.aab b/app/release/app.aab new file mode 100644 index 0000000..81acfd0 Binary files /dev/null and b/app/release/app.aab differ diff --git a/app/release/output.json b/app/release/output.json new file mode 100644 index 0000000..016d299 --- /dev/null +++ b/app/release/output.json @@ -0,0 +1 @@ +[{"outputType":{"type":"APK"},"apkData":{"type":"MAIN","splits":[],"versionCode":3,"versionName":"1.3","enabled":true,"outputFile":"app-release.apk","fullName":"release","baseName":"release"},"path":"app-release.apk","properties":{}}] \ No newline at end of file diff --git a/app/src/androidTest/java/com/example/atry/ExampleInstrumentedTest.java b/app/src/androidTest/java/com/example/atry/ExampleInstrumentedTest.java new file mode 100644 index 0000000..32a73bc --- /dev/null +++ b/app/src/androidTest/java/com/example/atry/ExampleInstrumentedTest.java @@ -0,0 +1,26 @@ +package com.example.atry; + +import android.content.Context; +import android.support.test.InstrumentationRegistry; +import android.support.test.runner.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.getTargetContext(); + + assertEquals("com.example.atry", appContext.getPackageName()); + } +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..ec9cec0 --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/cc/liuyx/note/BaseActivity.java b/app/src/main/java/cc/liuyx/note/BaseActivity.java new file mode 100644 index 0000000..b538da8 --- /dev/null +++ b/app/src/main/java/cc/liuyx/note/BaseActivity.java @@ -0,0 +1,78 @@ +package cc.liuyx.note; + +import android.app.Activity; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.content.SharedPreferences; +import android.content.pm.PackageManager; +import android.content.res.Resources; +import android.graphics.Color; +import android.os.Bundle; +import android.preference.PreferenceManager; +import android.support.v4.content.ContextCompat; +import android.support.v7.app.AppCompatActivity; +import android.util.Log; +import android.util.TypedValue; + +import com.example.atry.R; +import com.githang.statusbar.StatusBarCompat; + +import java.text.ParseException; +import java.text.SimpleDateFormat; + +public abstract class BaseActivity extends AppCompatActivity { + + public final String TAG = "BaseActivity"; + public final String ACTION = "NIGHT_SWITCH"; + protected BroadcastReceiver receiver; + protected IntentFilter filter; + + + @Override + protected void onCreate(Bundle savedInstanceState){ + super.onCreate(savedInstanceState); + setNightMode(); + TypedValue typedValue = new TypedValue(); + this.getTheme().resolveAttribute(R.attr.tvBackground, typedValue, true); + StatusBarCompat.setStatusBarColor(this, ContextCompat.getColor(this, typedValue.resourceId)); + + filter = new IntentFilter(); + filter.addAction(ACTION); + + receiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + needRefresh(); + } + }; + + registerReceiver(receiver, filter); + } + + public boolean isNightMode(){ + SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(getBaseContext()); + return sharedPreferences.getBoolean("nightMode", false); + } + + public void setNightMode(){ + if(isNightMode()) this.setTheme(R.style.NightTheme); + else setTheme(R.style.DayTheme); + + } + + protected abstract void needRefresh(); + + @Override + public void onDestroy(){ + super.onDestroy(); + unregisterReceiver(receiver); + } + + public long calStrToSec(String date) throws ParseException {//decode calender date to second + SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm"); + long secTime = format.parse(date).getTime(); + return secTime; + } +} diff --git a/app/src/main/java/cc/liuyx/note/EditActivity.java b/app/src/main/java/cc/liuyx/note/EditActivity.java new file mode 100644 index 0000000..255f656 --- /dev/null +++ b/app/src/main/java/cc/liuyx/note/EditActivity.java @@ -0,0 +1,212 @@ +package cc.liuyx.note; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.DialogInterface; +import android.content.Intent; +import android.content.SharedPreferences; +import android.os.Bundle; +import android.preference.PreferenceManager; +import android.support.v7.app.AlertDialog; +import android.support.v7.widget.Toolbar; +import android.view.KeyEvent; +import android.view.Menu; +import android.view.MenuItem; +import android.view.View; +import android.widget.AdapterView; +import android.widget.ArrayAdapter; +import android.widget.EditText; +import android.widget.Spinner; + +import com.example.atry.R; + +import java.text.SimpleDateFormat; +import java.util.Arrays; +import java.util.Date; +import java.util.List; + +import cc.liuyx.note.db.NoteDatabase; + +public class EditActivity extends BaseActivity { + + private NoteDatabase dbHelper; + private Context context = this; + private EditText et; + private String old_content = ""; + private String old_time = ""; + private int old_Tag = 1; + private long id = 0; + private int openMode = 0; + private int tag = 1; + private boolean tagChange = false; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.edit_layout); + + Toolbar myToolbar = (Toolbar) findViewById(R.id.my_toolbar); + setSupportActionBar(myToolbar); + getSupportActionBar().setHomeButtonEnabled(true); + + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + + Spinner mySpinner = (Spinner) findViewById(R.id.spinner); + SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context); + List tagList = Arrays.asList(sharedPreferences.getString("tagListString", null).split("_")); //获取tags + ArrayAdapter myAdapter = new ArrayAdapter(this, R.layout.spinner_item, tagList); + myAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); + mySpinner.setAdapter(myAdapter); + + mySpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { + @Override + public void onItemSelected(AdapterView parent, View view, int position, long id) { + tag = (int) id + 1; + tagChange = true; + } + + @Override + public void onNothingSelected(AdapterView parent) { + } + }); + + if (isNightMode()) + myToolbar.setNavigationIcon(getDrawable(R.drawable.ic_keyboard_arrow_left_white_24dp)); + else myToolbar.setNavigationIcon(getDrawable(R.drawable.ic_keyboard_arrow_left_black_24dp)); + + myToolbar.setNavigationOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + Intent intent = new Intent(); + if (openMode == 4) { + if (et.getText().toString().length() == 0) { + intent.putExtra("mode", -1); //nothing new happens. + } else { + intent.putExtra("mode", 0); // new one note; + intent.putExtra("content", et.getText().toString()); + intent.putExtra("time", dateToStr()); + intent.putExtra("tag", tag); + } + } else { + if (et.getText().toString().equals(old_content) && !tagChange) + intent.putExtra("mode", -1); // edit nothing + else { + intent.putExtra("mode", 1); //edit the content + intent.putExtra("content", et.getText().toString()); + intent.putExtra("time", dateToStr()); + intent.putExtra("id", id); + intent.putExtra("tag", tag); + } + } + setResult(RESULT_OK, intent); + finish();//返回 + overridePendingTransition(R.anim.in_lefttoright, R.anim.out_lefttoright); + } + }); + + et = (EditText) findViewById(R.id.et); + + Intent getIntent = getIntent(); + + openMode = getIntent.getIntExtra("mode", 0); + if (openMode == 3) {//打开已存在的note + id = getIntent.getLongExtra("id", 0); + old_content = getIntent.getStringExtra("content"); + old_time = getIntent.getStringExtra("time"); + old_Tag = getIntent.getIntExtra("tag", 1); + et.setText(old_content); + et.setSelection(old_content.length()); + mySpinner.setSelection(old_Tag - 1); + } + } + + @Override + protected void needRefresh() { + setNightMode(); + startActivity(new Intent(this, EditActivity.class)); + overridePendingTransition(R.anim.night_switch, R.anim.night_switch_over); + finish(); + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + getMenuInflater().inflate(R.menu.edit_menu, menu); + return super.onCreateOptionsMenu(menu); + } + + public boolean onKeyDown(int keyCode, KeyEvent event) { + + if (keyCode == KeyEvent.KEYCODE_HOME) { + return true; + } else if (keyCode == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_DOWN) { + Intent intent = new Intent(); + if (openMode == 4) { + if (et.getText().toString().length() == 0) { + intent.putExtra("mode", -1); //nothing new happens. + } else { + intent.putExtra("mode", 0); // new one note; + intent.putExtra("content", et.getText().toString()); + intent.putExtra("time", dateToStr()); + intent.putExtra("tag", tag); + } + } else { + if (et.getText().toString().equals(old_content) && !tagChange) + intent.putExtra("mode", -1); // edit nothing + else { + intent.putExtra("mode", 1); //edit the content + intent.putExtra("content", et.getText().toString()); + intent.putExtra("time", dateToStr()); + intent.putExtra("id", id); + intent.putExtra("tag", tag); + } + } + setResult(RESULT_OK, intent); + finish(); + overridePendingTransition(R.anim.in_lefttoright, R.anim.out_lefttoright); + return true; + } + return super.onKeyDown(keyCode, event); + } + + @SuppressLint("NonConstantResourceId") + @Override + public boolean onOptionsItemSelected(MenuItem item) { + final Intent intent = new Intent(); + switch (item.getItemId()) { + case R.id.delete: + deleteNote(intent); + break; + } + return super.onOptionsItemSelected(item); + } + + public String dateToStr() { + Date date = new Date(); + @SuppressLint("SimpleDateFormat") SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + return simpleDateFormat.format(date); + } + + private void deleteNote(Intent intent) { + new AlertDialog.Builder(EditActivity.this) + .setMessage("Delete this Note ?") + .setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + if (openMode == 4) { + intent.putExtra("mode", -1); // delete the note + setResult(RESULT_OK, intent); + } else { + intent.putExtra("mode", 2); // delete the note + intent.putExtra("id", id); + setResult(RESULT_OK, intent); + } + finish(); + } + }).setNegativeButton(android.R.string.no, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + } + }).create().show(); + } +} diff --git a/app/src/main/java/cc/liuyx/note/FabColorActivity.java b/app/src/main/java/cc/liuyx/note/FabColorActivity.java new file mode 100644 index 0000000..69e9316 --- /dev/null +++ b/app/src/main/java/cc/liuyx/note/FabColorActivity.java @@ -0,0 +1,190 @@ +package cc.liuyx.note; + +import android.annotation.SuppressLint; +import android.content.Intent; +import android.content.SharedPreferences; +import android.os.Bundle; +import android.preference.PreferenceManager; +import android.support.v7.app.AppCompatActivity; +import android.support.v7.widget.Toolbar; +import android.view.KeyEvent; +import android.view.View; +import android.widget.ImageView; +import android.widget.Toast; + +import com.example.atry.R; + +import java.util.Objects; + +public class FabColorActivity extends AppCompatActivity implements View.OnClickListener { + + private Toolbar myToolbar; + private int openMode; + private SharedPreferences sharedPreferences; + private ImageView q,w,e,r,t,y,u,i,o,p, curFab, defFab; + + @Override + protected void onCreate(Bundle savedInstanceState){ + super.onCreate(savedInstanceState); + setContentView(R.layout.setting_fabcolor); + + sharedPreferences = PreferenceManager.getDefaultSharedPreferences(getBaseContext()); + openMode = getIntent().getIntExtra("mode", 1); + + myToolbar = (Toolbar) findViewById(R.id.my_toolbar); + setSupportActionBar(myToolbar); + Objects.requireNonNull(getSupportActionBar()).setHomeButtonEnabled(true); + getSupportActionBar().setDisplayHomeAsUpEnabled(true); //设置toolbar取代actionbar + myToolbar.setNavigationOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + Intent intent = new Intent(); + intent.putExtra("opMode", 0);//无事发生 + setResult(RESULT_OK, intent); + overridePendingTransition(R.anim.in_lefttoright, R.anim.out_lefttoright); + finish(); + } + }); + + initImageView(); + + } + + private void initImageView(){ + q = findViewById(R.id.q); + w = findViewById(R.id.w); + e = findViewById(R.id.e); + r = findViewById(R.id.r); + t = findViewById(R.id.t); + y = findViewById(R.id.y); + u = findViewById(R.id.u); + i = findViewById(R.id.i); + o = findViewById(R.id.o); + p = findViewById(R.id.p); + curFab = findViewById(R.id.curFab); + if(openMode == 1) chooseCurFabColor(sharedPreferences.getInt("fabColor", -500041)); + else chooseCurFabColor(sharedPreferences.getInt("fabPlanColor", -500041)); + defFab = findViewById(R.id.defFab); + setClick(); + } + + private void chooseCurFabColor(int fabColor){ + //根据 preference.xml中的fabColor值调整curFab颜色,从MainActivity抄过来的 + switch (fabColor){ + case -500072: + curFab.setBackgroundResource(R.color.q); + break; + case -500081: + curFab.setBackgroundResource(R.color.w); + break; + case -500061: + curFab.setBackgroundResource(R.color.e); + break; + case -500074: + curFab.setBackgroundResource(R.color.r); + break; + case -500078: + curFab.setBackgroundResource(R.color.t); + break; + case -500083: + curFab.setBackgroundResource(R.color.y); + break; + case -500079: + curFab.setBackgroundResource(R.color.u); + break; + case -500063: + curFab.setBackgroundResource(R.color.i); + break; + case -500066: + curFab.setBackgroundResource(R.color.o); + break; + case -500069: + curFab.setBackgroundResource(R.color.p); + break; + default: + curFab.setBackgroundResource(R.color.fabColor1); + } + } + + + private void setClick(){ + q.setOnClickListener(this); + w.setOnClickListener(this); + e.setOnClickListener(this); + r.setOnClickListener(this); + t.setOnClickListener(this); + y.setOnClickListener(this); + u.setOnClickListener(this); + i.setOnClickListener(this); + o.setOnClickListener(this); + p.setOnClickListener(this); + curFab.setOnClickListener(this); + defFab.setOnClickListener(this); + } + + @SuppressLint("NonConstantResourceId") + @Override + public void onClick(View v) { + if(v.getId() == R.id.curFab){ + Toast.makeText(this, "Current color cannot be selected!", Toast.LENGTH_SHORT).show(); + }else { + + Intent intent = new Intent(); + intent.putExtra("opMode", openMode);//decide which button according to input intent + switch (v.getId()) { + case R.id.q: + intent.putExtra("id", -500072); + break; + case R.id.w: + intent.putExtra("id", -500081); + break; + case R.id.e: + intent.putExtra("id", -500061); + break; + case R.id.r: + intent.putExtra("id", -500074); + break; + case R.id.t: + intent.putExtra("id", -500078); + break; + case R.id.y: + intent.putExtra("id", -500083); + break; + case R.id.u: + intent.putExtra("id", -500079); + break; + case R.id.i: + intent.putExtra("id", -500063); + break; + case R.id.o: + intent.putExtra("id", -500066); + break; + case R.id.p: + intent.putExtra("id", -500069); + break; + case R.id.defFab: + intent.putExtra("id", -500041); + break; + + } + setResult(RESULT_OK, intent); + overridePendingTransition(R.anim.in_lefttoright, R.anim.out_lefttoright); + finish(); + } + } + + public boolean onKeyDown(int keyCode, KeyEvent event) { + + if( keyCode== KeyEvent.KEYCODE_HOME){ + return true; + } else if( keyCode== KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_DOWN){ + Intent intent = new Intent(); + intent.putExtra("opMode", 0); + setResult(RESULT_OK, intent); + finish(); + overridePendingTransition(R.anim.in_lefttoright, R.anim.out_lefttoright); + return true; + } + return super.onKeyDown(keyCode, event); + } +} diff --git a/app/src/main/java/cc/liuyx/note/MainActivity.java b/app/src/main/java/cc/liuyx/note/MainActivity.java new file mode 100644 index 0000000..9e3c2e7 --- /dev/null +++ b/app/src/main/java/cc/liuyx/note/MainActivity.java @@ -0,0 +1,1265 @@ +package cc.liuyx.note; + +import android.annotation.SuppressLint; +import android.app.AlarmManager; +import android.app.PendingIntent; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.DialogInterface; +import android.content.Intent; +import android.content.SharedPreferences; +import android.content.res.ColorStateList; +import android.database.Cursor; +import android.database.sqlite.SQLiteDatabase; +import android.graphics.Color; +import android.graphics.drawable.ColorDrawable; +import android.os.Bundle; +import android.os.Handler; +import android.preference.PreferenceManager; +import android.support.design.widget.FloatingActionButton; +import android.support.v7.app.AlertDialog; +import android.support.v7.widget.SearchView; +import android.support.v7.widget.Toolbar; +import android.text.TextUtils; +import android.util.DisplayMetrics; +import android.util.Log; +import android.view.Gravity; +import android.view.LayoutInflater; +import android.view.Menu; +import android.view.MenuItem; +import android.view.MotionEvent; +import android.view.View; +import android.view.View.OnClickListener; +import android.view.ViewGroup; +import android.view.WindowManager; +import android.widget.AdapterView; +import android.widget.AdapterView.OnItemClickListener; +import android.widget.AdapterView.OnItemLongClickListener; +import android.widget.CompoundButton; +import android.widget.EditText; +import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.ListView; +import android.widget.PopupWindow; +import android.widget.RelativeLayout; +import android.widget.Switch; +import android.widget.TextView; +import android.widget.Toast; + +import cc.liuyx.note.alarm.AlarmReceiver; +import cc.liuyx.note.alarm.EditAlarmActivity; +import cc.liuyx.note.alarm.Plan; +import cc.liuyx.note.alarm.PlanAdapter; +import cc.liuyx.note.alarm.PlanDatabase; +import cc.liuyx.note.adapter.NoteAdapter; +import cc.liuyx.note.adapter.TagAdapter; +import cc.liuyx.note.db.CRUD; +import cc.liuyx.note.db.NoteDatabase; +import cc.liuyx.note.entity.Note; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Calendar; +import java.util.Collections; +import java.util.Comparator; +import java.util.Date; +import java.util.List; +import java.util.Objects; + +import static android.view.View.GONE; + +import com.example.atry.R; + +public class MainActivity extends BaseActivity implements OnItemClickListener, OnItemLongClickListener { + + private NoteDatabase dbHelper; + private PlanDatabase planDbHelper; + + private FloatingActionButton fab; + private FloatingActionButton fab_alarm; + private ListView lv; + private ListView lv_plan; + private LinearLayout lv_layout; + private LinearLayout lv_plan_layout; + + private Context context = this; + private NoteAdapter adapter; + private PlanAdapter planAdapter; + private List noteList = new ArrayList(); + private List planList = new ArrayList(); + private TextView mEmptyView; + + private Toolbar myToolbar; + + private PopupWindow popupWindow; // 左侧弹出菜单 + private PopupWindow popupCover; // 菜单蒙版 + private LayoutInflater layoutInflater; + private RelativeLayout main; + private ViewGroup customView; + private ViewGroup coverView; + private WindowManager wm; + private DisplayMetrics metrics; + private TagAdapter tagAdapter; + + private TextView setting_text; + private ImageView setting_image; + private ListView lv_tag; + private TextView add_tag; + + private BroadcastReceiver myReceiver; + private Achievement achievement; + + private SharedPreferences sharedPreferences; + private Switch content_switch; + + private AlarmManager alarmManager; + + String[] list_String = {"before one month", "before three months", "before six months", "before one year"}; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_main); + + alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE); + achievement = new Achievement(context); + initView(); + + if (super.isNightMode()) + myToolbar.setNavigationIcon(getDrawable(R.drawable.ic_menu_white_24dp)); + else myToolbar.setNavigationIcon(getDrawable(R.drawable.ic_menu_black_24dp)); // 三道杠 + + myToolbar.setNavigationOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + showPopUpWindow(); + } + }); + + } + + private void showPopUpWindow() { + int width = metrics.widthPixels; + int height = metrics.heightPixels; + + popupCover = new PopupWindow(coverView, width, height, false); + popupWindow = new PopupWindow(customView, (int) (width * 0.7), (height), true); + if (isNightMode()) popupWindow.setBackgroundDrawable(new ColorDrawable(Color.LTGRAY)); + popupWindow.setBackgroundDrawable(new ColorDrawable(Color.WHITE)); + popupWindow.setAnimationStyle(R.style.AnimationFade); + popupCover.setAnimationStyle(R.style.AnimationCover); + + + //display the popup window + findViewById(R.id.main_layout).post(new Runnable() {//等待main_layout加载完,再show popupwindow + @Override + public void run() { + popupCover.showAtLocation(main, Gravity.NO_GRAVITY, 0, 0); + popupWindow.showAtLocation(main, Gravity.NO_GRAVITY, 0, 0); + + setting_text = customView.findViewById(R.id.setting_settings_text); + setting_image = customView.findViewById(R.id.setting_settings_image); + lv_tag = customView.findViewById(R.id.lv_tag); + add_tag = customView.findViewById(R.id.add_tag); + + add_tag.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + if (sharedPreferences.getString("tagListString", "").split("_").length < 8) { + final EditText et = new EditText(context); + new AlertDialog.Builder(MainActivity.this) + .setMessage("Enter the name of tag") + .setView(et) + .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + List tagList = Arrays.asList(sharedPreferences.getString("tagListString", null).split("_")); //获取tags + + String name = et.getText().toString(); + if (!tagList.contains(name)) { + SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context); + String oldTagListString = sharedPreferences.getString("tagListString", null); + String newTagListString = oldTagListString + "_" + name; + SharedPreferences.Editor editor = sharedPreferences.edit(); + editor.putString("tagListString", newTagListString); + editor.commit(); + refreshTagList(); + } else + Toast.makeText(context, "Repeated tag!", Toast.LENGTH_SHORT).show(); + } + }).setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + } + }).create().show(); + } else { + Toast.makeText(context, "自定义的标签够多了!", Toast.LENGTH_SHORT).show(); + } + } + }); + + //final SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context); + List tagList = Arrays.asList(sharedPreferences.getString("tagListString", null).split("_")); //获取tags + tagAdapter = new TagAdapter(context, tagList, numOfTagNotes(tagList)); + lv_tag.setAdapter(tagAdapter); + + lv_tag.setOnItemClickListener(new OnItemClickListener() { + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + List tagList = Arrays.asList(sharedPreferences.getString("tagListString", null).split("_")); //获取tags + int tag = position + 1; + List temp = new ArrayList<>(); + for (int i = 0; i < noteList.size(); i++) { + if (noteList.get(i).getTag() == tag) { + Note note = noteList.get(i); + temp.add(note); + } + } + NoteAdapter tempAdapter = new NoteAdapter(context, temp); + lv.setAdapter(tempAdapter); + myToolbar.setTitle(tagList.get(position)); + popupWindow.dismiss(); + Log.d(TAG, position + ""); + } + }); + + lv_tag.setOnItemLongClickListener(new OnItemLongClickListener() { + @Override + public boolean onItemLongClick(AdapterView parent, View view, final int position, long id) { + if (position > 4) { + resetTagsX(parent); + float length = getResources().getDimensionPixelSize(R.dimen.distance); + TextView blank = view.findViewById(R.id.blank_tag); + blank.animate().translationX(length).setDuration(300).start(); + TextView text = view.findViewById(R.id.text_tag); + text.animate().translationX(length).setDuration(300).start(); + ImageView del = view.findViewById(R.id.delete_tag); + del.setVisibility(View.VISIBLE); + del.animate().translationX(length).setDuration(300).start(); + + del.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + new AlertDialog.Builder(MainActivity.this) + .setMessage("All related notes will be tagged as \"no tag\" !") + .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + int tag = position + 1; + for (int i = 0; i < noteList.size(); i++) { + //被删除tag的对应notes tag = 1 + Note temp = noteList.get(i); + if (temp.getTag() == tag) { + temp.setTag(1); + CRUD op = new CRUD(context); + op.open(); + op.updateNote(temp); + op.close(); + } + } + List tagList = Arrays.asList(sharedPreferences.getString("tagListString", null).split("_")); //获取tags + if (tag + 1 < tagList.size()) { + for (int j = tag + 1; j < tagList.size() + 1; j++) { + //大于被删除的tag的所有tag减一 + for (int i = 0; i < noteList.size(); i++) { + Note temp = noteList.get(i); + if (temp.getTag() == j) { + temp.setTag(j - 1); + CRUD op = new CRUD(context); + op.open(); + op.updateNote(temp); + op.close(); + } + } + } + } + + //edit the preference + List newTagList = new ArrayList<>(); + newTagList.addAll(tagList); + newTagList.remove(position); + String newTagListString = TextUtils.join("_", newTagList); + Log.d(TAG, "onClick: " + newTagListString); + SharedPreferences.Editor editor = sharedPreferences.edit(); + editor.putString("tagListString", newTagListString); + editor.commit(); + + refreshTagList(); + } + }).setNegativeButton(android.R.string.no, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + } + }).create().show(); + } + }); + + return true; + } + return false; + } + }); + + + setting_text.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + startActivity(new Intent(MainActivity.this, UserSettingsActivity.class)); + overridePendingTransition(R.anim.in_lefttoright, R.anim.no); + + } + }); + setting_image.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + startActivity(new Intent(MainActivity.this, UserSettingsActivity.class)); + overridePendingTransition(R.anim.in_lefttoright, R.anim.no); + + } + }); + + + coverView.setOnTouchListener(new View.OnTouchListener() { + @Override + public boolean onTouch(View v, MotionEvent event) { + popupWindow.dismiss(); + return true; + } + }); + + popupWindow.setOnDismissListener(new PopupWindow.OnDismissListener() { + @Override + public void onDismiss() { + popupCover.dismiss(); + } + }); + } + }); + + } + + private void refreshTagList() { + SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context); + List tagList = Arrays.asList(sharedPreferences.getString("tagListString", null).split("_")); //获取tags + tagAdapter = new TagAdapter(context, tagList, numOfTagNotes(tagList)); + lv_tag.setAdapter(tagAdapter); + tagAdapter.notifyDataSetChanged(); + } + + private void resetTagsX(AdapterView parent) { + for (int i = 5; i < parent.getCount(); i++) { + View view = parent.getChildAt(i); + if (view.findViewById(R.id.delete_tag).getVisibility() == View.VISIBLE) { + float length = 0; + TextView blank = view.findViewById(R.id.blank_tag); + blank.animate().translationX(length).setDuration(300).start(); + TextView text = view.findViewById(R.id.text_tag); + text.animate().translationX(length).setDuration(300).start(); + ImageView del = view.findViewById(R.id.delete_tag); + del.setVisibility(GONE); + del.animate().translationX(length).setDuration(300).start(); + } + } + } + + @Override + protected void needRefresh() { + setNightMode(); + Intent intent = new Intent(this, MainActivity.class); + intent.putExtra("opMode", 10); + startActivity(intent); + overridePendingTransition(R.anim.night_switch, R.anim.night_switch_over); + if (popupWindow.isShowing()) popupWindow.dismiss(); + finish(); + } + + public void initView() { + + initPrefs(); + + fab = findViewById(R.id.fab); + fab_alarm = findViewById(R.id.fab_alarm); + lv = findViewById(R.id.lv); + lv_plan = findViewById(R.id.lv_plan); + lv_layout = findViewById(R.id.lv_layout); + lv_plan_layout = findViewById(R.id.lv_plan_layout); + content_switch = findViewById(R.id.content_switch); + myToolbar = findViewById(R.id.my_toolbar); + refreshLvVisibility(); + + mEmptyView = findViewById(R.id.emptyView); // search page + + adapter = new NoteAdapter(getApplicationContext(), noteList); + planAdapter = new PlanAdapter(getApplicationContext(), planList); + + refreshListView(); + lv.setAdapter(adapter); + lv.setEmptyView(mEmptyView); // connect empty textview with listview + lv_plan.setAdapter(planAdapter); + + boolean temp = sharedPreferences.getBoolean("content_switch", false); + content_switch.setChecked(temp);//判断是看note还是plan + content_switch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { + SharedPreferences.Editor editor = sharedPreferences.edit(); + editor.putBoolean("content_switch", isChecked); + editor.commit(); + refreshLvVisibility(); + } + }); + + fab.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + Intent intent = new Intent(MainActivity.this, EditActivity.class); + intent.putExtra("mode", 4); // MODE of 'new note' + startActivityForResult(intent, 1); //collect data from edit + overridePendingTransition(R.anim.in_righttoleft, R.anim.out_righttoleft); + + } + }); + fab_alarm.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + Intent intent = new Intent(MainActivity.this, EditAlarmActivity.class); + intent.putExtra("mode", 2); // MODE of 'new plan' + startActivityForResult(intent, 1); + overridePendingTransition(R.anim.in_righttoleft, R.anim.no); + } + }); + + lv.setOnItemClickListener(this); + lv_plan.setOnItemClickListener(this); + + lv.setOnItemLongClickListener(this); + lv_plan.setOnItemLongClickListener(this); + + + setSupportActionBar(myToolbar); + getSupportActionBar().setHomeButtonEnabled(true); + getSupportActionBar().setDisplayHomeAsUpEnabled(true); //设置toolbar取代actionbar + initPopupView(); + } + + private void refreshLvVisibility() { + //决定应该现实notes还是plans + boolean temp = sharedPreferences.getBoolean("content_switch", false); + if (temp) { + lv_layout.setVisibility(GONE); + lv_plan_layout.setVisibility(View.VISIBLE); + } else { + lv_layout.setVisibility(View.VISIBLE); + lv_plan_layout.setVisibility(GONE); + } + myToolbar.setTitleTextAppearance(this, R.style.Toolbar_Title); + if (temp) myToolbar.setTitle("所有计划"); + else myToolbar.setTitle("所有笔记"); + } + + public void initPopupView() { + //instantiate the popup.xml layout file + layoutInflater = (LayoutInflater) MainActivity.this.getSystemService(Context.LAYOUT_INFLATER_SERVICE); + customView = (ViewGroup) layoutInflater.inflate(R.layout.setting_layout, null); + coverView = (ViewGroup) layoutInflater.inflate(R.layout.setting_cover, null); + + main = findViewById(R.id.main_layout); + //instantiate popup window + wm = getWindowManager(); + metrics = new DisplayMetrics(); + wm.getDefaultDisplay().getMetrics(metrics); + + } + + private void initPrefs() { + //initialize all useful SharedPreferences for the first time the app runs + + sharedPreferences = PreferenceManager.getDefaultSharedPreferences(getBaseContext()); + SharedPreferences.Editor editor = sharedPreferences.edit(); + if (!sharedPreferences.contains("nightMode")) { + editor.putBoolean("nightMode", false); + editor.commit(); + } + if (!sharedPreferences.contains("reverseSort")) { + editor.putBoolean("reverseSort", false); + editor.commit(); + } + if (!sharedPreferences.contains("fabColor")) { + editor.putInt("fabColor", -500041); + editor.commit(); + } + if (!sharedPreferences.contains("tagListString")) { + String s = "no tag_life_study_work_play"; + editor.putString("tagListString", s); + editor.commit(); + } + if (!sharedPreferences.contains("content_switch")) { + editor.putBoolean("content_switch", false); + editor.commit(); + } + if (!sharedPreferences.contains("fabPlanColor")) { + editor.putInt("fabPlanColor", -500041); + editor.commit(); + } + if (!sharedPreferences.contains("noteTitle")) { + editor.putBoolean("noteTitle", true); + editor.commit(); + } + + + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + getMenuInflater().inflate(R.menu.main_menu, menu); + + //search setting + MenuItem mSearch = menu.findItem(R.id.action_search); + SearchView mSearchView = (SearchView) mSearch.getActionView(); + + mSearchView.setQueryHint("Search"); + mSearchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() { + @Override + public boolean onQueryTextSubmit(String query) { + return false; + } + + @Override + public boolean onQueryTextChange(String newText) { + if (content_switch.isChecked()) planAdapter.getFilter().filter(newText); + else adapter.getFilter().filter(newText); + return false; + } + }); + final int mode = (content_switch.isChecked() ? 2 : 1); + final String itemName = (mode == 1 ? "notes" : "plans"); + new Handler().post(new Runnable() { + @Override + public void run() { + final View view = findViewById(R.id.menu_clear); + + if (view != null) { + view.setOnLongClickListener(new View.OnLongClickListener() { + @Override + public boolean onLongClick(View v) { + AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this); + builder.setTitle("Delete all " + itemName); + builder.setIcon(R.drawable.ic_error_outline_black_24dp); + builder.setItems(list_String, new DialogInterface.OnClickListener() {//列表对话框; + @Override + public void onClick(DialogInterface dialog, final int which) {//根据这里which值,即可以指定是点击哪一个Item; + new AlertDialog.Builder(MainActivity.this) + .setMessage("Do you want to delete all " + itemName + " " + list_String[which] + "? ") + .setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int a) { + Log.d(TAG, "onClick: " + which); + removeSelectItems(which, mode); + refreshListView(); + } + + //根据模式与时长删除对顶的计划s/笔记s + private void removeSelectItems(int which, int mode) { + int monthNum = 0; + switch (which) { + case 0: + monthNum = 1; + break; + case 1: + monthNum = 3; + break; + case 2: + monthNum = 6; + break; + case 3: + monthNum = 12; + break; + } + Calendar rightNow = Calendar.getInstance(); + rightNow.add(Calendar.MONTH, -monthNum);//日期加3个月 + Date selectDate = rightNow.getTime(); + SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + String selectDateStr = simpleDateFormat.format(selectDate); + Log.d(TAG, "removeSelectItems: " + selectDateStr); + switch (mode) { + case 1: //notes + dbHelper = new NoteDatabase(context); + SQLiteDatabase db = dbHelper.getWritableDatabase(); + Cursor cursor = db.rawQuery("select * from notes", null); + while (cursor.moveToNext()) { + if (cursor.getString(cursor.getColumnIndex(NoteDatabase.TIME)).compareTo(selectDateStr) < 0) { + db.delete("notes", NoteDatabase.ID + "=?", new String[]{Long.toString(cursor.getLong(cursor.getColumnIndex(NoteDatabase.ID)))}); + } + } + db.execSQL("update sqlite_sequence set seq=0 where name='notes'"); //reset id to 1 + refreshListView(); + break; + case 2: //plans + planDbHelper = new PlanDatabase(context); + SQLiteDatabase pdb = planDbHelper.getWritableDatabase(); + Cursor pcursor = pdb.rawQuery("select * from plans", null); + while (pcursor.moveToNext()) { + if (pcursor.getString(pcursor.getColumnIndex(PlanDatabase.TIME)).compareTo(selectDateStr) < 0) { + pdb.delete("plans", PlanDatabase.ID + "=?", new String[]{Long.toString(pcursor.getLong(pcursor.getColumnIndex(PlanDatabase.ID)))}); + } + } + pdb.execSQL("update sqlite_sequence set seq=0 where name='plans'"); + refreshListView(); + break; + } + } + }).setNegativeButton(android.R.string.no, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + } + }).create().show(); + } + }); + + AlertDialog dialog = builder.create(); + dialog.show(); + return true; + } + }); + } + } + }); + + + return super.onCreateOptionsMenu(menu); + } + + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + switch (item.getItemId()) { + case R.id.menu_clear: + if (!content_switch.isChecked()) { + new AlertDialog.Builder(MainActivity.this) + .setMessage("Delete All Notes ?") + .setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dbHelper = new NoteDatabase(context); + SQLiteDatabase db = dbHelper.getWritableDatabase(); + db.delete("notes", null, null);//delete data in table NOTES + db.execSQL("update sqlite_sequence set seq=0 where name='notes'"); //reset id to 1 + refreshListView(); + } + }).setNegativeButton(android.R.string.no, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + } + }).create().show(); + } else { + new AlertDialog.Builder(MainActivity.this) + .setMessage("Delete All Plans ?") + .setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + planDbHelper = new PlanDatabase(context); + SQLiteDatabase db = planDbHelper.getWritableDatabase(); + db.delete("plans", null, null);//delete data in table NOTES + db.execSQL("update sqlite_sequence set seq=0 where name='plans'"); //reset id to 1 + refreshListView(); + } + }).setNegativeButton(android.R.string.no, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + } + }).create().show(); + } + + break; + case R.id.refresh: + myToolbar.setTitle("All Notes"); + lv.setAdapter(adapter); + break; + } + return super.onOptionsItemSelected(item); + } + + //刷新listview + public void refreshListView() { + SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this); + int fabColor = sharedPreferences.getInt("fabColor", -500041); + chooseFabColor(fabColor); + int fabPlanColor = sharedPreferences.getInt("fabPlanColor", -500041); + chooseFabPlanColor(fabPlanColor); + //initialize CRUD + CRUD op = new CRUD(context); + op.open(); + + // set adapter + if (noteList.size() > 0) noteList.clear(); + noteList.addAll(op.getAllNotes()); + if (sharedPreferences.getBoolean("reverseSort", false)) sortNotes(noteList, 2); + else sortNotes(noteList, 1); + op.close(); + adapter.notifyDataSetChanged(); + + cc.liuyx.note.alarm.CRUD op1 = new cc.liuyx.note.alarm.CRUD(context); + op1.open(); + if (planList.size() > 0) { + cancelAlarms(planList);//删除所有闹钟 + planList.clear(); + } + planList.addAll(op1.getAllPlans()); + startAlarms(planList);//添加所有新闹钟 + if (sharedPreferences.getBoolean("reverseSort", false)) sortPlans(planList, 2); + else sortPlans(planList, 1); + op1.close(); + planAdapter.notifyDataSetChanged(); + + achievement.listen(); + + } + + //根据 preference.xml中的fabColor值调整fab颜色 + private void chooseFabColor(int fabColor) { + + switch (fabColor) { + case -500072: + fab.setBackgroundTintList(ColorStateList.valueOf(getColor(R.color.q))); + break; + case -500081: + fab.setBackgroundTintList(ColorStateList.valueOf(getColor(R.color.w))); + break; + case -500061: + fab.setBackgroundTintList(ColorStateList.valueOf(getColor(R.color.e))); + break; + case -500074: + fab.setBackgroundTintList(ColorStateList.valueOf(getColor(R.color.r))); + break; + case -500078: + fab.setBackgroundTintList(ColorStateList.valueOf(getColor(R.color.t))); + break; + case -500083: + fab.setBackgroundTintList(ColorStateList.valueOf(getColor(R.color.y))); + break; + case -500079: + fab.setBackgroundTintList(ColorStateList.valueOf(getColor(R.color.u))); + break; + case -500063: + fab.setBackgroundTintList(ColorStateList.valueOf(getColor(R.color.i))); + break; + case -500066: + fab.setBackgroundTintList(ColorStateList.valueOf(getColor(R.color.o))); + break; + case -500069: + fab.setBackgroundTintList(ColorStateList.valueOf(getColor(R.color.p))); + break; + default: + fab.setBackgroundTintList(ColorStateList.valueOf(getColor(R.color.fabColor1))); + } + } + + //根据 preference.xml中的fab_alarmColor值调整fab_alarm颜色 + private void chooseFabPlanColor(int fabColor) { + + switch (fabColor) { + case -500072: + fab_alarm.setBackgroundTintList(ColorStateList.valueOf(getColor(R.color.q))); + break; + case -500081: + fab_alarm.setBackgroundTintList(ColorStateList.valueOf(getColor(R.color.w))); + break; + case -500061: + fab_alarm.setBackgroundTintList(ColorStateList.valueOf(getColor(R.color.e))); + break; + case -500074: + fab_alarm.setBackgroundTintList(ColorStateList.valueOf(getColor(R.color.r))); + break; + case -500078: + fab_alarm.setBackgroundTintList(ColorStateList.valueOf(getColor(R.color.t))); + break; + case -500083: + fab_alarm.setBackgroundTintList(ColorStateList.valueOf(getColor(R.color.y))); + break; + case -500079: + fab_alarm.setBackgroundTintList(ColorStateList.valueOf(getColor(R.color.u))); + break; + case -500063: + fab_alarm.setBackgroundTintList(ColorStateList.valueOf(getColor(R.color.i))); + break; + case -500066: + fab_alarm.setBackgroundTintList(ColorStateList.valueOf(getColor(R.color.o))); + break; + case -500069: + fab_alarm.setBackgroundTintList(ColorStateList.valueOf(getColor(R.color.p))); + break; + default: + fab_alarm.setBackgroundTintList(ColorStateList.valueOf(getColor(R.color.fabColor1))); + } + } + + //click item in listView + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + switch (parent.getId()) { + case R.id.lv: + Note curNote = (Note) parent.getItemAtPosition(position); + Intent intent = new Intent(MainActivity.this, EditActivity.class); + intent.putExtra("content", curNote.getContent()); + intent.putExtra("id", curNote.getId()); + intent.putExtra("time", curNote.getTime()); + intent.putExtra("mode", 3); // MODE of 'click to edit' + intent.putExtra("tag", curNote.getTag()); + startActivityForResult(intent, 1); //collect data from edit + overridePendingTransition(R.anim.in_righttoleft, R.anim.out_righttoleft); + break; + case R.id.lv_plan: + Plan curPlan = (Plan) parent.getItemAtPosition(position); + Intent intent1 = new Intent(MainActivity.this, EditAlarmActivity.class); + intent1.putExtra("title", curPlan.getTitle()); + intent1.putExtra("content", curPlan.getContent()); + intent1.putExtra("time", curPlan.getTime()); + intent1.putExtra("mode", 1); + intent1.putExtra("id", curPlan.getId()); + startActivityForResult(intent1, 1); + break; + } + } + + // react to startActivityForResult and collect data + @Override + protected void onActivityResult(int requestCode, int resultCode, Intent data) { + + int returnMode; + long note_Id; + returnMode = data.getExtras().getInt("mode", -1); + note_Id = data.getExtras().getLong("id", 0); + if (returnMode == 1) { //update current note + + String content = data.getExtras().getString("content"); + String time = data.getExtras().getString("time"); + int tag = data.getExtras().getInt("tag", 1); + Note newNote = new Note(content, time, tag); + newNote.setId(note_Id); + CRUD op = new CRUD(context); + op.open(); + op.updateNote(newNote); + achievement.editNote(op.getNote(note_Id).getContent(), content); + op.close(); + + } else if (returnMode == 2) { //delete current note + Note curNote = new Note(); + curNote.setId(note_Id); + CRUD op = new CRUD(context); + op.open(); + op.removeNote(curNote); + op.close(); + achievement.deleteNote(); + } else if (returnMode == 0) { // create new note + String content = data.getExtras().getString("content"); + String time = data.getExtras().getString("time"); + int tag = data.getExtras().getInt("tag", 1); + Note newNote = new Note(content, time, tag); + CRUD op = new CRUD(context); + op.open(); + op.addNote(newNote); + op.close(); + achievement.addNote(content); + } else if (returnMode == 11) {//edit plan + String title = data.getExtras().getString("title", null); + String content = data.getExtras().getString("content", null); + String time = data.getExtras().getString("time", null); + Log.d(TAG, time); + Plan plan = new Plan(title, content, time); + plan.setId(note_Id); + cc.liuyx.note.alarm.CRUD op = new cc.liuyx.note.alarm.CRUD(context); + op.open(); + op.updatePlan(plan); + op.close(); + } else if (returnMode == 12) {//delete existing plan + Plan plan = new Plan(); + plan.setId(note_Id); + cc.liuyx.note.alarm.CRUD op = new cc.liuyx.note.alarm.CRUD(context); + op.open(); + op.removePlan(plan); + op.close(); + } else if (returnMode == 10) {//create new plan + String title = data.getExtras().getString("title", null); + String content = data.getExtras().getString("content", null); + String time = data.getExtras().getString("time", null); + Plan newPlan = new Plan(title, content, time); + cc.liuyx.note.alarm.CRUD op = new cc.liuyx.note.alarm.CRUD(context); + op.open(); + op.addPlan(newPlan); + Log.d(TAG, "onActivityResult: " + time); + op.close(); + } else { + } + refreshListView(); + } + + //longclick item in listView + @Override + public boolean onItemLongClick(AdapterView parent, View view, int position, long id) { + switch (parent.getId()) { + case R.id.lv: + final Note note = noteList.get(position); + new AlertDialog.Builder(MainActivity.this) + .setMessage("Do you want to delete this note ?") + .setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + CRUD op = new CRUD(context); + op.open(); + op.removeNote(note); + op.close(); + refreshListView(); + } + }).setNegativeButton(android.R.string.no, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + } + }).create().show(); + break; + case R.id.lv_plan: + final Plan plan = planList.get(position); + new AlertDialog.Builder(MainActivity.this) + .setMessage("Do you want to delete this plan ?") + .setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + + cc.liuyx.note.alarm.CRUD op = new cc.liuyx.note.alarm.CRUD(context); + op.open(); + op.removePlan(plan); + op.close(); + refreshListView(); + } + }).setNegativeButton(android.R.string.no, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + } + }).create().show(); + break; + } + return true; + } + + //按模式时间排序笔记 + public void sortNotes(List noteList, final int mode) { + Collections.sort(noteList, new Comparator() { + @Override + public int compare(Note o1, Note o2) { + try { + if (mode == 1) { + Log.d(TAG, "sortnotes 1"); + return npLong(dateStrToSec(o2.getTime()) - dateStrToSec(o1.getTime())); + } else if (mode == 2) {//reverseSort + Log.d(TAG, "sortnotes 2"); + return npLong(dateStrToSec(o1.getTime()) - dateStrToSec(o2.getTime())); + } + } catch (ParseException e) { + e.printStackTrace(); + } + return 1; + } + }); + } + + //按模式时间排序计划 + public void sortPlans(List planList, final int mode) { + Collections.sort(planList, new Comparator() { + @Override + public int compare(Plan o1, Plan o2) { + try { + if (mode == 1) + return npLong(calStrToSec(o1.getTime()) - calStrToSec(o2.getTime())); + else if (mode == 2) //reverseSort + return npLong(calStrToSec(o2.getTime()) - calStrToSec(o1.getTime())); + } catch (ParseException e) { + e.printStackTrace(); + } + return 1; + } + }); + } + + //格式转换 string -> milliseconds + public long dateStrToSec(String date) throws ParseException { + @SuppressLint("SimpleDateFormat") SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + return Objects.requireNonNull(format.parse(date)).getTime(); + } + + //统计不同标签的笔记数 + public List numOfTagNotes(List noteStringList) { + Integer[] numbers = new Integer[noteStringList.size()]; + Arrays.fill(numbers, 0); + for (int i = 0; i < noteList.size(); i++) { + numbers[noteList.get(i).getTag() - 1]++; + } + return Arrays.asList(numbers); + } + + //turn long into 1, 0, -1 + public int npLong(Long l) { + if (l > 0) return 1; + else if (l < 0) return -1; + else return 0; + } + + @Override + public void onDestroy() { + super.onDestroy(); + } + + //设置提醒 + private void startAlarm(Plan p) { + Calendar c = p.getPlanTime(); + if (!c.before(Calendar.getInstance())) { + Intent intent = new Intent(MainActivity.this, AlarmReceiver.class); + intent.putExtra("title", p.getTitle()); + intent.putExtra("content", p.getContent()); + intent.putExtra("id", (int) p.getId()); + PendingIntent pendingIntent = PendingIntent.getBroadcast(this, (int) p.getId(), intent, PendingIntent.FLAG_ONE_SHOT | PendingIntent.FLAG_IMMUTABLE); + + alarmManager.setExact(AlarmManager.RTC_WAKEUP, c.getTimeInMillis(), pendingIntent); + } + } + + //设置很多提醒 + private void startAlarms(List plans) { + for (int i = 0; i < plans.size(); i++) startAlarm(plans.get(i)); + } + + //取消提醒 + private void cancelAlarm(Plan p) { + Intent intent = new Intent(this, AlarmReceiver.class); + @SuppressLint("UnspecifiedImmutableFlag") PendingIntent pendingIntent = PendingIntent.getBroadcast(this, (int) p.getId(), intent, PendingIntent.FLAG_ONE_SHOT | PendingIntent.FLAG_IMMUTABLE); + alarmManager.cancel(pendingIntent); + } + + //取消很多提醒 + private void cancelAlarms(List plans) { + for (int i = 0; i < plans.size(); i++) cancelAlarm(plans.get(i)); + } + + @Override + public void onResume() { + super.onResume(); + Intent intent = getIntent(); + if (intent != null && intent.getIntExtra("mode", 0) == 1) { + content_switch.setChecked(true); + refreshLvVisibility(); + } + } + + //achievement system + public class Achievement { + private SharedPreferences sharedPreferences; + + private int noteNumber; + private int wordNumber; + + private int noteLevel; + private int wordLevel; + + public Achievement(Context context) { + sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context); + initPref(); + getPref(); + } + + private void getPref() { + noteNumber = sharedPreferences.getInt("noteNumber", 0); + wordNumber = sharedPreferences.getInt("wordNumber", 0); + noteLevel = sharedPreferences.getInt("noteLevel", 0); + wordLevel = sharedPreferences.getInt("wordLevel", 0); + } + + private void initPref() { + SharedPreferences.Editor editor = sharedPreferences.edit(); + if (!sharedPreferences.contains("noteLevel")) { + editor.putInt("noteLevel", 0); + editor.commit(); + if (!sharedPreferences.contains("wordLevel")) { + editor.putInt("wordLevel", 0); + editor.commit(); + + addCurrent(noteList); + if (sharedPreferences.contains("maxRemainNumber")) { + editor.remove("maxRemainNumber"); + editor.commit(); + } + if (sharedPreferences.contains("remainNumber")) { + editor.remove("remainNumber"); + editor.commit(); + } + if (!sharedPreferences.contains("noteNumber")) { + editor.putInt("noteNumber", 0); + editor.commit(); + addCurrent(noteList); + if (!sharedPreferences.contains("wordNumber")) { + editor.putInt("wordNumber", 0); + editor.commit(); + + } + } + + } + } + } + + //加入已写好的笔记 + private void addCurrent(List list) { + SharedPreferences.Editor editor = sharedPreferences.edit(); + int tempNN = list.size(); + editor.putInt("noteNumber", tempNN); + if (tempNN >= 1000) editor.putInt("noteLevel", 4); + else if (tempNN >= 100) editor.putInt("noteLevel", 3); + else if (tempNN >= 10) editor.putInt("noteLevel", 2); + else if (tempNN >= 1) editor.putInt("noteLevel", 1); + int wordCount = 0; + for (int i = 0; i < list.size(); i++) { + wordCount += list.get(i).getContent().length(); + } + editor.putInt("wordNumber", wordCount); + if (wordCount >= 20000) editor.putInt("noteLevel", 5); + else if (wordCount >= 5000) editor.putInt("noteLevel", 4); + else if (wordCount >= 1000) editor.putInt("noteLevel", 3); + else if (wordCount >= 500) editor.putInt("noteLevel", 2); + else if (wordCount >= 100) editor.putInt("noteLevel", 1); + editor.commit(); + } + + //添加笔记 + public void addNote(String content) { + SharedPreferences.Editor editor = sharedPreferences.edit(); + noteNumber++; + editor.putInt("noteNumber", noteNumber); + + wordNumber += content.length(); + editor.putInt("wordNumber", wordNumber); + + editor.commit(); + } + + //删除笔记 + public void deleteNote() { + + } + + //编辑笔记,修改字数 + public void editNote(String oldContent, String newContent) { + if (newContent.length() > oldContent.length()) { + SharedPreferences.Editor editor = sharedPreferences.edit(); + wordNumber += (newContent.length() - oldContent.length()); + editor.putInt("wordNumber", wordNumber); + editor.commit(); + } + } + + //笔记数成就 + public void noteNumberAchievement(int num) { + switch (num) { + case 1: + if (noteLevel == 0) announcement("This is your first step!", 1, num); + break; + case 10: + if (noteLevel == 1) announcement("Keep going, and don't give up", 1, num); + break; + case 100: + if (noteLevel == 2) announcement("This has been a long way...", 1, num); + break; + case 1000: + if (noteLevel == 3) announcement("Final achievement! Well Done!", 1, num); + break; + } + + } + + //字数成就 + public void wordNumberAchievement(int num) { + if (num > 20000 && wordLevel == 4) + announcement("Final Achievement! Congrats!", 2, 20000); + else if (num > 5000 && wordLevel == 3) + announcement("A long story...", 2, 5000); + else if (num > 1000 && wordLevel == 2) + announcement("Double essays!", 2, 1000); + else if (num > 500 && wordLevel == 1) + announcement("You have written an essay!", 2, 500); + else if (num > 100 && wordLevel == 0) + announcement("Take it slow to create more possibilities!", 2, 100); + + } + + //对话框 + public void announcement(String message, int mode, int num) { + new AlertDialog.Builder(MainActivity.this) + .setTitle(annoucementTitle(mode, num)) + .setMessage(message) + .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + } + }) + .create().show(); + setState(mode); + } + + //对话框标题 + public String annoucementTitle(int mode, int num) { + switch (mode) { + case 1: + return "You have written " + num + " notes! "; + case 2: + return "You have written " + num + " words! "; + case 3: + return "You have " + num + " notes remaining visible!"; + } + return null; + } + + public void setState(int mode) { + //set corresponding state to true in case repetition of annoucement + SharedPreferences.Editor editor = sharedPreferences.edit(); + switch (mode) { + case 1: + noteLevel++; + editor.putInt("noteLevel", noteLevel); + editor.commit(); + break; + case 2: + wordLevel++; + editor.putInt("wordLevel", wordLevel); + editor.commit(); + break; + } + } + + //监听 + public void listen() { + noteNumberAchievement(noteNumber); + wordNumberAchievement(wordNumber); + } + + //重置成就 + public void resetAll() { + //reset all prefs and state + noteNumber = 0; + wordNumber = 0; + SharedPreferences.Editor editor = sharedPreferences.edit(); + editor.putInt("noteNumber", noteNumber); + editor.putInt("wordNumber", wordNumber); + editor.putInt("noteLevel", 0); + editor.putInt("wordLevel", 0); + editor.commit(); + } + + } + +} diff --git a/app/src/main/java/cc/liuyx/note/UserSettingsActivity.java b/app/src/main/java/cc/liuyx/note/UserSettingsActivity.java new file mode 100644 index 0000000..907c6fc --- /dev/null +++ b/app/src/main/java/cc/liuyx/note/UserSettingsActivity.java @@ -0,0 +1,174 @@ +package cc.liuyx.note; + +import android.content.Intent; +import android.content.SharedPreferences; +import android.os.Bundle; +import android.preference.PreferenceManager; +import android.support.v7.widget.Toolbar; +import android.view.KeyEvent; +import android.view.View; +import android.widget.CompoundButton; +import android.widget.LinearLayout; +import android.widget.Switch; + +import com.example.atry.R; + +import java.util.Objects; + +public class UserSettingsActivity extends BaseActivity { + + private Switch nightMode; + private Switch reverseSort; + private LinearLayout fabColor; + private LinearLayout fabPlanColor; + private Switch noteTitle; + private SharedPreferences sharedPreferences; + + private static boolean night_change; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + setContentView(R.layout.preference_layout); + sharedPreferences = PreferenceManager.getDefaultSharedPreferences(getBaseContext()); + Intent intent = getIntent(); + if (intent.getExtras() != null) + night_change = intent.getBooleanExtra("night_change", false); + else night_change = false; + + initView(); + + Toolbar myToolbar = (Toolbar) findViewById(R.id.my_toolbar); + setSupportActionBar(myToolbar); + Objects.requireNonNull(getSupportActionBar()).setHomeButtonEnabled(true); + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + + if (isNightMode()) + myToolbar.setNavigationIcon(getDrawable(R.drawable.ic_settings_white_24dp)); + else myToolbar.setNavigationIcon(getDrawable(R.drawable.ic_settings_black_24dp)); + } + + @Override + protected void needRefresh() { + //因为自身的刷新与其他activity不同步,所以此处留白 + } + + private void initView() { + nightMode = findViewById(R.id.nightMode); + reverseSort = findViewById(R.id.reverseSort); + fabColor = findViewById(R.id.fabColor); + fabPlanColor = findViewById(R.id.fabPlanColor); + noteTitle = findViewById(R.id.noteTitle); + + + nightMode.setChecked(sharedPreferences.getBoolean("nightMode", false)); + reverseSort.setChecked(sharedPreferences.getBoolean("reverseSort", false)); + + nightMode.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { + setNightModePref(isChecked); + setSelfNightMode(); + SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(getBaseContext()); + boolean temp = false; + } + }); + + reverseSort.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { + SharedPreferences sharedPreferences1 = PreferenceManager.getDefaultSharedPreferences(getBaseContext()); + SharedPreferences.Editor editor = sharedPreferences1.edit(); + editor.putBoolean("reverseSort", isChecked); + editor.apply(); + } + }); + + + fabColor.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + Intent intent = new Intent(UserSettingsActivity.this, FabColorActivity.class); + intent.putExtra("mode", 1); // add note button + startActivityForResult(intent, 1); + overridePendingTransition(R.anim.in_righttoleft, R.anim.no); + } + }); + + fabPlanColor.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + Intent intent = new Intent(UserSettingsActivity.this, FabColorActivity.class); + intent.putExtra("mode", 2); // add plan button + startActivityForResult(intent, 1); + overridePendingTransition(R.anim.in_righttoleft, R.anim.no); + } + }); + + noteTitle.setChecked(sharedPreferences.getBoolean("noteTitle", true)); + noteTitle.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { + SharedPreferences sharedPreferences1 = PreferenceManager.getDefaultSharedPreferences(getBaseContext()); + SharedPreferences.Editor editor = sharedPreferences1.edit(); + editor.putBoolean("noteTitle", isChecked); + editor.apply(); + } + }); + + } + + + @Override + protected void onActivityResult(int requestCode, int resultCode, Intent data) { + assert data != null; + int opMode = data.getExtras().getInt("opMode", -1); + if (opMode == 1) { + int imgId = data.getExtras().getInt("id"); + SharedPreferences.Editor editor = sharedPreferences.edit(); // 开始编辑该文件 + editor.putInt("fabColor", imgId); + editor.apply(); + } else if (opMode == 2) { + int imgId = data.getExtras().getInt("id"); + SharedPreferences.Editor editor = sharedPreferences.edit(); // 开始编辑该文件 + editor.putInt("fabPlanColor", imgId); + editor.apply(); + } + } + + private void setSelfNightMode() { + //重新赋值并重启本activity + + super.setNightMode(); + Intent intent = new Intent(this, UserSettingsActivity.class); + intent.putExtra("night_change", !night_change); //重启一次,正负颠倒。最终为正值时重启MainActivity。 + + startActivity(new Intent(this, UserSettingsActivity.class)); + overridePendingTransition(R.anim.night_switch, R.anim.night_switch_over); + finish(); + } + + private void setNightModePref(boolean night) { + //通过nightMode switch修改pref中的nightMode + sharedPreferences = PreferenceManager.getDefaultSharedPreferences(getBaseContext()); + SharedPreferences.Editor editor = sharedPreferences.edit(); + editor.putBoolean("nightMode", night); + editor.apply(); + } + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + if (keyCode == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_DOWN) { + Intent intent = new Intent(); + intent.setAction("NIGHT_SWITCH"); + sendBroadcast(intent); + finish(); + overridePendingTransition(R.anim.in_lefttoright, R.anim.out_lefttoright); + return true; + } + return super.onKeyDown(keyCode, event); + } + + +} diff --git a/app/src/main/java/cc/liuyx/note/adapter/NoteAdapter.java b/app/src/main/java/cc/liuyx/note/adapter/NoteAdapter.java new file mode 100644 index 0000000..49aea68 --- /dev/null +++ b/app/src/main/java/cc/liuyx/note/adapter/NoteAdapter.java @@ -0,0 +1,114 @@ +package cc.liuyx.note.adapter; + +import android.content.Context; +import android.content.SharedPreferences; +import android.preference.PreferenceManager; +import android.text.TextUtils; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.Filter; +import android.widget.Filterable; +import android.widget.TextView; + +import com.example.atry.R; + +import java.util.ArrayList; +import java.util.List; + +import cc.liuyx.note.entity.Note; + +public class NoteAdapter extends BaseAdapter implements Filterable { + + private Context mContext; + + private List backList;//用来备份原始数据 + private List noteList;//这个数据是会改变的,所以要有个变量来备份一下原始数据 + private MyFilter mFilter; + + public NoteAdapter(Context mContext, List noteList) { + this.mContext = mContext; + this.noteList = noteList; + backList = noteList; + } + + @Override + public int getCount() { + return noteList.size(); + } + + @Override + public Object getItem(int position) { + return noteList.get(position); + } + + @Override + public long getItemId(int position) { + return position; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(mContext); + mContext.setTheme((sharedPreferences.getBoolean("nightMode", false)? R.style.NightTheme: R.style.DayTheme)); + View v = View.inflate(mContext, R.layout.note_layout, null); + TextView tv_content = (TextView)v.findViewById(R.id.tv_content); + TextView tv_time = (TextView)v.findViewById(R.id.tv_time); + + //Set text for TextView + String allText = noteList.get(position).getContent(); + if (sharedPreferences.getBoolean("noteTitle" ,true)) + tv_content.setText(allText.split("\n")[0]); + else tv_content.setText(allText); + tv_time.setText(noteList.get(position).getTime()); + + //Save note id to tag + v.setTag(noteList.get(position).getId()); + + return v; + } + + @Override + public Filter getFilter() { + if (mFilter ==null){ + mFilter = new MyFilter(); + } + return mFilter; + } + + + class MyFilter extends Filter { + //我们在performFiltering(CharSequence charSequence)这个方法中定义过滤规则 + @Override + protected FilterResults performFiltering(CharSequence charSequence) { + FilterResults result = new FilterResults(); + List list; + if (TextUtils.isEmpty(charSequence)) {//当过滤的关键字为空的时候,我们则显示所有的数据 + list = backList; + } else {//否则把符合条件的数据对象添加到集合中 + list = new ArrayList<>(); + for (Note note : backList) { + if (note.getContent().contains(charSequence)) { + list.add(note); + } + + } + } + result.values = list; //将得到的集合保存到FilterResults的value变量中 + result.count = list.size();//将集合的大小保存到FilterResults的count变量中 + + return result; + } + //在publishResults方法中告诉适配器更新界面 + @Override + protected void publishResults(CharSequence charSequence, FilterResults filterResults) { + noteList = (List)filterResults.values; + if (filterResults.count>0){ + notifyDataSetChanged();//通知数据发生了改变 + }else { + notifyDataSetInvalidated();//通知数据失效 + } + } + } + +} diff --git a/app/src/main/java/cc/liuyx/note/adapter/TagAdapter.java b/app/src/main/java/cc/liuyx/note/adapter/TagAdapter.java new file mode 100644 index 0000000..e811e14 --- /dev/null +++ b/app/src/main/java/cc/liuyx/note/adapter/TagAdapter.java @@ -0,0 +1,62 @@ +package cc.liuyx.note.adapter; + +import android.content.Context; +import android.content.SharedPreferences; +import android.preference.PreferenceManager; +import android.util.Log; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.ImageView; +import android.widget.TextView; + +import com.example.atry.R; + +import java.util.List; + +public class TagAdapter extends BaseAdapter { + + private Context context; + private List tagList; + private List numList; + + public TagAdapter(Context context, List tagList, List numList) { + this.context = context; + this.tagList = tagList; + this.numList = numList; + + } + + @Override + public int getCount() { + return tagList.size(); + } + + @Override + public Object getItem(int position) { + return tagList.get(position); + } + + @Override + public long getItemId(int position) { + return position; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + for(int i = 0; i < numList.size(); i++) Log.d("tag", numList.get(i).toString()); + Log.d("tag", "getView: " + numList.size()); + SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context); + context.setTheme((sharedPreferences.getBoolean("nightMode", false)? R.style.NightTheme: R.style.DayTheme)); + View v = View.inflate(context, R.layout.tag_layout, null); + TextView blank_tag = v.findViewById(R.id.blank_tag); + TextView text_tag = v.findViewById(R.id.text_tag); + ImageView delete_tag = v.findViewById(R.id.delete_tag); + + blank_tag.setText(numList.get(position).toString()); + text_tag.setText(tagList.get(position)); + + + return v; + } +} diff --git a/app/src/main/java/cc/liuyx/note/alarm/AlarmReceiver.java b/app/src/main/java/cc/liuyx/note/alarm/AlarmReceiver.java new file mode 100644 index 0000000..f928549 --- /dev/null +++ b/app/src/main/java/cc/liuyx/note/alarm/AlarmReceiver.java @@ -0,0 +1,47 @@ +package cc.liuyx.note.alarm; + +import android.app.Notification; +import android.app.NotificationChannel; +import android.app.NotificationManager; +import android.app.PendingIntent; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.os.Build; +import android.support.v4.app.NotificationCompat; + +import cc.liuyx.note.MainActivity; +import com.example.atry.R; + +public class AlarmReceiver extends BroadcastReceiver { + + private String channelId = "Piggy Notes"; + private String name = "ChannelName"; + @Override + public void onReceive(Context context, Intent intent) { + String title = intent.getExtras().getString("title"); + String content = intent.getExtras().getString("content"); + int id = intent.getExtras().getInt("id"); + Intent intent1 = new Intent(context, MainActivity.class); + + PendingIntent pendingIntent = PendingIntent.getActivity(context, id, intent1, PendingIntent.FLAG_ONE_SHOT | PendingIntent.FLAG_IMMUTABLE); + intent1.putExtra("mode", 1); + NotificationManager manager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + NotificationChannel mChannel = new NotificationChannel(channelId, name, NotificationManager.IMPORTANCE_DEFAULT); + mChannel.enableVibration(true); + manager.createNotificationChannel(mChannel); + } + + + NotificationCompat.Builder builder = new NotificationCompat.Builder(context, channelId) + .setContentTitle(title).setContentText(content).setSmallIcon(R.drawable.red_alarm_24dp) + .setContentIntent(pendingIntent).setAutoCancel(true).setFullScreenIntent(pendingIntent, true); + + Notification notification = builder.build(); + + + manager.notify(1, notification); + + } +} diff --git a/app/src/main/java/cc/liuyx/note/alarm/CRUD.java b/app/src/main/java/cc/liuyx/note/alarm/CRUD.java new file mode 100644 index 0000000..f48c18e --- /dev/null +++ b/app/src/main/java/cc/liuyx/note/alarm/CRUD.java @@ -0,0 +1,86 @@ +package cc.liuyx.note.alarm; + +import android.content.ContentValues; +import android.content.Context; +import android.database.Cursor; +import android.database.sqlite.SQLiteDatabase; +import android.database.sqlite.SQLiteOpenHelper; +import java.util.ArrayList; +import java.util.List; + +public class CRUD { + SQLiteOpenHelper dbHandler; + SQLiteDatabase db; + + private static final String[] columns = { + PlanDatabase.ID, + PlanDatabase.TITLE, + PlanDatabase.CONTENT, + PlanDatabase.TIME, + }; + + public CRUD(Context context){ + dbHandler = new PlanDatabase(context); + } + + public void open(){ + db = dbHandler.getWritableDatabase(); + } + + public void close(){ + dbHandler.close(); + } + + public Plan addPlan(Plan plan){ + //add a plan object to database + ContentValues contentValues = new ContentValues(); + contentValues.put(PlanDatabase.TITLE, plan.getTitle()); + contentValues.put(PlanDatabase.CONTENT, plan.getContent()); + contentValues.put(PlanDatabase.TIME, plan.getTime()); + long insertId = db.insert(PlanDatabase.TABLE_NAME, null, contentValues); + plan.setId(insertId); + return plan; + } + + public Plan getPlan(long id){ + //get a plan from database using cursor index + Cursor cursor = db.query(PlanDatabase.TABLE_NAME,columns,PlanDatabase.ID + "=?", + new String[]{String.valueOf(id)},null,null, null, null); + if (cursor != null) cursor.moveToFirst(); + Plan e = new Plan(cursor.getString(1),cursor.getString(2), cursor.getString(3)); + return e; + } + + public List getAllPlans(){ + Cursor cursor = db.query(PlanDatabase.TABLE_NAME,columns,null,null,null, null, null); + + List plans = new ArrayList<>(); + if(cursor.getCount() > 0){ + while(cursor.moveToNext()){ + Plan plan = new Plan(); + plan.setId(cursor.getLong(cursor.getColumnIndex(PlanDatabase.ID))); + plan.setTitle(cursor.getString(cursor.getColumnIndex(PlanDatabase.TITLE))); + plan.setContent(cursor.getString(cursor.getColumnIndex(PlanDatabase.CONTENT))); + plan.setTime(cursor.getString(cursor.getColumnIndex(PlanDatabase.TIME))); + plans.add(plan); + } + } + return plans; + } + + public int updatePlan(Plan plan) { + //update the info of an existing plan + ContentValues values = new ContentValues(); + values.put(PlanDatabase.TITLE, plan.getTitle()); + values.put(PlanDatabase.CONTENT, plan.getContent()); + values.put(PlanDatabase.TIME, plan.getTime()); + // updating row + return db.update(PlanDatabase.TABLE_NAME, values, + PlanDatabase.ID + "=?",new String[] { String.valueOf(plan.getId())}); + } + + public void removePlan(Plan plan) { + //remove a plan according to ID value + db.delete(PlanDatabase.TABLE_NAME, PlanDatabase.ID + "=" + plan.getId(), null); + } +} diff --git a/app/src/main/java/cc/liuyx/note/alarm/EditAlarmActivity.java b/app/src/main/java/cc/liuyx/note/alarm/EditAlarmActivity.java new file mode 100644 index 0000000..b754a1a --- /dev/null +++ b/app/src/main/java/cc/liuyx/note/alarm/EditAlarmActivity.java @@ -0,0 +1,329 @@ +package cc.liuyx.note.alarm; + +import android.app.DatePickerDialog; +import android.app.TimePickerDialog; +import android.content.DialogInterface; +import android.content.Intent; +import android.os.Bundle; +import android.support.annotation.Nullable; +import android.support.v7.app.AlertDialog; +import android.support.v7.widget.Toolbar; +import android.util.Log; +import android.view.KeyEvent; +import android.view.Menu; +import android.view.MenuItem; +import android.view.View; +import android.widget.Button; +import android.widget.DatePicker; +import android.widget.EditText; +import android.widget.TextView; +import android.widget.TimePicker; +import android.widget.Toast; + +import cc.liuyx.note.BaseActivity; + +import com.example.atry.R; + +import java.util.Calendar; + +public class EditAlarmActivity extends BaseActivity implements View.OnClickListener { + + private DatePickerDialog.OnDateSetListener dateSetListener; + private TimePickerDialog.OnTimeSetListener timeSetListener; + private EditText et_title; + private EditText et; + private Button set_date; + private Button set_time; + + + + private TextView date; + private TextView time; + private Plan plan; + private int[] dateArray = new int[3]; + private int[] timeArray = new int[2]; + + private int openMode = 0; + private String old_title = ""; + private String old_content = ""; + private String old_time = ""; + private long id = 0; + private boolean timeChange = false; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.edit_alarm_layout); + + Toolbar myToolbar = (Toolbar) findViewById(R.id.my_toolbar); + setSupportActionBar(myToolbar); + getSupportActionBar().setHomeButtonEnabled(true); + + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + + init(); + + final Intent intent = getIntent(); + openMode = intent.getExtras().getInt("mode", 0); + if(openMode == 1){ + id = intent.getLongExtra("id", 0); + old_title = intent.getStringExtra("title"); + old_content = intent.getStringExtra("content"); + old_time = intent.getStringExtra("time"); + et_title.setText(old_title); + et_title.setSelection(old_title.length()); + et.setText(old_content); + et.setSelection(old_content.length()); + + String[] wholeTime = old_time.split(" "); + String[] temp = wholeTime[0].split("-"); + String[] temp1 = wholeTime[1].split(":"); + setDateTV(Integer.parseInt(temp[0]), Integer.parseInt(temp[1]), Integer.parseInt(temp[2])); + setTimeTV(Integer.parseInt(temp1[0]), Integer.parseInt(temp1[1])); + } + + if(isNightMode()) myToolbar.setNavigationIcon(getDrawable(R.drawable.ic_keyboard_arrow_left_white_24dp)); + else myToolbar.setNavigationIcon(getDrawable(R.drawable.ic_keyboard_arrow_left_black_24dp)); + + myToolbar.setNavigationOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + if(!canBeSet()) { + Toast.makeText(EditAlarmActivity.this, "Invalid Time", Toast.LENGTH_SHORT).show(); + }else if(et.getText().toString().length() + et_title.getText().toString().length() == 0 && openMode == 2){ + Intent intent1 = new Intent(); + intent1.putExtra("mode", -1);//nothing new happens. + setResult(RESULT_OK, intent1); + finish();//返回 + overridePendingTransition(R.anim.in_lefttoright, R.anim.out_lefttoright); + } + else if (et_title.getText().toString().length() == 0) { + Toast.makeText(EditAlarmActivity.this, "Title cannot be empty", Toast.LENGTH_SHORT).show(); + } + else { + isTimeChange(); + Intent intent = new Intent(); + if (openMode == 2) { + intent.putExtra("mode", 10); // new one plan; + intent.putExtra("title", et_title.getText().toString()); + intent.putExtra("content", et.getText().toString()); + intent.putExtra("time", date.getText().toString() + " " + time.getText().toString()); + Log.d(TAG, date.getText().toString() + time.getText().toString()); + } else { + if (et.getText().toString().equals(old_content) && et_title.getText().toString().equals(old_title) && !timeChange) { + intent.putExtra("mode", -1); // edit nothing + } + else { + intent.putExtra("mode", 11); //edit the content + intent.putExtra("title", et_title.getText().toString()); + intent.putExtra("content", et.getText().toString()); + intent.putExtra("time", date.getText().toString() + " " + time.getText().toString()); + intent.putExtra("id", id); + } + } + setResult(RESULT_OK, intent); + finish();//返回 + overridePendingTransition(R.anim.in_lefttoright, R.anim.out_lefttoright); + } + } + }); + + } + + public boolean onKeyDown(int keyCode, KeyEvent event) { + + if( keyCode== KeyEvent.KEYCODE_HOME){ + return true; + } else if( keyCode== KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_DOWN){ + if(!canBeSet()) { + Toast.makeText(EditAlarmActivity.this, "Invalid Time", Toast.LENGTH_SHORT).show(); + }else if(et.getText().toString().length() + et_title.getText().toString().length() == 0 && openMode == 2){ + Intent intent1 = new Intent(); + intent1.putExtra("mode", -1);//nothing new happens. + setResult(RESULT_OK, intent1); + finish();//返回 + overridePendingTransition(R.anim.in_lefttoright, R.anim.out_lefttoright); + } + else if (et_title.getText().toString().length() == 0) { + Toast.makeText(EditAlarmActivity.this, "Title cannot be empty", Toast.LENGTH_SHORT).show(); + } + else { + isTimeChange(); + Intent intent = new Intent(); + if (openMode == 2) { + intent.putExtra("mode", 10); // new one plan; + intent.putExtra("title", et_title.getText().toString()); + intent.putExtra("content", et.getText().toString()); + intent.putExtra("time", date.getText().toString() + " " + time.getText().toString()); + Log.d(TAG, date.getText().toString() + time.getText().toString()); + } else { + if (et.getText().toString().equals(old_content) && et_title.getText().toString().equals(old_title) && !timeChange) { + intent.putExtra("mode", -1); // edit nothing + } + else { + intent.putExtra("mode", 11); //edit the content + intent.putExtra("title", et_title.getText().toString()); + intent.putExtra("content", et.getText().toString()); + intent.putExtra("time", date.getText().toString() + " " + time.getText().toString()); + intent.putExtra("id", id); + } + } + setResult(RESULT_OK, intent); + finish();//返回 + overridePendingTransition(R.anim.in_lefttoright, R.anim.out_lefttoright); + } + } + return super.onKeyDown(keyCode, event); + } + + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + getMenuInflater().inflate(R.menu.edit_menu, menu); + return super.onCreateOptionsMenu(menu); + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + final Intent intent = new Intent(); + switch (item.getItemId()){ + case R.id.delete: + new AlertDialog.Builder(EditAlarmActivity.this) + .setMessage("Delete this plan ?") + .setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + if(openMode == 2){ + intent.putExtra("mode", -1); // delete the plan + setResult(RESULT_OK, intent); + } + else { + intent.putExtra("mode", 12); // delete the plan + intent.putExtra("id", id); + setResult(RESULT_OK, intent); + } + finish(); + } + }).setNegativeButton(android.R.string.no, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + } + }).create().show(); + break; + } + return super.onOptionsItemSelected(item); + } + + @Override + protected void needRefresh() { + setNightMode(); + startActivity(new Intent(this, EditAlarmActivity.class)); + overridePendingTransition(R.anim.night_switch, R.anim.night_switch_over); + finish(); + } + + private void init(){ + + plan = new Plan(); + dateArray[0] = plan.getYear(); + dateArray[1] = plan.getMonth() + 1; + dateArray[2] = plan.getDay(); + timeArray[0] = plan.getHour(); + timeArray[1] = plan.getMinute(); + + et_title = findViewById(R.id.et_title); + et = findViewById(R.id.et); + set_date = findViewById(R.id.set_date); + set_time = findViewById(R.id.set_time); + date = findViewById(R.id.date); + time = findViewById(R.id.time); + + //initialize two textviews + setDateTV(dateArray[0], dateArray[1], dateArray[2]); + setTimeTV((timeArray[1]>54? timeArray[0]+1 : timeArray[0]), (timeArray[1]+5)%60); + Log.d(TAG, "init: "+dateArray[1]); + + set_date.setOnClickListener(this); + set_time.setOnClickListener(this); + + dateSetListener = new DatePickerDialog.OnDateSetListener() { + @Override + public void onDateSet(DatePicker view, int year, int month, int dayOfMonth) { + setDateTV(year, month+1, dayOfMonth); + + } + }; + timeSetListener = new TimePickerDialog.OnTimeSetListener() { + @Override + public void onTimeSet(TimePicker view, int hourOfDay, int minute) { + setTimeTV(hourOfDay, minute); + } + }; + } + + private void setDateTV(int y, int m, int d){ + //update tv and dateArray + String temp = y + "-"; + if(m<10) temp += "0"; + temp += (m + "-"); + if(d<10) temp +="0"; + temp += d; + date.setText(temp); + dateArray[0] = y; + dateArray[1] = m; + dateArray[2] = d; + } + + private void setTimeTV(int h, int m){ + //update tv and timeArra + String temp = ""; + if(h<10) temp += "0"; + temp += (h + ":"); + if(m<10) temp += "0"; + temp += m; + time.setText(temp); + timeArray[0] = h; + timeArray[1] = m; + } + + @Override + public void onClick(View v) { + switch (v.getId()){ + case R.id.set_date: //choose day + DatePickerDialog dialog = new DatePickerDialog(EditAlarmActivity.this, + (isNightMode()?R.style.NightDialogTheme :R.style.DayDialogTheme), dateSetListener, + dateArray[0], dateArray[1] - 1, dateArray[2]); + //dialog.getWindow().setBackgroundDrawable(new ColorDrawable((isNightMode()?Color.BLACK : Color.WHITE))); + dialog.show(); + break; + case R.id.set_time://choose hour and minute + TimePickerDialog dialog1 = new TimePickerDialog(EditAlarmActivity.this, + (isNightMode()?R.style.NightDialogTheme :R.style.DayDialogTheme), timeSetListener, + timeArray[0], timeArray[1], true); + //dialog1.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT)); + dialog1.show(); + break; + } + } + + private void isTimeChange(){ + String newTime = date.getText().toString() + " " + time.getText().toString(); + if(!newTime.equals(old_time)) timeChange = true; + } + + private boolean canBeSet(){ + Calendar calendar = Calendar.getInstance(); + calendar.set(dateArray[0], dateArray[1] - 1, dateArray[2], timeArray[0], timeArray[1]); + Calendar cur = Calendar.getInstance(); + Log.d(TAG, "canBeSet: " + cur.getTime().toString() + calendar.getTime().toString()); + if(cur.before(calendar)) return true; + else { + Toast.makeText(this, "Invalid Time", Toast.LENGTH_SHORT).show(); + return false; + } + } + + + +} diff --git a/app/src/main/java/cc/liuyx/note/alarm/Plan.java b/app/src/main/java/cc/liuyx/note/alarm/Plan.java new file mode 100644 index 0000000..35d1ab0 --- /dev/null +++ b/app/src/main/java/cc/liuyx/note/alarm/Plan.java @@ -0,0 +1,91 @@ +package cc.liuyx.note.alarm; + +import android.util.Log; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Date; + +public class Plan { + private long id; + private String title; + private String content; + private Calendar planTime; + + + public Plan(String title, String content, String planTime) { + this.title = title; + this.content = content; + setTime(planTime); + } + + public Plan(){ + this.planTime = Calendar.getInstance(); + } + + public int getYear(){ + return planTime.get(Calendar.YEAR); + } + + public int getMonth(){ + return planTime.get(Calendar.MONTH); + } + + public int getDay() { + return planTime.get(Calendar.DAY_OF_MONTH); + } + + public int getHour() { + return planTime.get(Calendar.HOUR_OF_DAY); + } + + public int getMinute() { + return planTime.get(Calendar.MINUTE); + } + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + + 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 Calendar getPlanTime() { + return planTime; + } + + public String getTime(){ + SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm"); + return simpleDateFormat.format(planTime.getTime()); + } + public void setTime(String format){ + SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm"); + try { + Date temp = simpleDateFormat.parse(format); + Log.d("shit", ""+temp); + planTime = Calendar.getInstance(); + planTime.setTime(temp); + } catch (ParseException e) { + + } + } + +} diff --git a/app/src/main/java/cc/liuyx/note/alarm/PlanAdapter.java b/app/src/main/java/cc/liuyx/note/alarm/PlanAdapter.java new file mode 100644 index 0000000..a486097 --- /dev/null +++ b/app/src/main/java/cc/liuyx/note/alarm/PlanAdapter.java @@ -0,0 +1,109 @@ +package cc.liuyx.note.alarm; + +import android.content.Context; +import android.content.SharedPreferences; +import android.preference.PreferenceManager; +import android.text.TextUtils; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.Filter; +import android.widget.Filterable; +import android.widget.TextView; + +import com.example.atry.R; + +import java.util.ArrayList; +import java.util.List; + +public class PlanAdapter extends BaseAdapter implements Filterable { + private Context mContext; + + private List backList;//用来备份原始数据 + private List planList;//这个数据是会改变的,所以要有个变量来备份一下原始数据 + PlanAdapter.MyFilter mFilter; + + public PlanAdapter(Context mContext, List planList) { + this.mContext = mContext; + this.planList = planList; + backList = planList; + } + + @Override + public int getCount() { + return planList.size(); + } + + @Override + public Object getItem(int position) { + return planList.get(position); + } + + @Override + public long getItemId(int position) { + return position; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(mContext); + mContext.setTheme((sharedPreferences.getBoolean("nightMode", false)? R.style.NightTheme: R.style.DayTheme)); + View v = View.inflate(mContext, R.layout.plan_layout, null); + TextView tv_title = (TextView)v.findViewById(R.id.tv_title); + TextView tv_content = (TextView)v.findViewById(R.id.tv_content); + TextView tv_time = (TextView)v.findViewById(R.id.tv_time); + + //Set text for TextView + tv_title.setText(planList.get(position).getTitle()); + tv_content.setText(planList.get(position).getContent()); + tv_time.setText(planList.get(position).getTime()); + + //Save plan id to tag + v.setTag(planList.get(position).getId()); + + return v; + } + + @Override + public Filter getFilter() { + if (mFilter ==null){ + mFilter = new PlanAdapter.MyFilter(); + } + return mFilter; + } + + + class MyFilter extends Filter { + //我们在performFiltering(CharSequence charSequence)这个方法中定义过滤规则 + @Override + protected FilterResults performFiltering(CharSequence charSequence) { + FilterResults result = new FilterResults(); + List list; + if (TextUtils.isEmpty(charSequence)) {//当过滤的关键字为空的时候,我们则显示所有的数据 + list = backList; + } else {//否则把符合条件的数据对象添加到集合中 + list = new ArrayList<>(); + for (Plan plan : backList) { + if (plan.getTitle().contains(charSequence) || plan.getContent().contains(charSequence)) { + list.add(plan); + } + + } + } + result.values = list; //将得到的集合保存到FilterResults的value变量中 + result.count = list.size();//将集合的大小保存到FilterResults的count变量中 + + return result; + } + //在publishResults方法中告诉适配器更新界面 + @Override + protected void publishResults(CharSequence charSequence, FilterResults filterResults) { + planList = (List)filterResults.values; + if (filterResults.count>0){ + notifyDataSetChanged();//通知数据发生了改变 + }else { + notifyDataSetInvalidated();//通知数据失效 + } + } + } +} diff --git a/app/src/main/java/cc/liuyx/note/alarm/PlanDatabase.java b/app/src/main/java/cc/liuyx/note/alarm/PlanDatabase.java new file mode 100644 index 0000000..1faf3db --- /dev/null +++ b/app/src/main/java/cc/liuyx/note/alarm/PlanDatabase.java @@ -0,0 +1,37 @@ +package cc.liuyx.note.alarm; + +import android.content.Context; +import android.database.sqlite.SQLiteDatabase; +import android.database.sqlite.SQLiteOpenHelper; + +public class PlanDatabase extends SQLiteOpenHelper { + + public static final String TABLE_NAME = "plans"; + public static final String TITLE = "title"; + public static final String CONTENT = "content"; + public static final String ID = "_id"; + public static final String TIME = "time"; + public static final String MODE = "mode"; + + + public PlanDatabase(Context context){ + super(context, "plans", null, 1); + } + + @Override + public void onCreate(SQLiteDatabase db) { + db.execSQL("CREATE TABLE "+ TABLE_NAME + + "(" + + ID + " INTEGER PRIMARY KEY AUTOINCREMENT," + + TITLE + " TEXT NOT NULL," + + CONTENT + " TEXT," + + TIME + " TEXT NOT NULL)" + ); + } + + @Override + public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { + + } + +} diff --git a/app/src/main/java/cc/liuyx/note/db/CRUD.java b/app/src/main/java/cc/liuyx/note/db/CRUD.java new file mode 100644 index 0000000..efe7ff5 --- /dev/null +++ b/app/src/main/java/cc/liuyx/note/db/CRUD.java @@ -0,0 +1,91 @@ +package cc.liuyx.note.db; + +import android.annotation.SuppressLint; +import android.content.ContentValues; +import android.content.Context; +import android.database.Cursor; +import android.database.sqlite.SQLiteDatabase; +import android.database.sqlite.SQLiteOpenHelper; + +import java.util.ArrayList; +import java.util.List; + +import cc.liuyx.note.entity.Note; + +public class CRUD { + SQLiteOpenHelper dbHandler; + SQLiteDatabase db; + + private static final String[] columns = { + NoteDatabase.ID, + NoteDatabase.CONTENT, + NoteDatabase.TIME, + NoteDatabase.MODE + }; + + public CRUD(Context context){ + dbHandler = new NoteDatabase(context); + } + + public void open(){ + db = dbHandler.getWritableDatabase(); + } + + public void close(){ + dbHandler.close(); + } + + public void addNote(Note note){ + //add a note object to database + ContentValues contentValues = new ContentValues(); + contentValues.put(NoteDatabase.CONTENT, note.getContent()); + contentValues.put(NoteDatabase.TIME, note.getTime()); + contentValues.put(NoteDatabase.MODE, note.getTag()); + long insertId = db.insert(NoteDatabase.TABLE_NAME, null, contentValues); + note.setId(insertId); + } + + public Note getNote(long id){ + //get a note from database using cursor index + Cursor cursor = db.query(NoteDatabase.TABLE_NAME,columns,NoteDatabase.ID + "=?", + new String[]{String.valueOf(id)},null,null, null, null); + if (cursor != null) cursor.moveToFirst(); + assert cursor != null; + return new Note(cursor.getString(1),cursor.getString(2), cursor.getInt(3)); + } + + @SuppressLint("Range") + public List getAllNotes(){ + Cursor cursor = db.query(NoteDatabase.TABLE_NAME,columns,null,null,null, null, null); + + List notes = new ArrayList<>(); + if(cursor.getCount() > 0){ + while(cursor.moveToNext()){ + Note note = new Note(); + note.setId(cursor.getLong(cursor.getColumnIndex(NoteDatabase.ID))); + note.setContent(cursor.getString(cursor.getColumnIndex(NoteDatabase.CONTENT))); + note.setTime(cursor.getString(cursor.getColumnIndex(NoteDatabase.TIME))); + note.setTag(cursor.getInt(cursor.getColumnIndex(NoteDatabase.MODE))); + notes.add(note); + } + } + return notes; + } + + public void updateNote(Note note) { + //update the info of an existing note + ContentValues values = new ContentValues(); + values.put(NoteDatabase.CONTENT, note.getContent()); + values.put(NoteDatabase.TIME, note.getTime()); + values.put(NoteDatabase.MODE, note.getTag()); + // updating row + db.update(NoteDatabase.TABLE_NAME, values, + NoteDatabase.ID + "=?", new String[]{String.valueOf(note.getId())}); + } + + public void removeNote(Note note) { + //remove a note according to ID value + db.delete(NoteDatabase.TABLE_NAME, NoteDatabase.ID + "=" + note.getId(), null); + } + +} diff --git a/app/src/main/java/cc/liuyx/note/db/NoteDatabase.java b/app/src/main/java/cc/liuyx/note/db/NoteDatabase.java new file mode 100644 index 0000000..bdedc82 --- /dev/null +++ b/app/src/main/java/cc/liuyx/note/db/NoteDatabase.java @@ -0,0 +1,54 @@ +package cc.liuyx.note.db; + +import android.annotation.SuppressLint; +import android.content.ContentValues; +import android.content.Context; +import android.database.Cursor; +import android.database.sqlite.SQLiteDatabase; +import android.database.sqlite.SQLiteOpenHelper; +import android.util.Log; + +public class NoteDatabase extends SQLiteOpenHelper { + + public static final String TABLE_NAME = "notes"; + public static final String CONTENT = "content"; + public static final String ID = "_id"; + public static final String TIME = "time"; + public static final String MODE = "mode"; + + public NoteDatabase(Context context) { + super(context, "notes", null, 1); + } + + @Override + public void onCreate(SQLiteDatabase db) { + db.execSQL("CREATE TABLE " + TABLE_NAME + + "(" + + ID + " INTEGER PRIMARY KEY AUTOINCREMENT," + + CONTENT + " TEXT NOT NULL," + + TIME + " TEXT NOT NULL," + + MODE + " INTEGER DEFAULT 1)" + ); + } + + @Override + public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { + } + + private void updateMode(SQLiteDatabase db) { + //version 1 -> 2, 增加 mode -- notes的分类,默认为1 + db.execSQL("alter table " + TABLE_NAME + " add column " + MODE); + Cursor cursor = db.rawQuery("select * from " + TABLE_NAME, null); + while (cursor.moveToNext()) { + @SuppressLint("Range") String content = cursor.getString(cursor.getColumnIndex(CONTENT)); + @SuppressLint("Range") String time = cursor.getString(cursor.getColumnIndex(TIME)); + @SuppressLint("Range") int mode = cursor.getInt(cursor.getColumnIndex(MODE)); + ContentValues values = new ContentValues(); + values.put(CONTENT, content); + values.put(TIME, time); + values.put(MODE, 1); + db.update(TABLE_NAME, values, CONTENT + "=?", new String[]{content}); + } + Log.d("Base", "update db 1 - 2"); + } +} diff --git a/app/src/main/java/cc/liuyx/note/entity/Note.java b/app/src/main/java/cc/liuyx/note/entity/Note.java new file mode 100644 index 0000000..29c85e7 --- /dev/null +++ b/app/src/main/java/cc/liuyx/note/entity/Note.java @@ -0,0 +1,55 @@ +package cc.liuyx.note.entity; + +public class Note { + + private long id; + private String content; + private String time; + private int tag; + + public Note() { + } + + public Note(String content, String time, int tag) { + this.content = content; + this.time = time; + this.tag = tag; + } + + public long getId() { + return id; + } + + public String getContent() { + return content; + } + + public String getTime() { + return time; + } + + public void setId(long id) { + this.id = id; + } + + public void setContent(String content) { + this.content = content; + } + + public void setTime(String time) { + this.time = time; + } + + @Override + public String toString() { + return content + "\n" + time.substring(5,16) + " "+ id; + } + + public int getTag() { + return tag; + } + + public void setTag(int tag) { + this.tag = tag; + } +} diff --git a/app/src/main/java/cc/liuyx/note/entity/SpinnerItem.java b/app/src/main/java/cc/liuyx/note/entity/SpinnerItem.java new file mode 100644 index 0000000..f552881 --- /dev/null +++ b/app/src/main/java/cc/liuyx/note/entity/SpinnerItem.java @@ -0,0 +1,28 @@ +package cc.liuyx.note.entity; + +public class SpinnerItem { + + private String tagName; + private int tagId; + + public SpinnerItem(String tagName, int tagId) { + this.tagName = tagName; + this.tagId = tagId; + } + + public String getTagName() { + return tagName; + } + + public void setTagName(String tagName) { + this.tagName = tagName; + } + + public int getTagId() { + return tagId; + } + + public void setTagId(int tagId) { + this.tagId = tagId; + } +} diff --git a/app/src/main/piggy_launcher-web.png b/app/src/main/piggy_launcher-web.png new file mode 100644 index 0000000..b951fe9 Binary files /dev/null and b/app/src/main/piggy_launcher-web.png differ diff --git a/app/src/main/res/anim/in_lefttoright.xml b/app/src/main/res/anim/in_lefttoright.xml new file mode 100644 index 0000000..1034fe9 --- /dev/null +++ b/app/src/main/res/anim/in_lefttoright.xml @@ -0,0 +1,8 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/anim/in_righttoleft.xml b/app/src/main/res/anim/in_righttoleft.xml new file mode 100644 index 0000000..d09ce5e --- /dev/null +++ b/app/src/main/res/anim/in_righttoleft.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/anim/in_slow.xml b/app/src/main/res/anim/in_slow.xml new file mode 100644 index 0000000..4f91e23 --- /dev/null +++ b/app/src/main/res/anim/in_slow.xml @@ -0,0 +1,8 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/anim/night_switch.xml b/app/src/main/res/anim/night_switch.xml new file mode 100644 index 0000000..f864170 --- /dev/null +++ b/app/src/main/res/anim/night_switch.xml @@ -0,0 +1,7 @@ + + + diff --git a/app/src/main/res/anim/night_switch_over.xml b/app/src/main/res/anim/night_switch_over.xml new file mode 100644 index 0000000..362a744 --- /dev/null +++ b/app/src/main/res/anim/night_switch_over.xml @@ -0,0 +1,7 @@ + + + diff --git a/app/src/main/res/anim/no.xml b/app/src/main/res/anim/no.xml new file mode 100644 index 0000000..751d2da --- /dev/null +++ b/app/src/main/res/anim/no.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/anim/out_lefttoright.xml b/app/src/main/res/anim/out_lefttoright.xml new file mode 100644 index 0000000..36b01e7 --- /dev/null +++ b/app/src/main/res/anim/out_lefttoright.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/anim/out_righttoleft.xml b/app/src/main/res/anim/out_righttoleft.xml new file mode 100644 index 0000000..6f25a62 --- /dev/null +++ b/app/src/main/res/anim/out_righttoleft.xml @@ -0,0 +1,8 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/anim/out_slow.xml b/app/src/main/res/anim/out_slow.xml new file mode 100644 index 0000000..38ebe73 --- /dev/null +++ b/app/src/main/res/anim/out_slow.xml @@ -0,0 +1,8 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable-v24/ic_launcher_foreground.xml b/app/src/main/res/drawable-v24/ic_launcher_foreground.xml new file mode 100644 index 0000000..1f6bb29 --- /dev/null +++ b/app/src/main/res/drawable-v24/ic_launcher_foreground.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + diff --git a/app/src/main/res/drawable/ic_add_black_24dp.xml b/app/src/main/res/drawable/ic_add_black_24dp.xml new file mode 100644 index 0000000..0258249 --- /dev/null +++ b/app/src/main/res/drawable/ic_add_black_24dp.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_add_white_24dp.xml b/app/src/main/res/drawable/ic_add_white_24dp.xml new file mode 100644 index 0000000..e3979cd --- /dev/null +++ b/app/src/main/res/drawable/ic_add_white_24dp.xml @@ -0,0 +1,5 @@ + + + diff --git a/app/src/main/res/drawable/ic_arrow_drop_down_black_24dp.xml b/app/src/main/res/drawable/ic_arrow_drop_down_black_24dp.xml new file mode 100644 index 0000000..1245453 --- /dev/null +++ b/app/src/main/res/drawable/ic_arrow_drop_down_black_24dp.xml @@ -0,0 +1,5 @@ + + + diff --git a/app/src/main/res/drawable/ic_arrow_drop_down_white_24dp.xml b/app/src/main/res/drawable/ic_arrow_drop_down_white_24dp.xml new file mode 100644 index 0000000..a723531 --- /dev/null +++ b/app/src/main/res/drawable/ic_arrow_drop_down_white_24dp.xml @@ -0,0 +1,5 @@ + + + diff --git a/app/src/main/res/drawable/ic_autorenew_black_24dp.xml b/app/src/main/res/drawable/ic_autorenew_black_24dp.xml new file mode 100644 index 0000000..794ca6a --- /dev/null +++ b/app/src/main/res/drawable/ic_autorenew_black_24dp.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_autorenew_white_24dp.xml b/app/src/main/res/drawable/ic_autorenew_white_24dp.xml new file mode 100644 index 0000000..7c05474 --- /dev/null +++ b/app/src/main/res/drawable/ic_autorenew_white_24dp.xml @@ -0,0 +1,5 @@ + + + diff --git a/app/src/main/res/drawable/ic_delete_black_24dp.xml b/app/src/main/res/drawable/ic_delete_black_24dp.xml new file mode 100644 index 0000000..39e64d6 --- /dev/null +++ b/app/src/main/res/drawable/ic_delete_black_24dp.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_delete_forever_black_24dp.xml b/app/src/main/res/drawable/ic_delete_forever_black_24dp.xml new file mode 100644 index 0000000..2f5557a --- /dev/null +++ b/app/src/main/res/drawable/ic_delete_forever_black_24dp.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_delete_forever_white_24dp.xml b/app/src/main/res/drawable/ic_delete_forever_white_24dp.xml new file mode 100644 index 0000000..0d6fef8 --- /dev/null +++ b/app/src/main/res/drawable/ic_delete_forever_white_24dp.xml @@ -0,0 +1,5 @@ + + + diff --git a/app/src/main/res/drawable/ic_delete_white_24dp.xml b/app/src/main/res/drawable/ic_delete_white_24dp.xml new file mode 100644 index 0000000..8bed121 --- /dev/null +++ b/app/src/main/res/drawable/ic_delete_white_24dp.xml @@ -0,0 +1,5 @@ + + + diff --git a/app/src/main/res/drawable/ic_error_outline_black_24dp.xml b/app/src/main/res/drawable/ic_error_outline_black_24dp.xml new file mode 100644 index 0000000..8b12328 --- /dev/null +++ b/app/src/main/res/drawable/ic_error_outline_black_24dp.xml @@ -0,0 +1,5 @@ + + + diff --git a/app/src/main/res/drawable/ic_flag_black_24dp.xml b/app/src/main/res/drawable/ic_flag_black_24dp.xml new file mode 100644 index 0000000..82ef104 --- /dev/null +++ b/app/src/main/res/drawable/ic_flag_black_24dp.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_flag_white_24dp.xml b/app/src/main/res/drawable/ic_flag_white_24dp.xml new file mode 100644 index 0000000..f2e075a --- /dev/null +++ b/app/src/main/res/drawable/ic_flag_white_24dp.xml @@ -0,0 +1,5 @@ + + + diff --git a/app/src/main/res/drawable/ic_keyboard_arrow_left_black_24dp.xml b/app/src/main/res/drawable/ic_keyboard_arrow_left_black_24dp.xml new file mode 100644 index 0000000..c9f7747 --- /dev/null +++ b/app/src/main/res/drawable/ic_keyboard_arrow_left_black_24dp.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_keyboard_arrow_left_white_24dp.xml b/app/src/main/res/drawable/ic_keyboard_arrow_left_white_24dp.xml new file mode 100644 index 0000000..b79d00f --- /dev/null +++ b/app/src/main/res/drawable/ic_keyboard_arrow_left_white_24dp.xml @@ -0,0 +1,5 @@ + + + diff --git a/app/src/main/res/drawable/ic_launcher_background.xml b/app/src/main/res/drawable/ic_launcher_background.xml new file mode 100644 index 0000000..0d025f9 --- /dev/null +++ b/app/src/main/res/drawable/ic_launcher_background.xml @@ -0,0 +1,170 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/drawable/ic_menu_black_24dp.xml b/app/src/main/res/drawable/ic_menu_black_24dp.xml new file mode 100644 index 0000000..6d9343b --- /dev/null +++ b/app/src/main/res/drawable/ic_menu_black_24dp.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_menu_white_24dp.xml b/app/src/main/res/drawable/ic_menu_white_24dp.xml new file mode 100644 index 0000000..5f9eac7 --- /dev/null +++ b/app/src/main/res/drawable/ic_menu_white_24dp.xml @@ -0,0 +1,10 @@ + + + + diff --git a/app/src/main/res/drawable/ic_remove_black_24dp.xml b/app/src/main/res/drawable/ic_remove_black_24dp.xml new file mode 100644 index 0000000..a541177 --- /dev/null +++ b/app/src/main/res/drawable/ic_remove_black_24dp.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_remove_white_24dp.xml b/app/src/main/res/drawable/ic_remove_white_24dp.xml new file mode 100644 index 0000000..f6e9e94 --- /dev/null +++ b/app/src/main/res/drawable/ic_remove_white_24dp.xml @@ -0,0 +1,5 @@ + + + diff --git a/app/src/main/res/drawable/ic_search_black_24dp.xml b/app/src/main/res/drawable/ic_search_black_24dp.xml new file mode 100644 index 0000000..affc7ba --- /dev/null +++ b/app/src/main/res/drawable/ic_search_black_24dp.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_search_white_24dp.xml b/app/src/main/res/drawable/ic_search_white_24dp.xml new file mode 100644 index 0000000..be5ad99 --- /dev/null +++ b/app/src/main/res/drawable/ic_search_white_24dp.xml @@ -0,0 +1,5 @@ + + + diff --git a/app/src/main/res/drawable/ic_settings_black_24dp.xml b/app/src/main/res/drawable/ic_settings_black_24dp.xml new file mode 100644 index 0000000..24a5623 --- /dev/null +++ b/app/src/main/res/drawable/ic_settings_black_24dp.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_settings_white_24dp.xml b/app/src/main/res/drawable/ic_settings_white_24dp.xml new file mode 100644 index 0000000..1397d37 --- /dev/null +++ b/app/src/main/res/drawable/ic_settings_white_24dp.xml @@ -0,0 +1,5 @@ + + + diff --git a/app/src/main/res/drawable/note_shape.xml b/app/src/main/res/drawable/note_shape.xml new file mode 100644 index 0000000..751c8be --- /dev/null +++ b/app/src/main/res/drawable/note_shape.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/piggy.jpg b/app/src/main/res/drawable/piggy.jpg new file mode 100644 index 0000000..5f577ef Binary files /dev/null and b/app/src/main/res/drawable/piggy.jpg differ diff --git a/app/src/main/res/drawable/red_alarm_24dp.xml b/app/src/main/res/drawable/red_alarm_24dp.xml new file mode 100644 index 0000000..03a888c --- /dev/null +++ b/app/src/main/res/drawable/red_alarm_24dp.xml @@ -0,0 +1,5 @@ + + + diff --git a/app/src/main/res/drawable/spinner_bg.xml b/app/src/main/res/drawable/spinner_bg.xml new file mode 100644 index 0000000..43fa587 --- /dev/null +++ b/app/src/main/res/drawable/spinner_bg.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml new file mode 100644 index 0000000..1952997 --- /dev/null +++ b/app/src/main/res/layout/activity_main.xml @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/edit_alarm_layout.xml b/app/src/main/res/layout/edit_alarm_layout.xml new file mode 100644 index 0000000..a730357 --- /dev/null +++ b/app/src/main/res/layout/edit_alarm_layout.xml @@ -0,0 +1,97 @@ + + + + + + + + + + +