|
|
|
@ -16,6 +16,7 @@
|
|
|
|
|
|
|
|
|
|
package net.micode.notes.ui;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import android.app.Activity;
|
|
|
|
|
import android.app.AlarmManager;
|
|
|
|
|
import android.app.AlertDialog;
|
|
|
|
@ -102,9 +103,40 @@ import retrofit2.Retrofit;
|
|
|
|
|
import retrofit2.converter.gson.GsonConverterFactory;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
*
|
|
|
|
|
* @ProjectName:
|
|
|
|
|
* @Package: net.micode.notes.ui
|
|
|
|
|
* @ClassName: NoteEditActivity
|
|
|
|
|
* @Description: 编辑小米便签应用中的便签内容。它向用户提供了一个界面,允许用户输入、编辑和保存文本信息。
|
|
|
|
|
* 具体来说,用户可以在该界面中添加或编辑标题、标签、内容、图片等信息,并将这些信息保存到小米便签数据库中。
|
|
|
|
|
* 还提供了一些常用的编辑功能,如加粗、倾斜、下划线、字体调整、颜色设置、插入图片等,使得用户可以更加方便地对便签内容进行编辑和美化。
|
|
|
|
|
* @Author: xumingyang
|
|
|
|
|
* @CreateDate: 2024-01-03 8:44
|
|
|
|
|
* @UpdateUser: 更新者:
|
|
|
|
|
* @UpdateDate: 2024-01-03 8:44
|
|
|
|
|
* @UpdateRemark: 更新说明:
|
|
|
|
|
* @Version: 1.0
|
|
|
|
|
*/
|
|
|
|
|
import android.speech.tts.TextToSpeech.OnInitListener;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
*
|
|
|
|
|
* @ProjectName:
|
|
|
|
|
* @Package: net.micode.notes.ui
|
|
|
|
|
* @ClassName: NoteEditActivity
|
|
|
|
|
* @Description: 编辑小米便签应用中的便签内容。它向用户提供了一个界面,允许用户输入、编辑和保存文本信息。
|
|
|
|
|
* 具体来说,用户可以在该界面中添加或编辑标题、标签、内容、图片等信息,并将这些信息保存到小米便签数据库中。
|
|
|
|
|
* 还提供了一些常用的编辑功能,如加粗、倾斜、下划线、字体调整、颜色设置、插入图片等,使得用户可以更加方便地对便签内容进行编辑和美化。
|
|
|
|
|
* @Author: xumingyang
|
|
|
|
|
* @CreateDate: 2024-01-03 8:44
|
|
|
|
|
* @UpdateDate: 2024-01-03 8:44
|
|
|
|
|
* @Version: 1.0
|
|
|
|
|
*/
|
|
|
|
|
public class NoteEditActivity extends Activity implements OnClickListener,
|
|
|
|
|
NoteSettingChangedListener, OnTextViewChangeListener {
|
|
|
|
|
//该类主要是针对标签的编辑
|
|
|
|
|
//继承了系统内部许多和监听有关的类
|
|
|
|
|
public static void setmChanged(Stack mChanged) {
|
|
|
|
|
NoteEditActivity.mChanged = mChanged;
|
|
|
|
|
}
|
|
|
|
@ -112,6 +144,8 @@ public class NoteEditActivity extends Activity implements OnClickListener,
|
|
|
|
|
private class HeadViewHolder {
|
|
|
|
|
public TextView tvModified;
|
|
|
|
|
|
|
|
|
|
public EditText editText1;//新增
|
|
|
|
|
public TextView textView;//新增
|
|
|
|
|
public ImageView ivAlertIcon;
|
|
|
|
|
|
|
|
|
|
public TextView tvAlertDate;
|
|
|
|
@ -119,6 +153,7 @@ public class NoteEditActivity extends Activity implements OnClickListener,
|
|
|
|
|
public ImageView ibSetBgColor;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//使用Map实现数据存储
|
|
|
|
|
private static final Map<Integer, Integer> sBgSelectorBtnsMap = new HashMap<Integer, Integer>();
|
|
|
|
|
static {
|
|
|
|
|
sBgSelectorBtnsMap.put(R.id.iv_bg_yellow, ResourceParser.YELLOW);
|
|
|
|
@ -126,6 +161,7 @@ public class NoteEditActivity extends Activity implements OnClickListener,
|
|
|
|
|
sBgSelectorBtnsMap.put(R.id.iv_bg_blue, ResourceParser.BLUE);
|
|
|
|
|
sBgSelectorBtnsMap.put(R.id.iv_bg_green, ResourceParser.GREEN);
|
|
|
|
|
sBgSelectorBtnsMap.put(R.id.iv_bg_white, ResourceParser.WHITE);
|
|
|
|
|
//put函数是将指定值和指定键相连
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static final Map<Integer, Integer> sBgSelectorSelectionMap = new HashMap<Integer, Integer>();
|
|
|
|
@ -135,6 +171,7 @@ public class NoteEditActivity extends Activity implements OnClickListener,
|
|
|
|
|
sBgSelectorSelectionMap.put(ResourceParser.BLUE, R.id.iv_bg_blue_select);
|
|
|
|
|
sBgSelectorSelectionMap.put(ResourceParser.GREEN, R.id.iv_bg_green_select);
|
|
|
|
|
sBgSelectorSelectionMap.put(ResourceParser.WHITE, R.id.iv_bg_white_select);
|
|
|
|
|
//put函数是将指定值和指定键相连
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static final Map<Integer, Integer> sFontSizeBtnsMap = new HashMap<Integer, Integer>();
|
|
|
|
@ -157,22 +194,24 @@ public class NoteEditActivity extends Activity implements OnClickListener,
|
|
|
|
|
|
|
|
|
|
private HeadViewHolder mNoteHeaderHolder;
|
|
|
|
|
|
|
|
|
|
private View mHeadViewPanel;
|
|
|
|
|
private View mHeadViewPanel;//私有化一个界面操作mHeadViewPanel,对表头的操作
|
|
|
|
|
|
|
|
|
|
private View mNoteBgColorSelector;
|
|
|
|
|
private View mNoteBgColorSelector;//私有化一个界面操作mNoteBgColorSelector,对背景颜色的操作
|
|
|
|
|
|
|
|
|
|
private View mFontSizeSelector;
|
|
|
|
|
private View mFontSizeSelector;//私有化一个界面操作mFontSizeSelector,对标签字体的操作
|
|
|
|
|
|
|
|
|
|
private EditText mNoteEditor;
|
|
|
|
|
private EditText mNoteEditor;//声明编辑控件,对文本操作
|
|
|
|
|
|
|
|
|
|
private EditText editText;
|
|
|
|
|
private TextView textView;
|
|
|
|
|
private View mNoteEditorPanel;
|
|
|
|
|
private View mNoteEditorPanel;//私有化一个界面操作mNoteEditorPanel,文本编辑的控制板
|
|
|
|
|
|
|
|
|
|
private WorkingNote mWorkingNote;
|
|
|
|
|
private WorkingNote mWorkingNote;//对模板WorkingNote的初始化
|
|
|
|
|
|
|
|
|
|
private SharedPreferences mSharedPrefs;
|
|
|
|
|
private int mFontSizeId;
|
|
|
|
|
//私有化SharedPreferences的数据存储方式
|
|
|
|
|
//它的本质是基于XML文件存储key-value键值对数据
|
|
|
|
|
private int mFontSizeId;//用于操作字体的大小
|
|
|
|
|
|
|
|
|
|
private static final String PREFERENCE_FONT_SIZE = "pref_font_size";
|
|
|
|
|
|
|
|
|
@ -181,7 +220,7 @@ public class NoteEditActivity extends Activity implements OnClickListener,
|
|
|
|
|
public static final String TAG_CHECKED = String.valueOf('\u221A');
|
|
|
|
|
public static final String TAG_UNCHECKED = String.valueOf('\u25A1');
|
|
|
|
|
|
|
|
|
|
private LinearLayout mEditTextList;
|
|
|
|
|
private LinearLayout mEditTextList;//线性布局
|
|
|
|
|
|
|
|
|
|
private String mUserQuery;
|
|
|
|
|
private Pattern mPattern;
|
|
|
|
@ -359,9 +398,11 @@ public class NoteEditActivity extends Activity implements OnClickListener,
|
|
|
|
|
Editable editable = noteEditText.getText();
|
|
|
|
|
String noteText = editable.toString();
|
|
|
|
|
int length = editable.length();
|
|
|
|
|
//对于每个字符,从当前位置开始,向后遍历文本,直到找到与图片标记匹配的子字符串。
|
|
|
|
|
for (int i = 0; i < length; i++) {
|
|
|
|
|
for (int j = i; j < length; j++) {
|
|
|
|
|
String img_fragment = noteText.substring(i, j + 1);
|
|
|
|
|
//检查其长度是否大于15,且以"[local]"开头,以"[/local]"结尾
|
|
|
|
|
if (img_fragment.length() > 15 && img_fragment.endsWith("[/local]") && img_fragment.startsWith("[local]")) {
|
|
|
|
|
int limit = 7;
|
|
|
|
|
int len = img_fragment.length() - 15;
|
|
|
|
@ -369,17 +410,23 @@ public class NoteEditActivity extends Activity implements OnClickListener,
|
|
|
|
|
Bitmap bitmap = null;
|
|
|
|
|
Log.d(TAG, "图片的路径是:" + path);
|
|
|
|
|
try {
|
|
|
|
|
//BitmapFactory.decodeFile(path)是Android中用于从指定路径加载图片文件并返回一个Bitmap对象的方法
|
|
|
|
|
bitmap = BitmapFactory.decodeFile(path);
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
e.printStackTrace();
|
|
|
|
|
}
|
|
|
|
|
//如果解码成功(即bitmap不为null),则创建一个新的ImageSpan对象,并将其插入到原始文本中,替换原来的图片标记
|
|
|
|
|
if (bitmap != null) {
|
|
|
|
|
Log.d(TAG, "图片不为null");
|
|
|
|
|
//创建一个SpannableString对象,将字符串ss作为参数传递给构造函数。
|
|
|
|
|
//SpannableString是一个可编辑的字符串,可以设置文本样式(如颜色、大小等)。
|
|
|
|
|
ImageSpan imageSpan = new ImageSpan(NoteEditActivity.this, bitmap);
|
|
|
|
|
String ss = "[local]" + path + "[/local]";
|
|
|
|
|
SpannableString spannableString = new SpannableString(ss);
|
|
|
|
|
//将ImageSpan对象应用于spannableString,从索引0开始,到字符串长度结束。这样可以将图片显示在指定的文本范围内
|
|
|
|
|
spannableString.setSpan(imageSpan, 0, ss.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
|
|
|
|
|
Log.d(TAG, "Create spannable string success!");
|
|
|
|
|
//获取noteEditText的可编辑文本内容,并将其赋值给变量edit_text
|
|
|
|
|
Editable edit_text = noteEditText.getEditableText();
|
|
|
|
|
edit_text.delete(i, i + len + 15);
|
|
|
|
|
edit_text.insert(i, spannableString);
|
|
|
|
@ -390,6 +437,7 @@ public class NoteEditActivity extends Activity implements OnClickListener,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//处理返回的数据,并将图片的路径也写入到数据库
|
|
|
|
|
//当用户在相机应用中选择了一张图片后,该图片的URI会被传递给NoteEditActivity,然后通过这个方法进行处理。
|
|
|
|
|
@RequiresApi(api = Build.VERSION_CODES.KITKAT)
|
|
|
|
|
protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
|
|
|
|
|
super.onActivityResult(requestCode, resultCode, intent);
|
|
|
|
@ -399,12 +447,11 @@ public class NoteEditActivity extends Activity implements OnClickListener,
|
|
|
|
|
Uri originalUri = intent.getData();
|
|
|
|
|
Bitmap bitmap = null;
|
|
|
|
|
try {
|
|
|
|
|
bitmap = BitmapFactory.decodeStream(resolver.openInputStream(originalUri));//2.解码图片
|
|
|
|
|
bitmap = BitmapFactory.decodeStream(resolver.openInputStream(originalUri));//解码图片
|
|
|
|
|
} catch (FileNotFoundException e) {
|
|
|
|
|
Log.d(TAG, "onActivityResult: get file_exception");
|
|
|
|
|
e.printStackTrace();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (bitmap != null) {
|
|
|
|
|
Log.d(TAG, "onActivityResult: bitmap is not null");
|
|
|
|
|
ImageSpan imageSpan = new ImageSpan(NoteEditActivity.this, bitmap);
|
|
|
|
@ -467,12 +514,15 @@ public class NoteEditActivity extends Activity implements OnClickListener,
|
|
|
|
|
}
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
//用于从给定的URI中获取数据列
|
|
|
|
|
//Android的ContentResolver类来执行查询操作,通过url来定位和获取上下文数据
|
|
|
|
|
public String getDataColumn(Context context, Uri uri, String selection, String[] selectionArgs) {
|
|
|
|
|
Cursor cursor = null;
|
|
|
|
|
final String column = "_data";
|
|
|
|
|
final String[] projection = {column};
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
//调用context.getContentResolver().query()方法,传入URI、投影、选择条件、选择参数和排序方式,执行查询操作并将结果存储在cursor中
|
|
|
|
|
cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs, null);
|
|
|
|
|
if (cursor != null && cursor.moveToFirst()) {
|
|
|
|
|
final int column_index = cursor.getColumnIndexOrThrow(column);
|
|
|
|
@ -491,17 +541,27 @@ public class NoteEditActivity extends Activity implements OnClickListener,
|
|
|
|
|
return "com.android.providers.media.documents".equals(uri.getAuthority());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @method onCreate
|
|
|
|
|
* @description 描述一下方法的作用方法的主要作用是初始化Activity的状态、资源和界面,并对便签内容进行处理和计数。
|
|
|
|
|
*/
|
|
|
|
|
@Override
|
|
|
|
|
protected void onCreate(Bundle savedInstanceState) {
|
|
|
|
|
super.onCreate(savedInstanceState);
|
|
|
|
|
this.setContentView(R.layout.note_edit);
|
|
|
|
|
this.setContentView(R.layout.note_edit); //调用setContentView方法设置当前Activity显示的布局为note_edit.xml文件。
|
|
|
|
|
setmChanged(new Stack<>() );
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* 判断savedInstanceState是否为空,并调用initActivityState方法初始化Activity的状态。
|
|
|
|
|
* initActivityState方法会根据传入的Intent信息,判断当前是新建一个便签还是编辑一个已有的便签。
|
|
|
|
|
*/
|
|
|
|
|
if (savedInstanceState == null && !initActivityState(getIntent())) {
|
|
|
|
|
finish();
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
initResources();
|
|
|
|
|
count();
|
|
|
|
|
|
|
|
|
|
initResources();//调用initResources方法初始化Activity中的资源,如绑定控件等。
|
|
|
|
|
count();//新增文档计数功能
|
|
|
|
|
|
|
|
|
|
final ImageButton add_img_btn = (ImageButton) findViewById(R.id.add_img_btn);
|
|
|
|
|
add_img_btn.setOnClickListener(new View.OnClickListener() {
|
|
|
|
@ -523,21 +583,37 @@ public class NoteEditActivity extends Activity implements OnClickListener,
|
|
|
|
|
*/
|
|
|
|
|
//用于在Activity被系统销毁后恢复其状态
|
|
|
|
|
@Override
|
|
|
|
|
/**
|
|
|
|
|
* @method onRestoreInstanceState
|
|
|
|
|
* @description 该方法的主要作用是在Activity恢复状态时,根据保存的数据重新初始化Activity的状态,
|
|
|
|
|
* 以保证在Activity被销毁后重新创建时能够正确恢复之前的状态。
|
|
|
|
|
*/
|
|
|
|
|
protected void onRestoreInstanceState(Bundle savedInstanceState) {
|
|
|
|
|
super.onRestoreInstanceState(savedInstanceState);
|
|
|
|
|
//将保存在savedInstanceState中的Intent.EXTRA_UID的值作为Long类型的额外数据传递给新的Intent对象。
|
|
|
|
|
if (savedInstanceState != null && savedInstanceState.containsKey(Intent.EXTRA_UID)) {
|
|
|
|
|
Intent intent = new Intent(Intent.ACTION_VIEW);
|
|
|
|
|
intent.putExtra(Intent.EXTRA_UID, savedInstanceState.getLong(Intent.EXTRA_UID));
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* 调用initActivityState方法,将新的Intent传递进去进行初始化Activity的状态。
|
|
|
|
|
* 如果initActivityState返回false,说明初始化失败,直接销毁Activity并返回。
|
|
|
|
|
*/
|
|
|
|
|
if (!initActivityState(intent)) {
|
|
|
|
|
finish();
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
Log.d(TAG, "Restoring from killed activity");
|
|
|
|
|
}
|
|
|
|
|
}//为防止内存不足时程序的终止,在这里有一个保存现场的函数
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//该方法主要用于初始化Activity的状态,根据传入的Intent的不同动作(action)执行不同的操作。
|
|
|
|
|
private boolean initActivityState(Intent intent) {
|
|
|
|
|
/**
|
|
|
|
|
* @method initActivityState
|
|
|
|
|
* @description 作用是初始化NoteEditActivity的状态。
|
|
|
|
|
* @param
|
|
|
|
|
* @return true表示初始化成功 false表示初始化失败
|
|
|
|
|
*/
|
|
|
|
|
private boolean initActivityState(Intent intent) {//用于实时更新字符数的文本视图
|
|
|
|
|
/**
|
|
|
|
|
* If the user specified the {@link Intent#ACTION_VIEW} but not provided with id,
|
|
|
|
|
* then jump to the NotesListActivity
|
|
|
|
@ -547,31 +623,34 @@ public class NoteEditActivity extends Activity implements OnClickListener,
|
|
|
|
|
if (TextUtils.equals(Intent.ACTION_VIEW, intent.getAction())) {
|
|
|
|
|
long noteId = intent.getLongExtra(Intent.EXTRA_UID, 0);
|
|
|
|
|
mUserQuery = "";
|
|
|
|
|
|
|
|
|
|
//如果用户实例化标签时,系统并未给出标签ID
|
|
|
|
|
/**
|
|
|
|
|
* Starting from the searched result
|
|
|
|
|
*/
|
|
|
|
|
//根据键值查找ID
|
|
|
|
|
if (intent.hasExtra(SearchManager.EXTRA_DATA_KEY)) {
|
|
|
|
|
noteId = Long.parseLong(intent.getStringExtra(SearchManager.EXTRA_DATA_KEY));
|
|
|
|
|
mUserQuery = intent.getStringExtra(SearchManager.USER_QUERY);
|
|
|
|
|
}
|
|
|
|
|
//DataUtils.visibleInNoteDatabase(getContentResolver(), noteId, Notes.TYPE_NOTE) 是一个方法调用
|
|
|
|
|
// 用于检查给定的 noteId 是否存在于笔记数据库中
|
|
|
|
|
//如果ID在数据库中未找到
|
|
|
|
|
if (!DataUtils.visibleInNoteDatabase(getContentResolver(), noteId, Notes.TYPE_NOTE)) {
|
|
|
|
|
Intent jump = new Intent(this, NotesListActivity.class);
|
|
|
|
|
startActivity(jump);
|
|
|
|
|
startActivity(jump);//程序将跳转到上面声明的intent——jump
|
|
|
|
|
showToast(R.string.error_note_not_exist);
|
|
|
|
|
finish();
|
|
|
|
|
return false;
|
|
|
|
|
} else {
|
|
|
|
|
} else {//ID在数据库中找到
|
|
|
|
|
//如果指定的笔记 ID 存在于笔记数据库中,则调用 WorkingNote.load() 方法,根据指定的笔记 ID 加载笔记对象,并将结果赋值给 mWorkingNote
|
|
|
|
|
mWorkingNote = WorkingNote.load(this, noteId);
|
|
|
|
|
if (mWorkingNote == null) {
|
|
|
|
|
Log.e(TAG, "load note failed with note id" + noteId);
|
|
|
|
|
Log.e(TAG, "load note failed with note id" + noteId); //打印出红色的错误信息
|
|
|
|
|
finish();
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
//setSoftInputMode——软键盘输入模式
|
|
|
|
|
getWindow().setSoftInputMode(
|
|
|
|
|
WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN
|
|
|
|
|
| WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
|
|
|
|
@ -579,6 +658,11 @@ public class NoteEditActivity extends Activity implements OnClickListener,
|
|
|
|
|
//需要创建或编辑一个笔记
|
|
|
|
|
// New note
|
|
|
|
|
//从 Intent 中获取一些额外的信息,如文件夹 ID、小部件 ID、小部件类型和背景资源 ID。这些信息用于确定新笔记的位置和外观。
|
|
|
|
|
/*
|
|
|
|
|
* intent.getAction()
|
|
|
|
|
* 大多用于broadcast发送广播时给机制(intent)设置一个action,就是一个字符串
|
|
|
|
|
* 用户可以通过receive(接受)intent,通过 getAction得到的字符串,来决定做什么
|
|
|
|
|
*/
|
|
|
|
|
long folderId = intent.getLongExtra(Notes.INTENT_EXTRA_FOLDER_ID, 0);
|
|
|
|
|
int widgetId = intent.getIntExtra(Notes.INTENT_EXTRA_WIDGET_ID,
|
|
|
|
|
AppWidgetManager.INVALID_APPWIDGET_ID);
|
|
|
|
@ -625,20 +709,37 @@ public class NoteEditActivity extends Activity implements OnClickListener,
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @method onResume
|
|
|
|
|
* @description 在Activity恢复时重新初始化便签的显示
|
|
|
|
|
*/
|
|
|
|
|
@Override
|
|
|
|
|
protected void onResume() {
|
|
|
|
|
super.onResume();
|
|
|
|
|
initNoteScreen();
|
|
|
|
|
initNoteScreen();//然后调用initNoteScreen方法,该方法会根据mWorkingNote的内容初始化便签的各个UI控件,例如标题栏、编辑区域、图片等。
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//用于初始化笔记屏幕
|
|
|
|
|
/**
|
|
|
|
|
* @method initNoteScreen
|
|
|
|
|
* @description 根据mWorkingNote的内容重新初始化便签的UI,包括文本样式、编辑区域、背景、修改时间等
|
|
|
|
|
*/
|
|
|
|
|
private void initNoteScreen() {
|
|
|
|
|
mNoteEditor.setTextAppearance(this, TextAppearanceResources
|
|
|
|
|
.getTexAppearanceResource(mFontSizeId));
|
|
|
|
|
if (mWorkingNote.getCheckListMode() == TextNote.MODE_CHECK_LIST) {
|
|
|
|
|
/*
|
|
|
|
|
* 如果当前便签是“清单”模式,则调用switchToListMode方法将编辑区域切换到“清单”模式,
|
|
|
|
|
* 并将mWorkingNote中的内容填充到编辑区域。
|
|
|
|
|
*/
|
|
|
|
|
if (mWorkingNote.getCheckListMode() == TextNote.MODE_CHECK_LIST) {//首先根据mFontSizeId设置mNoteEditor的文本样式。
|
|
|
|
|
switchToListMode(mWorkingNote.getContent());
|
|
|
|
|
} else {
|
|
|
|
|
mNoteEditor.setText(getHighlightQueryResult(mWorkingNote.getContent(), mUserQuery));
|
|
|
|
|
}
|
|
|
|
|
/*
|
|
|
|
|
* 如果当前便签不是“清单”模式,则将mWorkingNote中的内容填充到编辑区域
|
|
|
|
|
* 并调用getHighlightQueryResult方法将搜索关键字高亮显示。
|
|
|
|
|
*/
|
|
|
|
|
else {
|
|
|
|
|
mNoteEditor.setText(getHighlightQueryResult(mWorkingNote.getContent(), mUserQuery));//将所有背景选择器控件隐藏,然后根据mWorkingNote的标题背景和便签背景设置标题栏和编辑区域的背景。
|
|
|
|
|
mNoteEditor.setSelection(mNoteEditor.getText().length());
|
|
|
|
|
}
|
|
|
|
|
for (Integer id : sBgSelectorSelectionMap.keySet()) {
|
|
|
|
@ -660,12 +761,17 @@ public class NoteEditActivity extends Activity implements OnClickListener,
|
|
|
|
|
convertToImage();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @method showAlertHeader
|
|
|
|
|
* @description 根据mWorkingNote的提醒设置来显示提醒相关的UI,包括提醒日期文本和提醒图标。
|
|
|
|
|
* 如果有设置提醒,则根据当前时间判断是否已过期,并显示相应的文本。如果没有设置提醒,则隐藏相关UI。
|
|
|
|
|
*/
|
|
|
|
|
private void showAlertHeader() {
|
|
|
|
|
if (mWorkingNote.hasClockAlert()) {
|
|
|
|
|
if (mWorkingNote.hasClockAlert()) {//首先判断mWorkingNote是否有设置提醒(hasClockAlert)。如果有设置提醒,则执行以下步骤
|
|
|
|
|
long time = System.currentTimeMillis();
|
|
|
|
|
if (time > mWorkingNote.getAlertDate()) {
|
|
|
|
|
mNoteHeaderHolder.tvAlertDate.setText(R.string.note_alert_expired);
|
|
|
|
|
} else {
|
|
|
|
|
mNoteHeaderHolder.tvAlertDate.setText(R.string.note_alert_expired);//判断当前时间是否超过了提醒时间(mWorkingNote.getAlertDate)。如果超过了提醒时间,则将提醒日期文本(tvAlertDate)
|
|
|
|
|
} else {//如果没有超过提醒时间,则将提醒日期文本设置为相对时间,即距离提醒时间还有多久(使用DateUtils.getRelativeTimeSpanString方法)。
|
|
|
|
|
mNoteHeaderHolder.tvAlertDate.setText(DateUtils.getRelativeTimeSpanString(
|
|
|
|
|
mWorkingNote.getAlertDate(), time, DateUtils.MINUTE_IN_MILLIS));
|
|
|
|
|
}
|
|
|
|
@ -678,11 +784,18 @@ public class NoteEditActivity extends Activity implements OnClickListener,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
//在Activity已经存在于任务栈中时,再次启动该Activity时的回调方法,可以在其中处理相关的逻辑操作
|
|
|
|
|
protected void onNewIntent(Intent intent) {
|
|
|
|
|
super.onNewIntent(intent);
|
|
|
|
|
initActivityState(intent);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @method onSaveInstanceState
|
|
|
|
|
* @description 在Activity即将被销毁时的回调方法,用于保存当前Activity的状态,
|
|
|
|
|
* 以便在Activity被恢复时能够正确地加载之前的状态。
|
|
|
|
|
* @return void
|
|
|
|
|
*/
|
|
|
|
|
@Override
|
|
|
|
|
protected void onSaveInstanceState(Bundle outState) {
|
|
|
|
|
super.onSaveInstanceState(outState);
|
|
|
|
@ -692,28 +805,33 @@ public class NoteEditActivity extends Activity implements OnClickListener,
|
|
|
|
|
* is no id which is equivalent to create new note
|
|
|
|
|
*/
|
|
|
|
|
if (!mWorkingNote.existInDatabase()) {
|
|
|
|
|
saveNote();
|
|
|
|
|
saveNote();//在创建一个新的标签时,先在数据库中匹配
|
|
|
|
|
//如果不存在,那么先在数据库中存储
|
|
|
|
|
}
|
|
|
|
|
outState.putLong(Intent.EXTRA_UID, mWorkingNote.getNoteId());
|
|
|
|
|
Log.d(TAG, "Save working note id: " + mWorkingNote.getNoteId() + " onSaveInstanceState");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
//MotionEvent是对屏幕触控的传递机制
|
|
|
|
|
public boolean dispatchTouchEvent(MotionEvent ev) {
|
|
|
|
|
if (mNoteBgColorSelector.getVisibility() == View.VISIBLE
|
|
|
|
|
&& !inRangeOfView(mNoteBgColorSelector, ev)) {
|
|
|
|
|
mNoteBgColorSelector.setVisibility(View.GONE);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}//颜色选择器在屏幕上可见
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (mFontSizeSelector.getVisibility() == View.VISIBLE
|
|
|
|
|
&& !inRangeOfView(mFontSizeSelector, ev)) {
|
|
|
|
|
mFontSizeSelector.setVisibility(View.GONE);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}//字体大小选择器在屏幕上可见
|
|
|
|
|
return super.dispatchTouchEvent(ev);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//对屏幕触控的坐标进行操作
|
|
|
|
|
private boolean inRangeOfView(View view, MotionEvent ev) {
|
|
|
|
|
int []location = new int[2];
|
|
|
|
|
view.getLocationOnScreen(location);
|
|
|
|
@ -723,7 +841,7 @@ public class NoteEditActivity extends Activity implements OnClickListener,
|
|
|
|
|
|| ev.getX() > (x + view.getWidth())
|
|
|
|
|
|| ev.getY() < y
|
|
|
|
|
|| ev.getY() > (y + view.getHeight())) {
|
|
|
|
|
return false;
|
|
|
|
|
return false;//如果触控的位置超出了给定的范围,返回false
|
|
|
|
|
}
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
@ -751,12 +869,12 @@ public class NoteEditActivity extends Activity implements OnClickListener,
|
|
|
|
|
for (int id : sBgSelectorBtnsMap.keySet()) {
|
|
|
|
|
ImageView iv = (ImageView) findViewById(id);
|
|
|
|
|
iv.setOnClickListener(this);
|
|
|
|
|
}
|
|
|
|
|
}//对标签各项属性内容的初始化
|
|
|
|
|
mFontSizeSelector = findViewById(R.id.font_size_selector);
|
|
|
|
|
for (int id : sFontSizeBtnsMap.keySet()) {
|
|
|
|
|
View view = findViewById(id);
|
|
|
|
|
view.setOnClickListener(this);
|
|
|
|
|
};
|
|
|
|
|
};//对字体大小的选择
|
|
|
|
|
mSharedPrefs = PreferenceManager.getDefaultSharedPreferences(this);
|
|
|
|
|
mFontSizeId = mSharedPrefs.getInt(PREFERENCE_FONT_SIZE, ResourceParser.BG_DEFAULT_FONT_SIZE);
|
|
|
|
|
/**
|
|
|
|
@ -910,15 +1028,17 @@ public class NoteEditActivity extends Activity implements OnClickListener,
|
|
|
|
|
alertDialog2.show();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//在Activity即将失去焦点并进入后台时的回调方法,用于执行一些与保存数据、清除状态等相关的操作。
|
|
|
|
|
@Override
|
|
|
|
|
protected void onPause() {
|
|
|
|
|
super.onPause();
|
|
|
|
|
if(saveNote()) {
|
|
|
|
|
Log.d(TAG, "Note data was saved with length:" + mWorkingNote.getContent().length());
|
|
|
|
|
}
|
|
|
|
|
clearSettingState();
|
|
|
|
|
clearSettingState();//调用clearSettingState()方法来清除一些设置状态。具体的逻辑需要根据实际需求来实现,可能包括清除临时数据、重置一些标志位等。
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//和桌面小工具的同步
|
|
|
|
|
private void updateWidget() {
|
|
|
|
|
Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
|
|
|
|
|
if (mWorkingNote.getWidgetType() == Notes.TYPE_WIDGET_2X) {
|
|
|
|
@ -934,6 +1054,7 @@ public class NoteEditActivity extends Activity implements OnClickListener,
|
|
|
|
|
mWorkingNote.getWidgetId()
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
//将当前Note笔记的Widget ID放入Intent的Extra参数中。注意,这里只更新当前Note笔记所绑定的Widget,因此只需要传入一个Widget ID。
|
|
|
|
|
sendBroadcast(intent);
|
|
|
|
|
setResult(RESULT_OK, intent);
|
|
|
|
|
}
|
|
|
|
@ -965,10 +1086,19 @@ public class NoteEditActivity extends Activity implements OnClickListener,
|
|
|
|
|
} else {
|
|
|
|
|
mNoteEditor.setTextAppearance(this, TextAppearanceResources.getTexAppearanceResource(mFontSizeId));
|
|
|
|
|
}
|
|
|
|
|
/*
|
|
|
|
|
* 如果点击的ID在sFontSizeBtnsMap中存在(即点击的是字体大小选择项的按钮),则将当前字体大小的选择项设置为不可见,
|
|
|
|
|
* 将字体大小ID更新为对应的值,并将新的字体大小选择项设置为可见。
|
|
|
|
|
* 同时,根据Note笔记的模式(是否为检查列表模式)进行相应的处理:
|
|
|
|
|
* 如果是检查列表模式,则切换到列表模式并获取最新的Note内容;
|
|
|
|
|
* 否则,仅更新文本编辑器的字体样式。
|
|
|
|
|
*/
|
|
|
|
|
mFontSizeSelector.setVisibility(View.GONE);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//这段代码重写了Activity的返回按钮操作,
|
|
|
|
|
// 在返回操作中处理了设置状态的清除和Note笔记的保存。
|
|
|
|
|
@Override
|
|
|
|
|
public void onBackPressed() {
|
|
|
|
|
if(clearSettingState()) {
|
|
|
|
@ -979,7 +1109,14 @@ public class NoteEditActivity extends Activity implements OnClickListener,
|
|
|
|
|
super.onBackPressed();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @method clearSettingState
|
|
|
|
|
* @description 这个方法的作用是在用户按下返回按钮时,检查当前是否处于设置状态(例如正在选择背景颜色或字体大小),
|
|
|
|
|
* 如果是,则清除设置状态并返回true,否则返回false。
|
|
|
|
|
* @return true表示成功清除了设置状态 返回false表示当前没有处于设置状态。
|
|
|
|
|
*/
|
|
|
|
|
private boolean clearSettingState() {
|
|
|
|
|
//首先检查背景颜色选择器(mNoteBgColorSelector)和字体大小选择器(mFontSizeSelector)的可见性
|
|
|
|
|
if (mNoteBgColorSelector.getVisibility() == View.VISIBLE) {
|
|
|
|
|
mNoteBgColorSelector.setVisibility(View.GONE);
|
|
|
|
|
return true;
|
|
|
|
@ -990,24 +1127,34 @@ public class NoteEditActivity extends Activity implements OnClickListener,
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @method onBackgroundColorChanged
|
|
|
|
|
* @description 在背景颜色发生变化时,根据新的背景颜色ID更新选中状态的选择项的可见性,
|
|
|
|
|
* 并将新的背景颜色资源应用到相关的视图上,以实现界面的背景颜色变更
|
|
|
|
|
*/
|
|
|
|
|
public void onBackgroundColorChanged() {
|
|
|
|
|
findViewById(sBgSelectorSelectionMap.get(mWorkingNote.getBgColorId())).setVisibility(
|
|
|
|
|
View.VISIBLE);
|
|
|
|
|
mNoteEditorPanel.setBackgroundResource(mWorkingNote.getBgColorResId());
|
|
|
|
|
mHeadViewPanel.setBackgroundResource(mWorkingNote.getTitleBgResId());
|
|
|
|
|
//获取当前Note笔记的背景颜色资源ID,并将该资源作为背景设置给mNoteEditorPanel和mHeadViewPanel,实现对编辑区域和标题区域的背景颜色的更新。
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @method onPrepareOptionsMenu
|
|
|
|
|
* @description 根据当前Note笔记的状态和属性,动态加载选项菜单的内容,并更新其中的部分选项的名称和可见性。
|
|
|
|
|
*/
|
|
|
|
|
//该方法的主要作用是根据当前的工作笔记(mWorkingNote)的属性来准备和更新菜单项。
|
|
|
|
|
@Override
|
|
|
|
|
public boolean onPrepareOptionsMenu(Menu menu) {
|
|
|
|
|
if (isFinishing()) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}//判断当前Activity是否正在关闭,如果是,则直接返回true,不做任何处理。
|
|
|
|
|
clearSettingState();
|
|
|
|
|
menu.clear();
|
|
|
|
|
menu.clear(); //调用clearSettingState()方法清除当前的设置状态,并使用menu.clear()方法清空选项菜单中的所有选项。
|
|
|
|
|
|
|
|
|
|
//工作笔记的文件夹ID
|
|
|
|
|
if (mWorkingNote.getFolderId() == Notes.ID_CALL_RECORD_FOLDER) {
|
|
|
|
|
getMenuInflater().inflate(R.menu.call_note_edit, menu);
|
|
|
|
|
getMenuInflater().inflate(R.menu.call_note_edit, menu);// MenuInflater是用来实例化Menu目录下的Menu布局文件的
|
|
|
|
|
} else {
|
|
|
|
|
getMenuInflater().inflate(R.menu.note_edit, menu);
|
|
|
|
|
}
|
|
|
|
@ -1016,6 +1163,7 @@ public class NoteEditActivity extends Activity implements OnClickListener,
|
|
|
|
|
} else {
|
|
|
|
|
menu.findItem(R.id.menu_list_mode).setTitle(R.string.menu_list_mode);
|
|
|
|
|
}
|
|
|
|
|
//如果当前Note笔记已经有闹钟提醒,则隐藏“添加提醒”选项,否则隐藏“删除提醒”选项。
|
|
|
|
|
if (mWorkingNote.hasClockAlert()) {
|
|
|
|
|
menu.findItem(R.id.menu_alert).setVisible(false);
|
|
|
|
|
} else {
|
|
|
|
@ -1024,12 +1172,22 @@ public class NoteEditActivity extends Activity implements OnClickListener,
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @method onOptionsItemSelected
|
|
|
|
|
* @description 用于处理选项菜单中的各个选项被点击时的事件响应。
|
|
|
|
|
* @return boolean 返回true表示已经处理了该选项的点击事件。
|
|
|
|
|
*/
|
|
|
|
|
@Override
|
|
|
|
|
public boolean onOptionsItemSelected(MenuItem item) {
|
|
|
|
|
int itemId = item.getItemId();
|
|
|
|
|
if (itemId == R.id.menu_new_note) {
|
|
|
|
|
int itemId = item.getItemId();//在这个方法中,首先获取被点击的选项的ID,然后根据ID的不同执行相应的操作。
|
|
|
|
|
if (itemId == R.id.menu_new_note) {//如果被点击的选项是“新建笔记”,则调用createNewNote()方法创建一个新的笔记。
|
|
|
|
|
createNewNote();
|
|
|
|
|
} else if (itemId == R.id.menu_delete) {
|
|
|
|
|
}
|
|
|
|
|
/*
|
|
|
|
|
* 如果被点击的选项是“删除”,则弹出一个警告对话框,询问用户是否确认删除当前笔记。
|
|
|
|
|
* 如果用户确认删除,则调用deleteCurrentNote()方法删除当前笔记,并关闭当前Activity。
|
|
|
|
|
*/
|
|
|
|
|
else if (itemId == R.id.menu_delete) {
|
|
|
|
|
AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
|
|
|
|
builder.setTitle(getString(R.string.alert_title_delete));
|
|
|
|
|
builder.setIcon(android.R.drawable.ic_dialog_alert);
|
|
|
|
@ -1043,20 +1201,33 @@ public class NoteEditActivity extends Activity implements OnClickListener,
|
|
|
|
|
});
|
|
|
|
|
builder.setNegativeButton(android.R.string.cancel, null);
|
|
|
|
|
builder.show();
|
|
|
|
|
} else if (itemId == R.id.menu_font_size) {
|
|
|
|
|
}
|
|
|
|
|
//如果被点击的选项是“修改字体大小”,则显示字体大小选择器,以供用户选择字体大小。
|
|
|
|
|
else if (itemId == R.id.menu_font_size) {
|
|
|
|
|
mFontSizeSelector.setVisibility (View.VISIBLE);
|
|
|
|
|
findViewById(sFontSelectorSelectionMap.get(mFontSizeId)).setVisibility(View.VISIBLE);
|
|
|
|
|
} else if (itemId == R.id.menu_list_mode) {
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
//如果被点击的选项是“切换列表模式”,则切换当前笔记的检查列表模式状态。
|
|
|
|
|
else if (itemId == R.id.menu_list_mode) {
|
|
|
|
|
mWorkingNote.setCheckListMode(mWorkingNote.getCheckListMode() == 0 ?
|
|
|
|
|
TextNote.MODE_CHECK_LIST : 0);
|
|
|
|
|
} else if (itemId == R.id.menu_share) {
|
|
|
|
|
}
|
|
|
|
|
//如果被点击的选项是“分享”,则获取当前笔记的内容并将其发送到其他应用程序。
|
|
|
|
|
else if (itemId == R.id.menu_share) {
|
|
|
|
|
getWorkingText();
|
|
|
|
|
sendTo(this, mWorkingNote.getContent());
|
|
|
|
|
} else if (itemId == R.id.menu_send_to_desktop) {
|
|
|
|
|
}
|
|
|
|
|
//如果被点击的选项是“发送到桌面”,则将当前笔记发送到桌面。
|
|
|
|
|
else if (itemId == R.id.menu_send_to_desktop) {
|
|
|
|
|
sendToDesktop();
|
|
|
|
|
} else if (itemId == R.id.menu_alert) {
|
|
|
|
|
}
|
|
|
|
|
//如果被点击的选项是“添加提醒”,则设置当前笔记的提醒时间
|
|
|
|
|
else if (itemId == R.id.menu_alert) {
|
|
|
|
|
setReminder();
|
|
|
|
|
} else if (itemId == R.id.menu_delete_remind) {
|
|
|
|
|
}
|
|
|
|
|
//如果被点击的选项是“删除提醒”,则清除当前笔记的提醒时间
|
|
|
|
|
else if (itemId == R.id.menu_delete_remind) {
|
|
|
|
|
mWorkingNote.setAlertDate(0, false);
|
|
|
|
|
}else if(itemId == R.id.menu_revoke) {
|
|
|
|
|
doRevoke();
|
|
|
|
@ -1075,42 +1246,51 @@ public class NoteEditActivity extends Activity implements OnClickListener,
|
|
|
|
|
private void setReminder() {
|
|
|
|
|
DateTimePickerDialog d = new DateTimePickerDialog(this, System.currentTimeMillis());
|
|
|
|
|
d.setOnDateTimeSetListener(new OnDateTimeSetListener() {
|
|
|
|
|
//首先创建一个DateTimePickerDialog对象,并将当前系统时间作为初始时间传入。
|
|
|
|
|
// 然后,为该对话框设置一个日期时间选择器监听器。
|
|
|
|
|
public void OnDateTimeSet(AlertDialog dialog, long date) {
|
|
|
|
|
mWorkingNote.setAlertDate(date , true);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
d.show();
|
|
|
|
|
d.show();//最后,显示日期时间选择器对话框。
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Share note to apps that support {@link Intent#ACTION_SEND} action
|
|
|
|
|
* and {@text/plain} type
|
|
|
|
|
*/
|
|
|
|
|
/**
|
|
|
|
|
* @method sendTo
|
|
|
|
|
* @description 用于在给定的Context上下文环境中,利用系统默认的分享功能将特定的文本信息发送给其他应用程序。
|
|
|
|
|
*/
|
|
|
|
|
private void sendTo(Context context, String info) {
|
|
|
|
|
Intent intent = new Intent(Intent.ACTION_SEND);
|
|
|
|
|
intent.putExtra(Intent.EXTRA_TEXT, info);
|
|
|
|
|
intent.setType("text/plain");
|
|
|
|
|
context.startActivity(intent);
|
|
|
|
|
Intent intent = new Intent(Intent.ACTION_SEND);//在方法内部,首先创建一个新的Intent对象,并将其动作设置为Intent.ACTION_SEND,表示发送内容。
|
|
|
|
|
|
|
|
|
|
intent.putExtra(Intent.EXTRA_TEXT, info);//接着,通过putExtra方法将要分享的文本信息info放入Intent中,使用Intent.EXTRA_TEXT作为键。
|
|
|
|
|
|
|
|
|
|
intent.setType("text/plain"); //然后,使用setType方法将要分享的内容的MIME类型设置为"text/plain",表示纯文本类型。
|
|
|
|
|
|
|
|
|
|
context.startActivity(intent);//最后,通过context.startActivity(intent)启动该Intent,将文本信息发送给其他应用程序进行处理。
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void count(){
|
|
|
|
|
private void count(){//用于实时更新字符数的文本视图
|
|
|
|
|
mNoteEditor.addTextChangedListener(new TextWatcher() {
|
|
|
|
|
|
|
|
|
|
int currentlength = 0;
|
|
|
|
|
@Override
|
|
|
|
|
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
|
|
|
|
|
textView.setText("字符数:"+currentlength);
|
|
|
|
|
}
|
|
|
|
|
}//在beforeTextChanged()方法中,通过获取当前文本的长度并更新textView的文本来显示当前字符数。
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
|
|
|
|
|
currentlength = editText.getText().length();
|
|
|
|
|
}
|
|
|
|
|
}//在onTextChanged()方法中,通过获取编辑框的文本长度并将其赋值给currentLength变量,以便在afterTextChanged()方法中使用。
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public void afterTextChanged(Editable editable) {
|
|
|
|
|
textView.setText("字符数:" + currentlength);
|
|
|
|
|
}
|
|
|
|
|
}//在afterTextChanged()方法中,再次更新textView的文本以显示最新的字符数
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
private void createNewNote() {
|
|
|
|
@ -1130,6 +1310,7 @@ public class NoteEditActivity extends Activity implements OnClickListener,
|
|
|
|
|
startActivity(intent);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//删除便签
|
|
|
|
|
private void deleteCurrentNote() {
|
|
|
|
|
//假如当前运行的便签内存有数据
|
|
|
|
|
if (mWorkingNote.existInDatabase()) {
|
|
|
|
@ -1159,6 +1340,11 @@ public class NoteEditActivity extends Activity implements OnClickListener,
|
|
|
|
|
mWorkingNote.markDeleted(true);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @method isSyncMode
|
|
|
|
|
* @description 用于判断是否处于同步模式。
|
|
|
|
|
* @return 如果此名称的长度大于0,则说明处于同步模式,返回true;否则返回false。
|
|
|
|
|
*/
|
|
|
|
|
private boolean isSyncMode() {
|
|
|
|
|
return NotesPreferenceActivity.getSyncAccountName(this).trim().length() > 0;
|
|
|
|
|
}
|
|
|
|
@ -1168,10 +1354,11 @@ public class NoteEditActivity extends Activity implements OnClickListener,
|
|
|
|
|
* User could set clock to an unsaved note, so before setting the
|
|
|
|
|
* alert clock, we should save the note first
|
|
|
|
|
*/
|
|
|
|
|
if (!mWorkingNote.existInDatabase()) {
|
|
|
|
|
if (!mWorkingNote.existInDatabase()) {//首先检查当前工作的便签是否存在于数据库中,如果不存在,则调用saveNote()方法保存便签。
|
|
|
|
|
saveNote();
|
|
|
|
|
}
|
|
|
|
|
if (mWorkingNote.getNoteId() > 0) {
|
|
|
|
|
if (mWorkingNote.getNoteId() > 0) {//若当前便签的ID大于0,则创建一个用于触发闹钟的Intent,并设置相应的PendingIntent。
|
|
|
|
|
// 然后根据参数set来决定是取消闹钟还是设置新的闹钟时间。
|
|
|
|
|
Intent intent = new Intent(this, AlarmReceiver.class);
|
|
|
|
|
intent.setData(ContentUris.withAppendedId(Notes.CONTENT_NOTE_URI, mWorkingNote.getNoteId()));
|
|
|
|
|
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, intent, 0);
|
|
|
|
@ -1193,10 +1380,15 @@ public class NoteEditActivity extends Activity implements OnClickListener,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//更新小部件的显示内容。具体的更新逻辑可能包括重新加载数据、刷新UI等操作,以确保小部件展示的内容和状态是最新的。
|
|
|
|
|
public void onWidgetChanged() {
|
|
|
|
|
updateWidget();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @method onEditTextDelete
|
|
|
|
|
* @description 用于处理删除文本编辑框的操作。
|
|
|
|
|
*/
|
|
|
|
|
public void onEditTextDelete(int index, String text) {
|
|
|
|
|
int childCount = mEditTextList.getChildCount();
|
|
|
|
|
if (childCount == 1) {
|
|
|
|
@ -1223,17 +1415,21 @@ public class NoteEditActivity extends Activity implements OnClickListener,
|
|
|
|
|
edit.setSelection(length);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @method onEditTextEnter
|
|
|
|
|
* @description 用于处理插入文本编辑框的操作。
|
|
|
|
|
*/
|
|
|
|
|
public void onEditTextEnter(int index, String text) {
|
|
|
|
|
/**
|
|
|
|
|
* Should not happen, check for debug
|
|
|
|
|
*/
|
|
|
|
|
if(index > mEditTextList.getChildCount()) {
|
|
|
|
|
Log.e(TAG, "Index out of mEditTextList boundrary, should not happen");
|
|
|
|
|
Log.e(TAG, "Index out of mEditTextList boundrary, should not happen");//在方法中,首先检查传入的索引位置是否超出了mEditTextList的子视图数量。如果超出了范围,会记录错误日志。
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
View view = getListItem(text, index);
|
|
|
|
|
mEditTextList.addView(view, index);
|
|
|
|
|
NoteEditText edit = (NoteEditText) view.findViewById(R.id.et_edit_text);
|
|
|
|
|
View view = getListItem(text, index);//根据传入的文本和索引位置创建一个新的视图view。
|
|
|
|
|
mEditTextList.addView(view, index);//将创建的视图插入到mEditTextList中的指定索引位置。
|
|
|
|
|
NoteEditText edit = (NoteEditText) view.findViewById(R.id.et_edit_text);//获取新插入的文本编辑框,并将其请求获取焦点。同时,将光标定位在文本编辑框的开头位置。
|
|
|
|
|
edit.requestFocus();
|
|
|
|
|
edit.setSelection(0);
|
|
|
|
|
for (int i = index + 1; i < mEditTextList.getChildCount(); i++) {
|
|
|
|
@ -1242,6 +1438,7 @@ public class NoteEditActivity extends Activity implements OnClickListener,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//用于切换到列表模式
|
|
|
|
|
private void switchToListMode(String text) {
|
|
|
|
|
mEditTextList.removeAllViews();
|
|
|
|
|
String[] items = text.split("\n");
|
|
|
|
@ -1259,6 +1456,7 @@ public class NoteEditActivity extends Activity implements OnClickListener,
|
|
|
|
|
mEditTextList.setVisibility(View.VISIBLE);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//用于将匹配到的查询结果进行高亮处理。
|
|
|
|
|
private Spannable getHighlightQueryResult(String fullText, String userQuery) {
|
|
|
|
|
SpannableString spannable = new SpannableString(fullText == null ? "" : fullText);
|
|
|
|
|
if (!TextUtils.isEmpty(userQuery)) {
|
|
|
|
@ -1276,11 +1474,15 @@ public class NoteEditActivity extends Activity implements OnClickListener,
|
|
|
|
|
return spannable;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @method getListItem
|
|
|
|
|
* @description 用于根据给定的文本项item和索引index创建一个列表项的视图。
|
|
|
|
|
*/
|
|
|
|
|
private View getListItem(String item, int index) {
|
|
|
|
|
View view = LayoutInflater.from(this).inflate(R.layout.note_edit_list_item, null);
|
|
|
|
|
View view = LayoutInflater.from(this).inflate(R.layout.note_edit_list_item, null);//首先使用LayoutInflater.from(this).inflate(R.layout.note_edit_list_item, null)从布局文件note_edit_list_item中获取一个视图view。
|
|
|
|
|
final NoteEditText edit = (NoteEditText) view.findViewById(R.id.et_edit_text);
|
|
|
|
|
edit.setTextAppearance(this, TextAppearanceResources.getTexAppearanceResource(mFontSizeId));
|
|
|
|
|
CheckBox cb = ((CheckBox) view.findViewById(R.id.cb_edit_item));
|
|
|
|
|
edit.setTextAppearance(this, TextAppearanceResources.getTexAppearanceResource(mFontSizeId));//从view中获取一个NoteEditText编辑框对象edit,并设置其文本外观为当前字体大小mFontSizeId对应的样式。
|
|
|
|
|
CheckBox cb = ((CheckBox) view.findViewById(R.id.cb_edit_item)); //从view中获取一个CheckBox对象cb,并设置其选中状态改变的监听器,以便在状态改变时修改编辑框的文本外观。
|
|
|
|
|
cb.setOnCheckedChangeListener(new OnCheckedChangeListener() {
|
|
|
|
|
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
|
|
|
|
|
if (isChecked) {
|
|
|
|
@ -1291,6 +1493,11 @@ public class NoteEditActivity extends Activity implements OnClickListener,
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
根据文本项的前缀标记判断当前列表项是否被选中。如果是,则将复选框设置为选中状态,并将编辑框的文本外观设置为带有删除线的样式;
|
|
|
|
|
否则,将复选框设置为未选中状态,并将编辑框的文本外观设置为普通样式。
|
|
|
|
|
同时,去除前缀标记并去除两端的空格。
|
|
|
|
|
*/
|
|
|
|
|
if (item.startsWith(TAG_CHECKED)) {
|
|
|
|
|
cb.setChecked(true);
|
|
|
|
|
edit.setPaintFlags(edit.getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG);
|
|
|
|
@ -1303,38 +1510,61 @@ public class NoteEditActivity extends Activity implements OnClickListener,
|
|
|
|
|
|
|
|
|
|
edit.setOnTextViewChangeListener(this);
|
|
|
|
|
edit.setIndex(index);
|
|
|
|
|
edit.setText(getHighlightQueryResult(item, mUserQuery));
|
|
|
|
|
return view;
|
|
|
|
|
edit.setText(getHighlightQueryResult(item, mUserQuery));//设置编辑框的值为经过高亮处理的文本项item,并设置编辑框的索引值为传入的索引index,
|
|
|
|
|
return view;// 最后将edit对象添加到视图view中并返回该视图。
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @method onCheckListModeChanged
|
|
|
|
|
* @description 用于监听编辑框中文本的改变,并根据是否有文本来控制复选框的可见性。
|
|
|
|
|
*/
|
|
|
|
|
public void onTextChange(int index, boolean hasText) {
|
|
|
|
|
if (index >= mEditTextList.getChildCount()) {
|
|
|
|
|
Log.e(TAG, "Wrong index, should not happen");
|
|
|
|
|
return;
|
|
|
|
|
//判断传入的索引值index是否超出了编辑框列表中子视图的数量范围。
|
|
|
|
|
//如果超出,则打印错误日志并退出方法。
|
|
|
|
|
}
|
|
|
|
|
if(hasText) {
|
|
|
|
|
mEditTextList.getChildAt(index).findViewById(R.id.cb_edit_item).setVisibility(View.VISIBLE);
|
|
|
|
|
} else {
|
|
|
|
|
mEditTextList.getChildAt(index).findViewById(R.id.cb_edit_item).setVisibility(View.GONE);
|
|
|
|
|
}
|
|
|
|
|
//根据传入的hasText参数判断当前编辑框是否有文本。如果有文本,则将该编辑框所在的列表项的复选框设置为可见状态;
|
|
|
|
|
// 否则,将复选框设置为不可见状态。
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @method onCheckListModeChanged
|
|
|
|
|
* @description 用于监听检查列表模式的改变,并根据新的模式来更新界面显示。
|
|
|
|
|
*/
|
|
|
|
|
public void onCheckListModeChanged(int oldMode, int newMode) {
|
|
|
|
|
//判断新的模式是否为检查列表模式。如果是,则调用switchToListMode()方法,
|
|
|
|
|
// 并传入当前编辑器中的文本内容,以切换到列表模式。
|
|
|
|
|
if (newMode == TextNote.MODE_CHECK_LIST) {
|
|
|
|
|
switchToListMode(mNoteEditor.getText().toString());
|
|
|
|
|
} else {
|
|
|
|
|
//调用getWorkingText()方法来获取当前的工作文本。如果获取失败(即没有工作文本),则将工作文本设置为去除了未选中标记的内容。
|
|
|
|
|
if (!getWorkingText()) {
|
|
|
|
|
mWorkingNote.setWorkingText(mWorkingNote.getContent().replace(TAG_UNCHECKED + " ",
|
|
|
|
|
""));
|
|
|
|
|
}
|
|
|
|
|
mNoteEditor.setText(getHighlightQueryResult(mWorkingNote.getContent(), mUserQuery));
|
|
|
|
|
mEditTextList.setVisibility(View.GONE);
|
|
|
|
|
mNoteEditor.setVisibility(View.VISIBLE);
|
|
|
|
|
mNoteEditor.setText(getHighlightQueryResult(mWorkingNote.getContent(), mUserQuery));//将编辑器的文本设置为经过高亮处理的工作文本内容
|
|
|
|
|
mEditTextList.setVisibility(View.GONE);//将编辑框列表设置为不可见状态。
|
|
|
|
|
mNoteEditor.setVisibility(View.VISIBLE);//将编辑器设置为可见状态。
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @method getWorkingText
|
|
|
|
|
* @description 用于获取工作笔记的文本内容,并根据是否为待办事项模式进行相应处理。
|
|
|
|
|
* @return 该方法返回一个布尔值,表示在待办事项模式下是否有选中的项目。
|
|
|
|
|
*/
|
|
|
|
|
private boolean getWorkingText() {
|
|
|
|
|
boolean hasChecked = false;
|
|
|
|
|
//检查当前工作笔记mWorkingNote是否为待办事项模式。如果是,就遍历所有子视图view,其中包含每个待办事项的复选框和文本编辑框。
|
|
|
|
|
// 对于每个非空的文本编辑框,如果其相应的复选框被选中,则将文本内容作为已选中的待办事项添加到字符串缓冲区sb中,并将标记hasChecked设置为true;
|
|
|
|
|
// 否则,将文本内容作为未选中的待办事项添加到字符串缓冲区sb中。
|
|
|
|
|
if (mWorkingNote.getCheckListMode() == TextNote.MODE_CHECK_LIST) {
|
|
|
|
|
StringBuilder sb = new StringBuilder();
|
|
|
|
|
for (int i = 0; i < mEditTextList.getChildCount(); i++) {
|
|
|
|
@ -1345,6 +1575,7 @@ public class NoteEditActivity extends Activity implements OnClickListener,
|
|
|
|
|
sb.append(TAG_CHECKED).append(" ").append(edit.getText()).append("\n");
|
|
|
|
|
hasChecked = true;
|
|
|
|
|
} else {
|
|
|
|
|
//如果不是待办事项模式,则将文本编辑器mNoteEditor中的文本内容设置为工作笔记的文本内容。
|
|
|
|
|
sb.append(TAG_UNCHECKED).append(" ").append(edit.getText()).append("\n");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -1353,12 +1584,16 @@ public class NoteEditActivity extends Activity implements OnClickListener,
|
|
|
|
|
} else {
|
|
|
|
|
mWorkingNote.setWorkingText(mNoteEditor.getText().toString());
|
|
|
|
|
}
|
|
|
|
|
return hasChecked;
|
|
|
|
|
return hasChecked;//该方法返回一个布尔值hasChecked,表示在待办事项模式下是否有选中的项目。
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//用于保存当前正在编辑的笔记。
|
|
|
|
|
private boolean saveNote() {
|
|
|
|
|
//在方法内部,首先调用getWorkingText方法获取当前正在编辑的笔记的文本内容,并将其保存到mWorkingNote对象中。
|
|
|
|
|
getWorkingText();
|
|
|
|
|
boolean saved = mWorkingNote.saveNote();
|
|
|
|
|
//如果保存成功,则调用setResult(RESULT_OK)方法,设置当前Activity的返回状态为RESULT_OK。
|
|
|
|
|
//这个状态用于标识从编辑状态返回到列表视图时,是创建新笔记还是编辑已有笔记。
|
|
|
|
|
if (saved) {
|
|
|
|
|
/**
|
|
|
|
|
* There are two modes from List view to edit view, open one note,
|
|
|
|
@ -1372,30 +1607,34 @@ public class NoteEditActivity extends Activity implements OnClickListener,
|
|
|
|
|
return saved;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//用于将笔记发送到桌面。
|
|
|
|
|
private void sendToDesktop() {
|
|
|
|
|
/**
|
|
|
|
|
* Before send message to home, we should make sure that current
|
|
|
|
|
* editing note is exists in databases. So, for new note, firstly
|
|
|
|
|
* save it
|
|
|
|
|
*/
|
|
|
|
|
//检查当前正在编辑的笔记是否存在于数据库中。如果笔记不存在于数据库中,则调用saveNote()方法保存笔记。
|
|
|
|
|
if (!mWorkingNote.existInDatabase()) {
|
|
|
|
|
saveNote();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (mWorkingNote.getNoteId() > 0) {
|
|
|
|
|
Intent sender = new Intent();
|
|
|
|
|
Intent sender = new Intent();//创建一个Intent对象sender用于发送广播。
|
|
|
|
|
Intent shortcutIntent = new Intent(this, NoteEditActivity.class);
|
|
|
|
|
shortcutIntent.setAction(Intent.ACTION_VIEW);
|
|
|
|
|
shortcutIntent.putExtra(Intent.EXTRA_UID, mWorkingNote.getNoteId());
|
|
|
|
|
shortcutIntent.setAction(Intent.ACTION_VIEW);//创建一个Intent对象shortcutIntent,指定其目标为NoteEditActivity类,并设置动作为Intent.ACTION_VIEW
|
|
|
|
|
shortcutIntent.putExtra(Intent.EXTRA_UID, mWorkingNote.getNoteId());//将正在编辑的笔记ID作为附加数据放入shortcutIntent中。
|
|
|
|
|
//将笔记内容生成适合作为快捷方式图标标题的字符串,并放入sender中作为附加数据。
|
|
|
|
|
sender.putExtra(Intent.EXTRA_SHORTCUT_INTENT, shortcutIntent);
|
|
|
|
|
sender.putExtra(Intent.EXTRA_SHORTCUT_NAME,
|
|
|
|
|
makeShortcutIconTitle(mWorkingNote.getContent()));
|
|
|
|
|
sender.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE,
|
|
|
|
|
Intent.ShortcutIconResource.fromContext(this, R.drawable.icon_app));
|
|
|
|
|
//将应用程序的图标资源作为快捷方式图标放入sender中。
|
|
|
|
|
sender.putExtra("duplicate", true);
|
|
|
|
|
sender.setAction("com.android.launcher.action.INSTALL_SHORTCUT");
|
|
|
|
|
showToast(R.string.info_note_enter_desktop);
|
|
|
|
|
sendBroadcast(sender);
|
|
|
|
|
sender.setAction("com.android.launcher.action.INSTALL_SHORTCUT");//设置sender的动作为com.android.launcher.action.INSTALL_SHORTCUT,表示要安装快捷方式。
|
|
|
|
|
showToast(R.string.info_note_enter_desktop);//弹出一个简短的提示消息,提示用户笔记已经进入桌面。
|
|
|
|
|
sendBroadcast(sender);//发送广播,安装快捷方式。
|
|
|
|
|
} else {
|
|
|
|
|
/**
|
|
|
|
|
* There is the condition that user has input nothing (the note is
|
|
|
|
@ -1404,20 +1643,26 @@ public class NoteEditActivity extends Activity implements OnClickListener,
|
|
|
|
|
*/
|
|
|
|
|
Log.e(TAG, "Send to desktop error");
|
|
|
|
|
showToast(R.string.error_note_empty_for_send_to_desktop);
|
|
|
|
|
//如果当前正在编辑的笔记没有有效的笔记ID,则执行以下操作:
|
|
|
|
|
//输出一个错误日志,表示发送到桌面出错
|
|
|
|
|
//弹出一个提示消息,提醒用户必须输入一些内容才能发送到桌面。
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//用于生成快捷图标的标题
|
|
|
|
|
private String makeShortcutIconTitle(String content) {
|
|
|
|
|
content = content.replace(TAG_CHECKED, "");
|
|
|
|
|
content = content.replace(TAG_CHECKED, "");//使用replace()方法将文本中的所有TAG_CHECKED和TAG_UNCHECKED替换为空字符串,即去除已选中和未选中标记。
|
|
|
|
|
content = content.replace(TAG_UNCHECKED, "");
|
|
|
|
|
return content.length() > SHORTCUT_ICON_TITLE_MAX_LEN ? content.substring(0,
|
|
|
|
|
SHORTCUT_ICON_TITLE_MAX_LEN) : content;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//用于显示一个短时间的 Toast 提示消息
|
|
|
|
|
private void showToast(int resId) {
|
|
|
|
|
showToast(resId, Toast.LENGTH_SHORT);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//用于显示一个指定时长的 Toast 提示消息
|
|
|
|
|
private void showToast(int resId, int duration) {
|
|
|
|
|
Toast.makeText(this, resId, duration).show();
|
|
|
|
|
}
|
|
|
|
|