|
|
|
@ -86,9 +86,10 @@ import java.util.Map;
|
|
|
|
|
import java.util.regex.Matcher;
|
|
|
|
|
import java.util.regex.Pattern;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//便签编辑活动
|
|
|
|
|
public class NoteEditActivity extends AppCompatActivity implements OnClickListener,
|
|
|
|
|
NoteSettingChangedListener, OnTextViewChangeListener {
|
|
|
|
|
//存放便签编辑页面顶部四个组件的内部类
|
|
|
|
|
private class HeadViewHolder {
|
|
|
|
|
public TextView tvModified;
|
|
|
|
|
|
|
|
|
@ -98,7 +99,7 @@ public class NoteEditActivity extends AppCompatActivity implements OnClickListen
|
|
|
|
|
|
|
|
|
|
public ImageView ibSetBgColor;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//存储背景颜色图标id的Map
|
|
|
|
|
private static final Map<Integer, Integer> sBgSelectorBtnsMap = new HashMap<Integer, Integer>();
|
|
|
|
|
static {
|
|
|
|
|
sBgSelectorBtnsMap.put(R.id.iv_bg_yellow, ResourceParser.YELLOW);
|
|
|
|
@ -107,7 +108,7 @@ public class NoteEditActivity extends AppCompatActivity implements OnClickListen
|
|
|
|
|
sBgSelectorBtnsMap.put(R.id.iv_bg_green, ResourceParser.GREEN);
|
|
|
|
|
sBgSelectorBtnsMap.put(R.id.iv_bg_white, ResourceParser.WHITE);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//存储背景颜色图标下方勾选图标id的Map
|
|
|
|
|
private static final Map<Integer, Integer> sBgSelectorSelectionMap = new HashMap<Integer, Integer>();
|
|
|
|
|
static {
|
|
|
|
|
sBgSelectorSelectionMap.put(ResourceParser.YELLOW, R.id.iv_bg_yellow_select);
|
|
|
|
@ -116,7 +117,7 @@ public class NoteEditActivity extends AppCompatActivity implements OnClickListen
|
|
|
|
|
sBgSelectorSelectionMap.put(ResourceParser.GREEN, R.id.iv_bg_green_select);
|
|
|
|
|
sBgSelectorSelectionMap.put(ResourceParser.WHITE, R.id.iv_bg_white_select);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//存储每一个字体选择布局id的Map
|
|
|
|
|
private static final Map<Integer, Integer> sFontSizeBtnsMap = new HashMap<Integer, Integer>();
|
|
|
|
|
static {
|
|
|
|
|
sFontSizeBtnsMap.put(R.id.ll_font_large, ResourceParser.TEXT_LARGE);
|
|
|
|
@ -124,7 +125,7 @@ public class NoteEditActivity extends AppCompatActivity implements OnClickListen
|
|
|
|
|
sFontSizeBtnsMap.put(R.id.ll_font_normal, ResourceParser.TEXT_MEDIUM);
|
|
|
|
|
sFontSizeBtnsMap.put(R.id.ll_font_super, ResourceParser.TEXT_SUPER);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//存储字体大小图标旁边勾选图标id的Map
|
|
|
|
|
private static final Map<Integer, Integer> sFontSelectorSelectionMap = new HashMap<Integer, Integer>();
|
|
|
|
|
static {
|
|
|
|
|
sFontSelectorSelectionMap.put(ResourceParser.TEXT_LARGE, R.id.iv_large_select);
|
|
|
|
@ -155,8 +156,9 @@ public class NoteEditActivity extends AppCompatActivity implements OnClickListen
|
|
|
|
|
private static final String PREFERENCE_FONT_SIZE = "pref_font_size";
|
|
|
|
|
|
|
|
|
|
private static final int SHORTCUT_ICON_TITLE_MAX_LEN = 10;
|
|
|
|
|
|
|
|
|
|
//勾型符号
|
|
|
|
|
public static final String TAG_CHECKED = String.valueOf('\u221A');
|
|
|
|
|
//空心方形符号
|
|
|
|
|
public static final String TAG_UNCHECKED = String.valueOf('\u25A1');
|
|
|
|
|
|
|
|
|
|
private LinearLayout mEditTextList;
|
|
|
|
@ -167,12 +169,14 @@ public class NoteEditActivity extends AppCompatActivity implements OnClickListen
|
|
|
|
|
@Override
|
|
|
|
|
protected void onCreate(Bundle savedInstanceState) {
|
|
|
|
|
super.onCreate(savedInstanceState);
|
|
|
|
|
//加载便签编辑页面布局
|
|
|
|
|
this.setContentView(R.layout.note_edit);
|
|
|
|
|
|
|
|
|
|
if (savedInstanceState == null && !initActivityState(getIntent())) {
|
|
|
|
|
finish();
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
//初始化活动中的资源,包括各种组件等
|
|
|
|
|
initResources();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -180,12 +184,16 @@ public class NoteEditActivity extends AppCompatActivity implements OnClickListen
|
|
|
|
|
* Current activity may be killed when the memory is low. Once it is killed, for another time
|
|
|
|
|
* user load this activity, we should restore the former state
|
|
|
|
|
*/
|
|
|
|
|
//进程被系统gc回收后,若是再次启动,调用该方法,读取之前保存的数据
|
|
|
|
|
@Override
|
|
|
|
|
protected void onRestoreInstanceState(Bundle savedInstanceState) {
|
|
|
|
|
super.onRestoreInstanceState(savedInstanceState);
|
|
|
|
|
//首先判断进程被回收前是否保存了数据
|
|
|
|
|
if (savedInstanceState != null && savedInstanceState.containsKey(Intent.EXTRA_UID)) {
|
|
|
|
|
Intent intent = new Intent(Intent.ACTION_VIEW);
|
|
|
|
|
//保存便签的ID
|
|
|
|
|
intent.putExtra(Intent.EXTRA_UID, savedInstanceState.getLong(Intent.EXTRA_UID));
|
|
|
|
|
//初始化内容
|
|
|
|
|
if (!initActivityState(intent)) {
|
|
|
|
|
finish();
|
|
|
|
|
return;
|
|
|
|
@ -200,35 +208,46 @@ public class NoteEditActivity extends AppCompatActivity implements OnClickListen
|
|
|
|
|
* then jump to the NotesListActivity
|
|
|
|
|
*/
|
|
|
|
|
mWorkingNote = null;
|
|
|
|
|
//判断活动启动的方式,是否为Intent.ACTION_VIEW类型,即为直接打开一个便签
|
|
|
|
|
if (TextUtils.equals(Intent.ACTION_VIEW, intent.getAction())) {
|
|
|
|
|
//读取NotesListActivity传来的便签id,若是没有则为0
|
|
|
|
|
long noteId = intent.getLongExtra(Intent.EXTRA_UID, 0);
|
|
|
|
|
mUserQuery = "";
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Starting from the searched result
|
|
|
|
|
*/
|
|
|
|
|
//判断用户是否是通过搜索后打开便签
|
|
|
|
|
if (intent.hasExtra(SearchManager.EXTRA_DATA_KEY)) {
|
|
|
|
|
//读取便签id
|
|
|
|
|
noteId = Long.parseLong(intent.getStringExtra(SearchManager.EXTRA_DATA_KEY));
|
|
|
|
|
mUserQuery = intent.getStringExtra(SearchManager.USER_QUERY);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//若是没有查找到对应的便签,则说明便签不存在,直接结束该活动
|
|
|
|
|
if (!DataUtils.visibleInNoteDatabase(getContentResolver(), noteId, Notes.TYPE_NOTE)) {
|
|
|
|
|
//跳转到便签列表活动,即NotesListActivity
|
|
|
|
|
Intent jump = new Intent(this, NotesListActivity.class);
|
|
|
|
|
startActivity(jump);
|
|
|
|
|
//显示便签不存在
|
|
|
|
|
showToast(R.string.error_note_not_exist);
|
|
|
|
|
//结束该活动
|
|
|
|
|
finish();
|
|
|
|
|
return false;
|
|
|
|
|
} else {
|
|
|
|
|
//加载对应id的便签
|
|
|
|
|
mWorkingNote = WorkingNote.load(this, noteId);
|
|
|
|
|
//判断是否加载成功
|
|
|
|
|
if (mWorkingNote == null) {
|
|
|
|
|
Log.e(TAG, "load note failed with note id" + noteId);
|
|
|
|
|
finish();
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
//调整软盘布局,当用户进入活动时隐藏软盘,当输入法显示时,允许窗口重新计算尺寸,使内容不被输入法所覆盖
|
|
|
|
|
getWindow().setSoftInputMode(
|
|
|
|
|
WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN
|
|
|
|
|
| WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
|
|
|
|
|
//判断活动启动的方式,是否为Intent.ACTION_INSERT_OR_EDIT类型,即为创建一个便签
|
|
|
|
|
} else if(TextUtils.equals(Intent.ACTION_INSERT_OR_EDIT, intent.getAction())) {
|
|
|
|
|
// New note
|
|
|
|
|
long folderId = intent.getLongExtra(Notes.INTENT_EXTRA_FOLDER_ID, 0);
|
|
|
|
@ -264,7 +283,7 @@ public class NoteEditActivity extends AppCompatActivity implements OnClickListen
|
|
|
|
|
mWorkingNote = WorkingNote.createEmptyNote(this, folderId, widgetId, widgetType,
|
|
|
|
|
bgResId);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//调整软盘布局,当用户进入活动时显示软盘,并且允许窗口重新计算尺寸,使内容不被输入法所覆盖
|
|
|
|
|
getWindow().setSoftInputMode(
|
|
|
|
|
WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE
|
|
|
|
|
| WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);
|
|
|
|
@ -273,10 +292,12 @@ public class NoteEditActivity extends AppCompatActivity implements OnClickListen
|
|
|
|
|
finish();
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
//为便签设置项设置监听
|
|
|
|
|
mWorkingNote.setOnSettingStatusChangedListener(this);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//activity生命周期回调方法
|
|
|
|
|
@Override
|
|
|
|
|
protected void onResume() {
|
|
|
|
|
super.onResume();
|
|
|
|
@ -284,20 +305,26 @@ public class NoteEditActivity extends AppCompatActivity implements OnClickListen
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void initNoteScreen() {
|
|
|
|
|
//设置便签内容字体的外观
|
|
|
|
|
mNoteEditor.setTextAppearance(this, TextAppearanceResources
|
|
|
|
|
.getTexAppearanceResource(mFontSizeId));
|
|
|
|
|
//判断是否是清单模式
|
|
|
|
|
if (mWorkingNote.getCheckListMode() == TextNote.MODE_CHECK_LIST) {
|
|
|
|
|
switchToListMode(mWorkingNote.getContent());
|
|
|
|
|
} else {
|
|
|
|
|
//设置编辑区域便签的初始内容(内容经过处理)
|
|
|
|
|
mNoteEditor.setText(getHighlightQueryResult(mWorkingNote.getContent(), mUserQuery));
|
|
|
|
|
//设置EditText中光标位置
|
|
|
|
|
mNoteEditor.setSelection(mNoteEditor.getText().length());
|
|
|
|
|
}
|
|
|
|
|
//设置背景颜色选择下方的勾选图标不可见
|
|
|
|
|
for (Integer id : sBgSelectorSelectionMap.keySet()) {
|
|
|
|
|
findViewById(sBgSelectorSelectionMap.get(id)).setVisibility(View.GONE);
|
|
|
|
|
}
|
|
|
|
|
//设置便签编辑页面编辑区域和头部的背景颜色
|
|
|
|
|
mHeadViewPanel.setBackgroundResource(mWorkingNote.getTitleBgResId());
|
|
|
|
|
mNoteEditorPanel.setBackgroundResource(mWorkingNote.getBgColorResId());
|
|
|
|
|
|
|
|
|
|
//设置便签编辑页面头部显示的时间
|
|
|
|
|
mNoteHeaderHolder.tvModified.setText(DateUtils.formatDateTime(this,
|
|
|
|
|
mWorkingNote.getModifiedDate(), DateUtils.FORMAT_SHOW_DATE
|
|
|
|
|
| DateUtils.FORMAT_NUMERIC_DATE | DateUtils.FORMAT_SHOW_TIME
|
|
|
|
@ -310,19 +337,29 @@ public class NoteEditActivity extends AppCompatActivity implements OnClickListen
|
|
|
|
|
showAlertHeader();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//设置显示定时提醒
|
|
|
|
|
private void showAlertHeader() {
|
|
|
|
|
//判断便签是否设置定时提醒
|
|
|
|
|
if (mWorkingNote.hasClockAlert()) {
|
|
|
|
|
//获取系统当前时间
|
|
|
|
|
long time = System.currentTimeMillis();
|
|
|
|
|
//判断当前时间是否超过了设置的提醒时间
|
|
|
|
|
if (time > mWorkingNote.getAlertDate()) {
|
|
|
|
|
//设置显示提醒时间的TextView显示"已过期"
|
|
|
|
|
mNoteHeaderHolder.tvAlertDate.setText(R.string.note_alert_expired);
|
|
|
|
|
} else {
|
|
|
|
|
//设置显示提醒时间的TextView显示设置时间距离现在的时长
|
|
|
|
|
mNoteHeaderHolder.tvAlertDate.setText(DateUtils.getRelativeTimeSpanString(
|
|
|
|
|
mWorkingNote.getAlertDate(), time, DateUtils.MINUTE_IN_MILLIS));
|
|
|
|
|
}
|
|
|
|
|
//设置显示提醒时间的TextView可见
|
|
|
|
|
mNoteHeaderHolder.tvAlertDate.setVisibility(View.VISIBLE);
|
|
|
|
|
//设置显示提醒时间的TextView旁边的闹钟图标可见
|
|
|
|
|
mNoteHeaderHolder.ivAlertIcon.setVisibility(View.VISIBLE);
|
|
|
|
|
} else {
|
|
|
|
|
//设置显示提醒时间的TextView不可见
|
|
|
|
|
mNoteHeaderHolder.tvAlertDate.setVisibility(View.GONE);
|
|
|
|
|
//设置显示提醒时间的TextView旁边的闹钟图标不可见
|
|
|
|
|
mNoteHeaderHolder.ivAlertIcon.setVisibility(View.GONE);
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
@ -333,6 +370,7 @@ public class NoteEditActivity extends AppCompatActivity implements OnClickListen
|
|
|
|
|
initActivityState(intent);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//进程被杀死或者结束前,调用该方法进行数据保存,防止程序因内存不足被杀死而丢失数据
|
|
|
|
|
@Override
|
|
|
|
|
protected void onSaveInstanceState(Bundle outState) {
|
|
|
|
|
super.onSaveInstanceState(outState);
|
|
|
|
@ -341,21 +379,26 @@ public class NoteEditActivity extends AppCompatActivity implements OnClickListen
|
|
|
|
|
* generate a id. If the editing note is not worth saving, there
|
|
|
|
|
* is no id which is equivalent to create new note
|
|
|
|
|
*/
|
|
|
|
|
//对于新建的便签,在没保存之前是没有id的,为了得到它的id,将其先保存
|
|
|
|
|
if (!mWorkingNote.existInDatabase()) {
|
|
|
|
|
saveNote();
|
|
|
|
|
}
|
|
|
|
|
//保存便签的id
|
|
|
|
|
outState.putLong(Intent.EXTRA_UID, mWorkingNote.getNoteId());
|
|
|
|
|
Log.d(TAG, "Save working note id: " + mWorkingNote.getNoteId() + " onSaveInstanceState");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//设置触摸事件
|
|
|
|
|
@Override
|
|
|
|
|
public boolean dispatchTouchEvent(MotionEvent ev) {
|
|
|
|
|
//当具体的背景颜色选择界面可见并且点击事件并不在该View中时,将具体的背景颜色选择界面设置不可见
|
|
|
|
|
if (mNoteBgColorSelector.getVisibility() == View.VISIBLE
|
|
|
|
|
&& !inRangeOfView(mNoteBgColorSelector, ev)) {
|
|
|
|
|
//
|
|
|
|
|
mNoteBgColorSelector.setVisibility(View.GONE);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//当具体的字体大小选择界面可见并且点击事件并不在该View中时,将具体的字体大小选择界面设置不可见
|
|
|
|
|
if (mFontSizeSelector.getVisibility() == View.VISIBLE
|
|
|
|
|
&& !inRangeOfView(mFontSizeSelector, ev)) {
|
|
|
|
|
mFontSizeSelector.setVisibility(View.GONE);
|
|
|
|
@ -364,6 +407,7 @@ public class NoteEditActivity extends AppCompatActivity implements OnClickListen
|
|
|
|
|
return super.dispatchTouchEvent(ev);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//返回时间发生的位置是否在某个视图内的boolean
|
|
|
|
|
private boolean inRangeOfView(View view, MotionEvent ev) {
|
|
|
|
|
int []location = new int[2];
|
|
|
|
|
view.getLocationOnScreen(location);
|
|
|
|
@ -379,45 +423,63 @@ public class NoteEditActivity extends AppCompatActivity implements OnClickListen
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void initResources() {
|
|
|
|
|
//获取编辑页面头部布局,为一个LinearLayout
|
|
|
|
|
mHeadViewPanel = findViewById(R.id.note_title);
|
|
|
|
|
//创建一个存放头部布局里面四个组件的容器
|
|
|
|
|
mNoteHeaderHolder = new HeadViewHolder();
|
|
|
|
|
//获取第一个组件,即为一个TextView,即用来显示最近更新时间
|
|
|
|
|
mNoteHeaderHolder.tvModified = (TextView) findViewById(R.id.tv_modified_date);
|
|
|
|
|
//获取第二个组件,即为一个ImageView,显示闹钟图标
|
|
|
|
|
mNoteHeaderHolder.ivAlertIcon = (ImageView) findViewById(R.id.iv_alert_icon);
|
|
|
|
|
//获取第三个组件,即为一个TextView,即用来显示闹钟提醒时间,即为距现在还有多长时间
|
|
|
|
|
mNoteHeaderHolder.tvAlertDate = (TextView) findViewById(R.id.tv_alert_date);
|
|
|
|
|
//获取第四个组件,为一个ImageButton,即为用来切换便签背景的按钮
|
|
|
|
|
mNoteHeaderHolder.ibSetBgColor = (ImageView) findViewById(R.id.btn_set_bg_color);
|
|
|
|
|
//为切换便签背景的按钮设置监听
|
|
|
|
|
mNoteHeaderHolder.ibSetBgColor.setOnClickListener(this);
|
|
|
|
|
//获取便签编辑区域EditText
|
|
|
|
|
mNoteEditor = (EditText) findViewById(R.id.note_edit_view);
|
|
|
|
|
//获取便签编辑区域整体布局,为一个LinearLayout
|
|
|
|
|
mNoteEditorPanel = findViewById(R.id.sv_note_edit);
|
|
|
|
|
//获取具体背景选择的布局,为一个LinearLayout
|
|
|
|
|
mNoteBgColorSelector = findViewById(R.id.note_bg_color_selector);
|
|
|
|
|
//遍历每一个可选的背景图标,并为其设置监听
|
|
|
|
|
for (int id : sBgSelectorBtnsMap.keySet()) {
|
|
|
|
|
ImageView iv = (ImageView) findViewById(id);
|
|
|
|
|
iv.setOnClickListener(this);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//获取具体字体大小选择的布局,为一个LinearLayout
|
|
|
|
|
mFontSizeSelector = findViewById(R.id.font_size_selector);
|
|
|
|
|
//获取每一个存放可选字体图标的布局,为FrameLayout,并为其设置监听
|
|
|
|
|
for (int id : sFontSizeBtnsMap.keySet()) {
|
|
|
|
|
View view = findViewById(id);
|
|
|
|
|
view.setOnClickListener(this);
|
|
|
|
|
};
|
|
|
|
|
//可以获得整个应用程序的默认共享首选项文件,无需加名字,以我们 App 的包名加 _preferences 并以 xml 的格式保存在 /data/data/包名/shared_prefs/下
|
|
|
|
|
mSharedPrefs = PreferenceManager.getDefaultSharedPreferences(this);
|
|
|
|
|
//读取保存的字体大小的id(即为数组中的位置),存在默认值,为BG_DEFAULT_FONT_SIZE
|
|
|
|
|
mFontSizeId = mSharedPrefs.getInt(PREFERENCE_FONT_SIZE, ResourceParser.BG_DEFAULT_FONT_SIZE);
|
|
|
|
|
/**
|
|
|
|
|
* HACKME: Fix bug of store the resource id in shared preference.
|
|
|
|
|
* The id may larger than the length of resources, in this case,
|
|
|
|
|
* return the {@link ResourceParser#BG_DEFAULT_FONT_SIZE}
|
|
|
|
|
*/
|
|
|
|
|
//判断读取的字体大小的id(即为数组中的位置)是否超过存放字体大小数组的长度,如果超过了该长度,则字体大小的id设置为默认值
|
|
|
|
|
if(mFontSizeId >= TextAppearanceResources.getResourcesSize()) {
|
|
|
|
|
mFontSizeId = ResourceParser.BG_DEFAULT_FONT_SIZE;
|
|
|
|
|
}
|
|
|
|
|
//获取清单模式下存放每一个行布局的容器,为一个LinearLayout
|
|
|
|
|
mEditTextList = (LinearLayout) findViewById(R.id.note_edit_list);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
protected void onPause() {
|
|
|
|
|
super.onPause();
|
|
|
|
|
//保存便签相关信息
|
|
|
|
|
if(saveNote()) {
|
|
|
|
|
Log.d(TAG, "Note data was saved with length:" + mWorkingNote.getContent().length());
|
|
|
|
|
}
|
|
|
|
|
//清理界面的背景颜色选择界面或者字体大小选择界面,将其设置为不可见,即为GONE
|
|
|
|
|
clearSettingState();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -440,79 +502,113 @@ public class NoteEditActivity extends AppCompatActivity implements OnClickListen
|
|
|
|
|
setResult(RESULT_OK, intent);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//重写OnClickListener中的onclick方法
|
|
|
|
|
@SuppressLint("WrongConstant")
|
|
|
|
|
public void onClick(View v) {
|
|
|
|
|
//获取点击的View的id
|
|
|
|
|
int id = v.getId();
|
|
|
|
|
if (id == R.id.btn_set_bg_color) {
|
|
|
|
|
//设置存储便签背景选择的布局可见
|
|
|
|
|
mNoteBgColorSelector.setVisibility(View.VISIBLE);
|
|
|
|
|
//设置当前便签已选定的颜色图标下方的勾选图标可见
|
|
|
|
|
findViewById(sBgSelectorSelectionMap.get(mWorkingNote.getBgColorId())).setVisibility(
|
|
|
|
|
- View.VISIBLE);
|
|
|
|
|
//判断点击的是否时展开背景选择后的具体的选择颜色的View
|
|
|
|
|
} else if (sBgSelectorBtnsMap.containsKey(id)) {
|
|
|
|
|
//取消先前已选定的颜色下方的勾选图标
|
|
|
|
|
findViewById(sBgSelectorSelectionMap.get(mWorkingNote.getBgColorId())).setVisibility(
|
|
|
|
|
View.GONE);
|
|
|
|
|
//重新设置便签的颜色属性,即保存对应颜色的id
|
|
|
|
|
mWorkingNote.setBgColorId(sBgSelectorBtnsMap.get(id));
|
|
|
|
|
//设置背景选择不可见
|
|
|
|
|
mNoteBgColorSelector.setVisibility(View.GONE);
|
|
|
|
|
//判断点击的是否是展开字体大小选择后的具体的一个字体选择View
|
|
|
|
|
} else if (sFontSizeBtnsMap.containsKey(id)) {
|
|
|
|
|
//取消先前已选定的字体大小旁边的勾选图标
|
|
|
|
|
findViewById(sFontSelectorSelectionMap.get(mFontSizeId)).setVisibility(View.GONE);
|
|
|
|
|
//从Map中读出选择的字体大小对应的id
|
|
|
|
|
mFontSizeId = sFontSizeBtnsMap.get(id);
|
|
|
|
|
//将字体大小写入应用首选的SharedPreferences文件中
|
|
|
|
|
mSharedPrefs.edit().putInt(PREFERENCE_FONT_SIZE, mFontSizeId).commit();
|
|
|
|
|
//将选中的字体大小图标旁边的勾选符设置为可见
|
|
|
|
|
findViewById(sFontSelectorSelectionMap.get(mFontSizeId)).setVisibility(View.VISIBLE);
|
|
|
|
|
//判断当前是否是清单模式
|
|
|
|
|
if (mWorkingNote.getCheckListMode() == TextNote.MODE_CHECK_LIST) {
|
|
|
|
|
//对便签内容进行处理和保存
|
|
|
|
|
getWorkingText();
|
|
|
|
|
//传入便签内容,切换到清单模式
|
|
|
|
|
switchToListMode(mWorkingNote.getContent());
|
|
|
|
|
} else {
|
|
|
|
|
//非清单模式时设置字体的样式
|
|
|
|
|
mNoteEditor.setTextAppearance(this,
|
|
|
|
|
TextAppearanceResources.getTexAppearanceResource(mFontSizeId));
|
|
|
|
|
}
|
|
|
|
|
//将具体字体选择界面设置为不可见
|
|
|
|
|
mFontSizeSelector.setVisibility(View.GONE);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//按返回键时执行的操作
|
|
|
|
|
@Override
|
|
|
|
|
public void onBackPressed() {
|
|
|
|
|
//首先处理界面内展开的选项,如背景选择、字体大小选择
|
|
|
|
|
if(clearSettingState()) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//在上述都处理完后,点击后销毁该活动,在该操作前保存便签相关内容
|
|
|
|
|
saveNote();
|
|
|
|
|
super.onBackPressed();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//清理界面的背景颜色选择界面或者字体大小选择界面,将其设置为不可见,即为GONE
|
|
|
|
|
private boolean clearSettingState() {
|
|
|
|
|
//判断便签背景选择是否可见
|
|
|
|
|
if (mNoteBgColorSelector.getVisibility() == View.VISIBLE) {
|
|
|
|
|
//便签背景选择设置为不可见
|
|
|
|
|
mNoteBgColorSelector.setVisibility(View.GONE);
|
|
|
|
|
return true;
|
|
|
|
|
//判断字体大小选择是否可见
|
|
|
|
|
} else if (mFontSizeSelector.getVisibility() == View.VISIBLE) {
|
|
|
|
|
//设置字体大小选择不可见
|
|
|
|
|
mFontSizeSelector.setVisibility(View.GONE);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//便签背景颜色发生改变时调用
|
|
|
|
|
public void onBackgroundColorChanged() {
|
|
|
|
|
//设置便签选的颜色下方的勾选符号可见
|
|
|
|
|
findViewById(sBgSelectorSelectionMap.get(mWorkingNote.getBgColorId())).setVisibility(
|
|
|
|
|
View.VISIBLE);
|
|
|
|
|
//设置便签编辑区域的颜色
|
|
|
|
|
mNoteEditorPanel.setBackgroundResource(mWorkingNote.getBgColorResId());
|
|
|
|
|
//设置便签编辑区域上方头部的颜色
|
|
|
|
|
mHeadViewPanel.setBackgroundResource(mWorkingNote.getTitleBgResId());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//点击menu时调用,用于显示menu内容
|
|
|
|
|
@Override
|
|
|
|
|
public boolean onPrepareOptionsMenu(Menu menu) {
|
|
|
|
|
//首先判断activity是否处于活跃状态
|
|
|
|
|
if (isFinishing()) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
//点击菜单生效前先,清理界面的背景颜色选择界面或者字体大小选择界面
|
|
|
|
|
clearSettingState();
|
|
|
|
|
menu.clear();
|
|
|
|
|
//根据FolderId加载不同的菜单布局
|
|
|
|
|
if (mWorkingNote.getFolderId() == Notes.ID_CALL_RECORD_FOLDER) {
|
|
|
|
|
getMenuInflater().inflate(R.menu.call_note_edit, menu);
|
|
|
|
|
} else {
|
|
|
|
|
getMenuInflater().inflate(R.menu.note_edit, menu);
|
|
|
|
|
}
|
|
|
|
|
//如果当前模式是清单模式,则菜单中应该显示退出清单模式,否则应该显示进入清单模式
|
|
|
|
|
if (mWorkingNote.getCheckListMode() == TextNote.MODE_CHECK_LIST) {
|
|
|
|
|
menu.findItem(R.id.menu_list_mode).setTitle(R.string.menu_normal_mode);
|
|
|
|
|
} else {
|
|
|
|
|
menu.findItem(R.id.menu_list_mode).setTitle(R.string.menu_list_mode);
|
|
|
|
|
}
|
|
|
|
|
//如果当前便签有闹钟提醒,则菜单中应该只显示删除提醒,否则应该只显示提醒我
|
|
|
|
|
if (mWorkingNote.hasClockAlert()) {
|
|
|
|
|
menu.findItem(R.id.menu_alert).setVisible(false);
|
|
|
|
|
} else {
|
|
|
|
@ -521,14 +617,19 @@ public class NoteEditActivity extends AppCompatActivity implements OnClickListen
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//菜单项监听
|
|
|
|
|
@RequiresApi(api = Build.VERSION_CODES.O)
|
|
|
|
|
@Override
|
|
|
|
|
public boolean onOptionsItemSelected(MenuItem item) {
|
|
|
|
|
switch (item.getItemId()) {
|
|
|
|
|
//点击新建便签,则会新建一个便签
|
|
|
|
|
case R.id.menu_new_note:
|
|
|
|
|
createNewNote();
|
|
|
|
|
break;
|
|
|
|
|
//点击删除
|
|
|
|
|
case 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);
|
|
|
|
@ -536,7 +637,9 @@ public class NoteEditActivity extends AppCompatActivity implements OnClickListen
|
|
|
|
|
builder.setPositiveButton(android.R.string.ok,
|
|
|
|
|
new DialogInterface.OnClickListener() {
|
|
|
|
|
public void onClick(DialogInterface dialog, int which) {
|
|
|
|
|
//删除便签方法
|
|
|
|
|
deleteCurrentNote();
|
|
|
|
|
//结束当前活动
|
|
|
|
|
finish();
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
@ -544,24 +647,32 @@ public class NoteEditActivity extends AppCompatActivity implements OnClickListen
|
|
|
|
|
builder.show();
|
|
|
|
|
break;
|
|
|
|
|
case R.id.menu_font_size:
|
|
|
|
|
//设置字体选择界面可见
|
|
|
|
|
mFontSizeSelector.setVisibility(View.VISIBLE);
|
|
|
|
|
//初始时选中之前选择过的字体
|
|
|
|
|
findViewById(sFontSelectorSelectionMap.get(mFontSizeId)).setVisibility(View.VISIBLE);
|
|
|
|
|
break;
|
|
|
|
|
case R.id.menu_list_mode:
|
|
|
|
|
//便签设置查看模式
|
|
|
|
|
mWorkingNote.setCheckListMode(mWorkingNote.getCheckListMode() == 0 ?
|
|
|
|
|
TextNote.MODE_CHECK_LIST : 0);
|
|
|
|
|
break;
|
|
|
|
|
case R.id.menu_share:
|
|
|
|
|
//通过该方法先对便签内容进行处理、保存
|
|
|
|
|
getWorkingText();
|
|
|
|
|
//分享便签内容
|
|
|
|
|
sendTo(this, mWorkingNote.getContent());
|
|
|
|
|
break;
|
|
|
|
|
case R.id.menu_send_to_desktop:
|
|
|
|
|
//便签发送到桌面方法
|
|
|
|
|
sendToDesktop();
|
|
|
|
|
break;
|
|
|
|
|
case R.id.menu_alert:
|
|
|
|
|
//设置便签提醒时间
|
|
|
|
|
setReminder();
|
|
|
|
|
break;
|
|
|
|
|
case R.id.menu_delete_remind:
|
|
|
|
|
//设置便签提醒时间为0,即删除该提醒
|
|
|
|
|
mWorkingNote.setAlertDate(0, false);
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
@ -571,9 +682,12 @@ public class NoteEditActivity extends AppCompatActivity implements OnClickListen
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void setReminder() {
|
|
|
|
|
//创建一个时间选择对话框
|
|
|
|
|
DateTimePickerDialog d = new DateTimePickerDialog(this, System.currentTimeMillis());
|
|
|
|
|
//注册时间选择监听
|
|
|
|
|
d.setOnDateTimeSetListener(new OnDateTimeSetListener() {
|
|
|
|
|
public void OnDateTimeSet(AlertDialog dialog, long date) {
|
|
|
|
|
//便签设置提醒时间
|
|
|
|
|
mWorkingNote.setAlertDate(date , true);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
@ -584,7 +698,9 @@ public class NoteEditActivity extends AppCompatActivity implements OnClickListen
|
|
|
|
|
* Share note to apps that support {@link Intent#ACTION_SEND} action
|
|
|
|
|
* and {@text/plain} type
|
|
|
|
|
*/
|
|
|
|
|
//分享便签内容方法
|
|
|
|
|
private void sendTo(Context context, String info) {
|
|
|
|
|
//根据Intent意图自动创建活动,这里为创建一个系统活动
|
|
|
|
|
Intent intent = new Intent(Intent.ACTION_SEND);
|
|
|
|
|
intent.putExtra(Intent.EXTRA_TEXT, info);
|
|
|
|
|
intent.setType("text/plain");
|
|
|
|
@ -593,19 +709,24 @@ public class NoteEditActivity extends AppCompatActivity implements OnClickListen
|
|
|
|
|
|
|
|
|
|
private void createNewNote() {
|
|
|
|
|
// Firstly, save current editing notes
|
|
|
|
|
//保存当前便签相关内容
|
|
|
|
|
saveNote();
|
|
|
|
|
|
|
|
|
|
// For safety, start a new NoteEditActivity
|
|
|
|
|
//结束当前活动
|
|
|
|
|
finish();
|
|
|
|
|
//创建一个新的便签编辑活动
|
|
|
|
|
Intent intent = new Intent(this, NoteEditActivity.class);
|
|
|
|
|
intent.setAction(Intent.ACTION_INSERT_OR_EDIT);
|
|
|
|
|
intent.putExtra(Notes.INTENT_EXTRA_FOLDER_ID, mWorkingNote.getFolderId());
|
|
|
|
|
startActivity(intent);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//删除便签方法
|
|
|
|
|
private void deleteCurrentNote() {
|
|
|
|
|
//先判断当前便签是否已经保存
|
|
|
|
|
if (mWorkingNote.existInDatabase()) {
|
|
|
|
|
HashSet<Long> ids = new HashSet<Long>();
|
|
|
|
|
//获取便签id
|
|
|
|
|
long id = mWorkingNote.getNoteId();
|
|
|
|
|
if (id != Notes.ID_ROOT_FOLDER) {
|
|
|
|
|
ids.add(id);
|
|
|
|
@ -628,24 +749,31 @@ public class NoteEditActivity extends AppCompatActivity implements OnClickListen
|
|
|
|
|
private boolean isSyncMode() {
|
|
|
|
|
return NotesPreferenceActivity.getSyncAccountName(this).trim().length() > 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//便签提醒状态发生改变时调用该方法
|
|
|
|
|
public void onClockAlertChanged(long date, boolean set) {
|
|
|
|
|
/**
|
|
|
|
|
* User could set clock to an unsaved note, so before setting the
|
|
|
|
|
* alert clock, we should save the note first
|
|
|
|
|
*/
|
|
|
|
|
//如果便签没有保存,先保存
|
|
|
|
|
if (!mWorkingNote.existInDatabase()) {
|
|
|
|
|
saveNote();
|
|
|
|
|
}
|
|
|
|
|
if (mWorkingNote.getNoteId() > 0) {
|
|
|
|
|
Intent intent = new Intent(this, AlarmReceiver.class);
|
|
|
|
|
//保存便签内容的uri,便于后续查找
|
|
|
|
|
intent.setData(ContentUris.withAppendedId(Notes.CONTENT_NOTE_URI, mWorkingNote.getNoteId()));
|
|
|
|
|
//pendingIntent封装具体执行的intent
|
|
|
|
|
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, intent, 0);
|
|
|
|
|
//获取系统服务
|
|
|
|
|
AlarmManager alarmManager = ((AlarmManager) getSystemService(ALARM_SERVICE));
|
|
|
|
|
showAlertHeader();
|
|
|
|
|
//根据用户具体选择,
|
|
|
|
|
if(!set) {
|
|
|
|
|
//取消定时任务
|
|
|
|
|
alarmManager.cancel(pendingIntent);
|
|
|
|
|
} else {
|
|
|
|
|
//设置单次定时任务
|
|
|
|
|
alarmManager.set(AlarmManager.RTC_WAKEUP, date, pendingIntent);
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
@ -655,6 +783,7 @@ public class NoteEditActivity extends AppCompatActivity implements OnClickListen
|
|
|
|
|
* should input something
|
|
|
|
|
*/
|
|
|
|
|
Log.e(TAG, "Clock alert setting error");
|
|
|
|
|
//输出提示消息
|
|
|
|
|
showToast(R.string.error_note_empty_for_clock);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -662,20 +791,23 @@ public class NoteEditActivity extends AppCompatActivity implements OnClickListen
|
|
|
|
|
public void onWidgetChanged() {
|
|
|
|
|
updateWidget();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//清单模式下删除便签内容时调用
|
|
|
|
|
public void onEditTextDelete(int index, String text) {
|
|
|
|
|
//获取清单模式下便签中总共有多少个行编辑布局,即有多少“行”
|
|
|
|
|
int childCount = mEditTextList.getChildCount();
|
|
|
|
|
//当只有一个行布局时,不再允许删除
|
|
|
|
|
if (childCount == 1) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//重新调整删除便签中一行(即一个行布局)之后的所有行的位置
|
|
|
|
|
for (int i = index + 1; i < childCount; i++) {
|
|
|
|
|
((NoteEditText) mEditTextList.getChildAt(i).findViewById(R.id.et_edit_text))
|
|
|
|
|
.setIndex(i - 1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//移除删除的行布局
|
|
|
|
|
mEditTextList.removeViewAt(index);
|
|
|
|
|
NoteEditText edit = null;
|
|
|
|
|
//获取删除的便签行布局的前一个行布局中的EditText,处理index为0的特殊情况
|
|
|
|
|
if(index == 0) {
|
|
|
|
|
edit = (NoteEditText) mEditTextList.getChildAt(0).findViewById(
|
|
|
|
|
R.id.et_edit_text);
|
|
|
|
@ -683,12 +815,16 @@ public class NoteEditActivity extends AppCompatActivity implements OnClickListen
|
|
|
|
|
edit = (NoteEditText) mEditTextList.getChildAt(index - 1).findViewById(
|
|
|
|
|
R.id.et_edit_text);
|
|
|
|
|
}
|
|
|
|
|
//记录EditText中字符串的长度
|
|
|
|
|
int length = edit.length();
|
|
|
|
|
//将删除的行布局中的EditText中的内容拼接到上一个行布局的EditText
|
|
|
|
|
edit.append(text);
|
|
|
|
|
//上一行的EditText获取焦点
|
|
|
|
|
edit.requestFocus();
|
|
|
|
|
//调整上一行的EditText焦点的位置
|
|
|
|
|
edit.setSelection(length);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//清单模式下新建一行便签内容
|
|
|
|
|
public void onEditTextEnter(int index, String text) {
|
|
|
|
|
/**
|
|
|
|
|
* Should not happen, check for debug
|
|
|
|
@ -696,12 +832,15 @@ public class NoteEditActivity extends AppCompatActivity implements OnClickListen
|
|
|
|
|
if(index > mEditTextList.getChildCount()) {
|
|
|
|
|
Log.e(TAG, "Index out of mEditTextList boundrary, should not happen");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//清单模式下新建一个编辑行布局
|
|
|
|
|
View view = getListItem(text, index);
|
|
|
|
|
mEditTextList.addView(view, index);
|
|
|
|
|
//在编辑行布局中获取EditText,并获取焦点
|
|
|
|
|
NoteEditText edit = (NoteEditText) view.findViewById(R.id.et_edit_text);
|
|
|
|
|
edit.requestFocus();
|
|
|
|
|
//EditText光标设置为起始位置
|
|
|
|
|
edit.setSelection(0);
|
|
|
|
|
//重新设定从新建的位置之后每一个编辑行的位置
|
|
|
|
|
for (int i = index + 1; i < mEditTextList.getChildCount(); i++) {
|
|
|
|
|
((NoteEditText) mEditTextList.getChildAt(i).findViewById(R.id.et_edit_text))
|
|
|
|
|
.setIndex(i);
|
|
|
|
@ -709,33 +848,46 @@ public class NoteEditActivity extends AppCompatActivity implements OnClickListen
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void switchToListMode(String text) {
|
|
|
|
|
//移除清单模式下的父布局LinearLayout的所有子视图
|
|
|
|
|
mEditTextList.removeAllViews();
|
|
|
|
|
//将便签内容以字符串分隔,形成清单模式下的每一条内容
|
|
|
|
|
String[] items = text.split("\n");
|
|
|
|
|
int index = 0;
|
|
|
|
|
//遍历每一条内容
|
|
|
|
|
for (String item : items) {
|
|
|
|
|
//判断内容是否为空
|
|
|
|
|
if(!TextUtils.isEmpty(item)) {
|
|
|
|
|
//在清单模式下的父布局LinearLayout中添加子布局,并在子布局中显示便签中的内容
|
|
|
|
|
mEditTextList.addView(getListItem(item, index));
|
|
|
|
|
index++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
//在清单模式下的父布局LinearLayout中的最后多添加一条内容为空的子布局
|
|
|
|
|
mEditTextList.addView(getListItem("", index));
|
|
|
|
|
//空的子布局中的EditText获取焦点,以便用户输入
|
|
|
|
|
mEditTextList.getChildAt(index).findViewById(R.id.et_edit_text).requestFocus();
|
|
|
|
|
|
|
|
|
|
//设置正常模式(即非清单模式)下显示便签内容的布局不可见
|
|
|
|
|
mNoteEditor.setVisibility(View.GONE);
|
|
|
|
|
//设置清单模式下的显示便签内容的布局可见
|
|
|
|
|
mEditTextList.setVisibility(View.VISIBLE);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private Spannable getHighlightQueryResult(String fullText, String userQuery) {
|
|
|
|
|
//SpannableString类用于便捷解决字符串中部分需要特殊显示效果处理
|
|
|
|
|
SpannableString spannable = new SpannableString(fullText == null ? "" : fullText);
|
|
|
|
|
if (!TextUtils.isEmpty(userQuery)) {
|
|
|
|
|
//便签内容模式匹配用户的搜索内容
|
|
|
|
|
mPattern = Pattern.compile(userQuery);
|
|
|
|
|
Matcher m = mPattern.matcher(fullText);
|
|
|
|
|
int start = 0;
|
|
|
|
|
//第一次从字符串起始位置查找,查找所有匹配的位置
|
|
|
|
|
while (m.find(start)) {
|
|
|
|
|
//设置匹配内容的字体颜色为R.color.user_query_highlight
|
|
|
|
|
spannable.setSpan(
|
|
|
|
|
new BackgroundColorSpan(this.getResources().getColor(
|
|
|
|
|
R.color.user_query_highlight)), m.start(), m.end(),
|
|
|
|
|
Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
|
|
|
|
|
//设置查找位置为上一次匹配的末位置,再次查找
|
|
|
|
|
start = m.end();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -743,69 +895,101 @@ public class NoteEditActivity extends AppCompatActivity implements OnClickListen
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private View getListItem(String item, int index) {
|
|
|
|
|
//加载清单模式下的每一条内容的布局
|
|
|
|
|
View view = LayoutInflater.from(this).inflate(R.layout.note_edit_list_item, null);
|
|
|
|
|
//获取布局中的EditText
|
|
|
|
|
final NoteEditText edit = (NoteEditText) view.findViewById(R.id.et_edit_text);
|
|
|
|
|
//设置EditText重的字体的样式
|
|
|
|
|
edit.setTextAppearance(this, TextAppearanceResources.getTexAppearanceResource(mFontSizeId));
|
|
|
|
|
//获取勾选组件CheckBox
|
|
|
|
|
CheckBox cb = ((CheckBox) view.findViewById(R.id.cb_edit_item));
|
|
|
|
|
//为勾选组件设置监听
|
|
|
|
|
cb.setOnCheckedChangeListener(new OnCheckedChangeListener() {
|
|
|
|
|
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
|
|
|
|
|
if (isChecked) {
|
|
|
|
|
//给EditText中的内容添加划线
|
|
|
|
|
edit.setPaintFlags(edit.getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG);
|
|
|
|
|
} else {
|
|
|
|
|
//取消EditText中的内容的划线
|
|
|
|
|
edit.setPaintFlags(Paint.ANTI_ALIAS_FLAG | Paint.DEV_KERN_TEXT_FLAG);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
//判断便签中的一条内容是否以TAG_CHECKED开头,即是否勾选
|
|
|
|
|
if (item.startsWith(TAG_CHECKED)) {
|
|
|
|
|
//设置CheckBox为勾选状态
|
|
|
|
|
cb.setChecked(true);
|
|
|
|
|
//给EditText中的内容添加划线
|
|
|
|
|
edit.setPaintFlags(edit.getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG);
|
|
|
|
|
//去掉一行内容中的TAG_CHECKED前缀
|
|
|
|
|
item = item.substring(TAG_CHECKED.length(), item.length()).trim();
|
|
|
|
|
} else if (item.startsWith(TAG_UNCHECKED)) {
|
|
|
|
|
//设置CheckBox为非勾选状态
|
|
|
|
|
cb.setChecked(false);
|
|
|
|
|
//设置EditText中的内容为正常状态,即无划线
|
|
|
|
|
edit.setPaintFlags(Paint.ANTI_ALIAS_FLAG | Paint.DEV_KERN_TEXT_FLAG);
|
|
|
|
|
//去掉一行内容中的TAG_UNCHECKED前缀
|
|
|
|
|
item = item.substring(TAG_UNCHECKED.length(), item.length()).trim();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//为EditText注册监听器
|
|
|
|
|
edit.setOnTextViewChangeListener(this);
|
|
|
|
|
//记录EditText的位置
|
|
|
|
|
edit.setIndex(index);
|
|
|
|
|
//设置EditText中显示的为清单模式中一行的内容,并且对于用户通过搜索之后进入清单模式,便签内容与搜索内容匹配的部分的颜色特殊处理
|
|
|
|
|
edit.setText(getHighlightQueryResult(item, mUserQuery));
|
|
|
|
|
return view;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void onTextChange(int index, boolean hasText) {
|
|
|
|
|
//判断清单模式下这一行的位置是否超过了总行数
|
|
|
|
|
if (index >= mEditTextList.getChildCount()) {
|
|
|
|
|
Log.e(TAG, "Wrong index, should not happen");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
//首先判断清单模式下这一行是否有内容
|
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//监测编辑便签内容时模式的改变(清单模式还是普通)
|
|
|
|
|
public void onCheckListModeChanged(int oldMode, int newMode) {
|
|
|
|
|
//判断是否是清单模式
|
|
|
|
|
if (newMode == TextNote.MODE_CHECK_LIST) {
|
|
|
|
|
//切换到清单模式
|
|
|
|
|
switchToListMode(mNoteEditor.getText().toString());
|
|
|
|
|
} else {
|
|
|
|
|
//去掉字符串中所有的TAG_UNCHECKED + " ",实际上这里并没有处理勾选符号
|
|
|
|
|
if (!getWorkingText()) {
|
|
|
|
|
mWorkingNote.setWorkingText(mWorkingNote.getContent().replace(TAG_UNCHECKED + " ",
|
|
|
|
|
""));
|
|
|
|
|
}
|
|
|
|
|
//处理便签内容与用户搜索匹配的部分
|
|
|
|
|
mNoteEditor.setText(getHighlightQueryResult(mWorkingNote.getContent(), mUserQuery));
|
|
|
|
|
//设置清单模式下的布局不可见
|
|
|
|
|
mEditTextList.setVisibility(View.GONE);
|
|
|
|
|
//设置普通模式下的布局可见
|
|
|
|
|
mNoteEditor.setVisibility(View.VISIBLE);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private boolean getWorkingText() {
|
|
|
|
|
//记录清单模式中是否存在有被选中的内容
|
|
|
|
|
boolean hasChecked = false;
|
|
|
|
|
//判断是否是清单模式
|
|
|
|
|
if (mWorkingNote.getCheckListMode() == TextNote.MODE_CHECK_LIST) {
|
|
|
|
|
//拼接便签内容
|
|
|
|
|
StringBuilder sb = new StringBuilder();
|
|
|
|
|
for (int i = 0; i < mEditTextList.getChildCount(); i++) {
|
|
|
|
|
//获取清单模式一行的布局,为一个LinearLayout
|
|
|
|
|
View view = mEditTextList.getChildAt(i);
|
|
|
|
|
//获取清单模式一个布局中(即一行)的EditText
|
|
|
|
|
NoteEditText edit = (NoteEditText) view.findViewById(R.id.et_edit_text);
|
|
|
|
|
//拼接清单模式一行中的内容,包括符号和具体内容
|
|
|
|
|
if (!TextUtils.isEmpty(edit.getText())) {
|
|
|
|
|
if (((CheckBox) view.findViewById(R.id.cb_edit_item)).isChecked()) {
|
|
|
|
|
sb.append(TAG_CHECKED).append(" ").append(edit.getText()).append("\n");
|
|
|
|
@ -815,6 +999,7 @@ public class NoteEditActivity extends AppCompatActivity implements OnClickListen
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
//记录便签的内容以及编辑日期等信息
|
|
|
|
|
mWorkingNote.setWorkingText(sb.toString());
|
|
|
|
|
} else {
|
|
|
|
|
mWorkingNote.setWorkingText(mNoteEditor.getText().toString());
|
|
|
|
@ -822,7 +1007,9 @@ public class NoteEditActivity extends AppCompatActivity implements OnClickListen
|
|
|
|
|
return hasChecked;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//保存便签内容
|
|
|
|
|
private boolean saveNote() {
|
|
|
|
|
//记录好便签中的内容
|
|
|
|
|
getWorkingText();
|
|
|
|
|
boolean saved = mWorkingNote.saveNote();
|
|
|
|
|
if (saved) {
|
|
|
|
@ -839,6 +1026,7 @@ public class NoteEditActivity extends AppCompatActivity implements OnClickListen
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//将便签发送到桌面
|
|
|
|
|
@RequiresApi(api = Build.VERSION_CODES.O)
|
|
|
|
|
private void sendToDesktop() {
|
|
|
|
|
/**
|
|
|
|
@ -846,7 +1034,9 @@ public class NoteEditActivity extends AppCompatActivity implements OnClickListen
|
|
|
|
|
* editing note is exists in databases. So, for new note, firstly
|
|
|
|
|
* save it
|
|
|
|
|
*/
|
|
|
|
|
//根据便签id判断便签是否存在
|
|
|
|
|
if (!mWorkingNote.existInDatabase()) {
|
|
|
|
|
//保存便签内容
|
|
|
|
|
saveNote();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -880,16 +1070,24 @@ public class NoteEditActivity extends AppCompatActivity implements OnClickListen
|
|
|
|
|
List<ShortcutInfoCompat> lst = new ArrayList<>();
|
|
|
|
|
lst.add(shortcut);
|
|
|
|
|
ShortcutManagerCompat.addDynamicShortcuts(this, lst);*/
|
|
|
|
|
|
|
|
|
|
//创建快捷方式管理对象
|
|
|
|
|
ShortcutManager shortcutManager =
|
|
|
|
|
getSystemService(ShortcutManager.class);
|
|
|
|
|
|
|
|
|
|
//验证设备的默认启动器是否支持应用内固定快捷方式
|
|
|
|
|
if (shortcutManager.isRequestPinShortcutSupported()) {
|
|
|
|
|
// Assumes there's already a shortcut with the ID "my-shortcut".
|
|
|
|
|
// The shortcut must be enabled.
|
|
|
|
|
//创建一个用于活动启动的Intent
|
|
|
|
|
Intent shortcutIntent = new Intent(this, NoteEditActivity.class);
|
|
|
|
|
//设置Intent的意图
|
|
|
|
|
shortcutIntent.setAction(Intent.ACTION_VIEW);
|
|
|
|
|
//Intent中存入便签的id
|
|
|
|
|
shortcutIntent.putExtra(Intent.EXTRA_UID, mWorkingNote.getNoteId());
|
|
|
|
|
//构建快捷方式
|
|
|
|
|
//以便签的id作为快捷方式的ID
|
|
|
|
|
//以处理后的便签内容作为简短说明快捷方式用途的词组和详细说明快捷方式用途的词组
|
|
|
|
|
//设置快捷方式的图标
|
|
|
|
|
//设置快捷方式的启动操作
|
|
|
|
|
ShortcutInfo pinShortcutInfo = new ShortcutInfo.Builder(this, String.valueOf(mWorkingNote.getNoteId()))
|
|
|
|
|
.setShortLabel(makeShortcutIconTitle(mWorkingNote.getContent()))
|
|
|
|
|
.setLongLabel(makeShortcutIconTitle(mWorkingNote.getContent()))
|
|
|
|
@ -901,14 +1099,17 @@ public class NoteEditActivity extends AppCompatActivity implements OnClickListen
|
|
|
|
|
// pinning operation fails, your app isn't notified. We assume here that the
|
|
|
|
|
// app has implemented a method called createShortcutResultIntent() that
|
|
|
|
|
// returns a broadcast intent.
|
|
|
|
|
//创建一个意图
|
|
|
|
|
Intent pinnedShortcutCallbackIntent =
|
|
|
|
|
shortcutManager.createShortcutResultIntent(pinShortcutInfo);
|
|
|
|
|
|
|
|
|
|
// Configure the intent so that your app's broadcast receiver gets
|
|
|
|
|
// the callback successfully.For details, see PendingIntent.getBroadcast().
|
|
|
|
|
//和其他系统控件交互一样需要延时意图PendingIntent
|
|
|
|
|
//该Intent执行的操作其实是实际传来的Intent的操作,自带Context
|
|
|
|
|
PendingIntent successCallback = PendingIntent.getBroadcast(this, 0,
|
|
|
|
|
pinnedShortcutCallbackIntent, 0);
|
|
|
|
|
|
|
|
|
|
//创建固定快捷方式
|
|
|
|
|
shortcutManager.requestPinShortcut(pinShortcutInfo,
|
|
|
|
|
successCallback.getIntentSender());
|
|
|
|
|
}
|
|
|
|
@ -924,16 +1125,19 @@ public class NoteEditActivity extends AppCompatActivity implements OnClickListen
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private String makeShortcutIconTitle(String content) {
|
|
|
|
|
//去掉清单模式下保存内容时加的TAG_CHECKED和TAG_UNCHECKED标识符
|
|
|
|
|
content = content.replace(TAG_CHECKED, "");
|
|
|
|
|
content = content.replace(TAG_UNCHECKED, "");
|
|
|
|
|
//如果保存内容超过10个字符则截取前10个字符作为标题,否则直接以保存的内容作为标题
|
|
|
|
|
return content.length() > SHORTCUT_ICON_TITLE_MAX_LEN ? content.substring(0,
|
|
|
|
|
SHORTCUT_ICON_TITLE_MAX_LEN) : content;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//输出提示信息
|
|
|
|
|
private void showToast(int resId) {
|
|
|
|
|
showToast(resId, Toast.LENGTH_SHORT);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//输出提示信息
|
|
|
|
|
private void showToast(int resId, int duration) {
|
|
|
|
|
Toast.makeText(this, resId, duration).show();
|
|
|
|
|
}
|
|
|
|
|