diff --git a/AlarmInitReceiver.java b/AlarmInitReceiver.java deleted file mode 100644 index c1e7d08..0000000 --- a/AlarmInitReceiver.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package net.micode.notes.ui; // 指定该类所在的包路径 - -import android.app.AlarmManager; // 引入AlarmManager类,用于设置闹钟 -import android.app.PendingIntent; // 引入PendingIntent类,表示延迟的Intent -import android.content.BroadcastReceiver; // 引入BroadcastReceiver类,用于接收广播 -import android.content.ContentUris; // 引入ContentUris类,用于生成URI -import android.content.Context; // 引入Context类,用于访问系统资源 -import android.content.Intent; // 引入Intent类,用于启动组件 -import android.database.Cursor; // 引入Cursor类,用于数据库查询 - -import net.micode.notes.data.Notes; // 引入Notes类,处理笔记数据 -import net.micode.notes.data.Notes.NoteColumns; // 引入NoteColumns类,表示Notes表的列 - -public class AlarmInitReceiver extends BroadcastReceiver { // 定义一个继承自BroadcastReceiver的类 - - // 定义查询需要的列 - private static final String [] PROJECTION = new String [] { - NoteColumns.ID, // 获取笔记的ID列 - NoteColumns.ALERTED_DATE // 获取提醒时间列 - }; - - // 列索引常量 - private static final int COLUMN_ID = 0; // 第0列是ID列 - private static final int COLUMN_ALERTED_DATE = 1; // 第1列是提醒时间列 - - @Override - public void onReceive(Context context, Intent intent) { // 重写onReceive方法,接收广播 - long currentDate = System.currentTimeMillis(); // 获取当前的系统时间(以毫秒为单位) - - // 查询数据库,获取需要提醒的笔记,且提醒时间大于当前时间 - Cursor c = context.getContentResolver().query(Notes.CONTENT_NOTE_URI, // 查询URI为Notes.CONTENT_NOTE_URI的内容提供者 - PROJECTION, // 需要查询的列 - NoteColumns.ALERTED_DATE + ">? AND " + NoteColumns.TYPE + "=" + Notes.TYPE_NOTE, // 查询条件:提醒时间大于当前时间,且类型为笔记 - new String[] { String.valueOf(currentDate) }, // 查询条件中的当前时间 - null); // 不需要排序 - - // 如果查询结果不为空 - if (c != null) { - // 如果查询到至少一条记录 - if (c.moveToFirst()) { - do { - long alertDate = c.getLong(COLUMN_ALERTED_DATE); // 获取提醒时间 - Intent sender = new Intent(context, AlarmReceiver.class); // 创建一个新的Intent,用于发送广播 - sender.setData(ContentUris.withAppendedId(Notes.CONTENT_NOTE_URI, c.getLong(COLUMN_ID))); // 设置Intent的数据(笔记的ID) - - // 创建PendingIntent,表示在指定时间执行AlarmReceiver广播 - PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, sender, 0); - - // 获取系统的AlarmManager服务 - AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); - - // 设置闹钟,使用RTC_WAKEUP模式,当到达指定的提醒时间时唤醒设备并触发PendingIntent - alarmManager.set(AlarmManager.RTC_WAKEUP, alertDate, pendingIntent); - } while (c.moveToNext()); // 如果查询结果中还有下一条记录,则继续处理 - } - c.close(); // 关闭Cursor - } - } -} diff --git a/AlarmReceiver.java b/AlarmReceiver.java deleted file mode 100644 index c692e17..0000000 --- a/AlarmReceiver.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package net.micode.notes.ui; - -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; - -// AlarmReceiver 类继承自 BroadcastReceiver,用于接收便签提醒的广播事件。 -public class AlarmReceiver extends BroadcastReceiver { - // onReceive 方法是 BroadcastReceiver 的回调方法,当接收到广播时被调用。 - @Override - public void onReceive(Context context, Intent intent) { - // 设置 intent 的目标类为 AlarmAlertActivity。 - intent.setClass(context, AlarmAlertActivity.class); - // 为 intent 添加 FLAG_ACTIVITY_NEW_TASK 标志,使得在新的任务栈中启动 Activity。 - intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - // 在给定的上下文中启动 AlarmAlertActivity。 - context.startActivity(intent); - } -} \ No newline at end of file diff --git a/DropdownMenu.java b/DropdownMenu.java deleted file mode 100644 index fe6e47a..0000000 --- a/DropdownMenu.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package net.micode.notes.ui; // 定义类所在的包路径 - -import android.content.Context; // 引入Context类,用于访问应用程序的上下文 -import android.view.Menu; // 引入Menu类,用于操作菜单 -import android.view.MenuItem; // 引入MenuItem类,用于菜单项的处理 -import android.view.View; // 引入View类,用于视图的操作 -import android.view.View.OnClickListener; // 引入OnClickListener接口,用于处理点击事件 -import android.widget.Button; // 引入Button类,用于显示按钮 -import android.widget.PopupMenu; // 引入PopupMenu类,用于显示弹出菜单 -import android.widget.PopupMenu.OnMenuItemClickListener; // 引入PopupMenu的菜单项点击监听器 - -public class DropdownMenu { - private Button mButton; // 用于显示的按钮,点击后弹出菜单 - private PopupMenu mPopupMenu; // 弹出菜单的实例 - private Menu mMenu; // 菜单项的集合 - - // 构造函数,初始化DropdownMenu,设置按钮及其弹出菜单 - public DropdownMenu(Context context, Button button, int menuId) { - mButton = button; // 获取传入的按钮对象 - mButton.setBackgroundResource(R.drawable.dropdown_icon); // 设置按钮的背景图标为下拉菜单图标 - mPopupMenu = new PopupMenu(context, mButton); // 初始化PopupMenu,指定按钮作为弹出菜单的锚点 - mMenu = mPopupMenu.getMenu(); // 获取PopupMenu中的Menu对象 - mPopupMenu.getMenuInflater().inflate(menuId, mMenu); // 使用传入的menuId加载菜单资源 - mButton.setOnClickListener(new OnClickListener() { // 为按钮设置点击事件监听器 - public void onClick(View v) { - mPopupMenu.show(); // 当按钮被点击时,显示弹出菜单 - } - }); - } - - // 设置菜单项点击事件监听器 - public void setOnDropdownMenuItemClickListener(OnMenuItemClickListener listener) { - if (mPopupMenu != null) { - mPopupMenu.setOnMenuItemClickListener(listener); // 设置PopupMenu的菜单项点击监听器 - } - } - - // 根据菜单项的ID查找菜单项 - public MenuItem findItem(int id) { - return mMenu.findItem(id); // 在菜单中查找具有指定ID的菜单项 - } - - // 设置按钮的文本 - public void setTitle(CharSequence title) { - mButton.setText(title); // 设置按钮的文本为传入的title - } -} diff --git a/FoldersListAdapter.java b/FoldersListAdapter.java deleted file mode 100644 index 94bb583..0000000 --- a/FoldersListAdapter.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package net.micode.notes.ui; - -import android.content.Context; -import android.database.Cursor; -import android.view.View; -import android.view.ViewGroup; -import android.widget.CursorAdapter; -import android.widget.LinearLayout; -import android.widget.TextView; - -import net.micode.notes.R; -import net.micode.notes.data.Notes; -import net.micode.notes.data.Notes.NoteColumns; - - -// FoldersListAdapter 是一个自定义的 CursorAdapter,用于显示文件夹列表。 -public class FoldersListAdapter extends CursorAdapter { - // 定义查询数据库时需要的列。 - public static final String [] PROJECTION = { - NoteColumns.ID, - NoteColumns.SNIPPET - }; - - // 定义列索引常量。 - public static final int ID_COLUMN = 0; - public static final int NAME_COLUMN = 1; - - // FoldersListAdapter 的构造函数。 - public FoldersListAdapter(Context context, Cursor c) { - super(context, c); - // TODO Auto-generated constructor stub - } - - // 新建视图的方法,返回一个 FolderListItem 实例。 - @Override - public View newView(Context context, Cursor cursor, ViewGroup parent) { - return new FolderListItem(context); - } - - // 绑定视图与数据的方法。 - @Override - public void bindView(View view, Context context, Cursor cursor) { - if (view instanceof FolderListItem) { - String folderName = (cursor.getLong(ID_COLUMN) == Notes.ID_ROOT_FOLDER) ? context - .getString(R.string.menu_move_parent_folder) : cursor.getString(NAME_COLUMN); - ((FolderListItem) view).bind(folderName); - } - } - - // 根据位置获取文件夹名称的方法。 - public String getFolderName(Context context, int position) { - Cursor cursor = (Cursor) getItem(position); - return (cursor.getLong(ID_COLUMN) == Notes.ID_ROOT_FOLDER) ? context - .getString(R.string.menu_move_parent_folder) : cursor.getString(NAME_COLUMN); - } - - // FolderListItem 是一个内部类,表示列表中的单个文件夹项。 - private class FolderListItem extends LinearLayout { - private TextView mName; // 用于显示文件夹名称的 TextView。 - - // FolderListItem 的构造函数。 - public FolderListItem(Context context) { - super(context); - inflate(context, R.layout.folder_list_item, this); - mName = (TextView) findViewById(R.id.tv_folder_name); - } - - // 绑定文件夹名称的方法。 - public void bind(String name) { - mName.setText(name); - } - } -} \ No newline at end of file diff --git a/NoteEditActivity.java b/NoteEditActivity.java deleted file mode 100644 index 075ccd6..0000000 --- a/NoteEditActivity.java +++ /dev/null @@ -1,515 +0,0 @@ -/* - * Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package net.micode.notes.ui; - -import android.app.Activity; -import android.app.AlarmManager; -import android.app.AlertDialog; -import android.app.PendingIntent; -import android.app.SearchManager; -import android.appwidget.AppWidgetManager; -import android.content.ContentUris; -import android.content.Context; -import android.content.DialogInterface; -import android.content.Intent; -import android.content.SharedPreferences; -import android.graphics.Paint; -import android.os.Bundle; -import android.preference.PreferenceManager; -import android.text.Spannable; -import android.text.SpannableString; -import android.text.TextUtils; -import android.text.format.DateUtils; -import android.text.style.BackgroundColorSpan; -import android.util.Log; -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.WindowManager; -import android.widget.CheckBox; -import android.widget.CompoundButton; -import android.widget.CompoundButton.OnCheckedChangeListener; -import android.widget.EditText; -import android.widget.ImageView; -import android.widget.LinearLayout; -import android.widget.TextView; -import android.widget.Toast; - -import net.micode.notes.R; -import net.micode.notes.data.Notes; -import net.micode.notes.data.Notes.TextNote; -import net.micode.notes.model.WorkingNote; -import net.micode.notes.model.WorkingNote.NoteSettingChangedListener; -import net.micode.notes.tool.DataUtils; -import net.micode.notes.tool.ResourceParser; -import net.micode.notes.tool.ResourceParser.TextAppearanceResources; -import net.micode.notes.ui.DateTimePickerDialog.OnDateTimeSetListener; -import net.micode.notes.ui.NoteEditText.OnTextViewChangeListener; -import net.micode.notes.widget.NoteWidgetProvider_2x; -import net.micode.notes.widget.NoteWidgetProvider_4x; - -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -// NoteEditActivity 是一个用于编辑便签的 Activity。 -public class NoteEditActivity extends Activity implements OnClickListener, - NoteSettingChangedListener, OnTextViewChangeListener { - // 内部类,用于持有头部视图的控件引用。 - private class HeadViewHolder { - public TextView tvModified; // 修改日期的 TextView。 - public ImageView ivAlertIcon; // 提醒图标的 ImageView。 - public TextView tvAlertDate; // 提醒日期的 TextView。 - public ImageView ibSetBgColor; // 设置背景颜色的 ImageView。 - } - - // 背景颜色选择按钮与颜色 ID 的映射。 - private static final Map sBgSelectorBtnsMap = new HashMap(); - static { - sBgSelectorBtnsMap.put(R.id.iv_bg_yellow, ResourceParser.YELLOW); - sBgSelectorBtnsMap.put(R.id.iv_bg_red, ResourceParser.RED); - 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); - } - - // 背景颜色选择结果与按钮 ID 的映射。 - private static final Map sBgSelectorSelectionMap = new HashMap(); - static { - sBgSelectorSelectionMap.put(ResourceParser.YELLOW, R.id.iv_bg_yellow_select); - sBgSelectorSelectionMap.put(ResourceParser.RED, R.id.iv_bg_red_select); - 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); - } - - // 字体大小选择按钮与大小 ID 的映射。 - private static final Map sFontSizeBtnsMap = new HashMap(); - static { - sFontSizeBtnsMap.put(R.id.ll_font_large, ResourceParser.TEXT_LARGE); - sFontSizeBtnsMap.put(R.id.ll_font_small, ResourceParser.TEXT_SMALL); - sFontSizeBtnsMap.put(R.id.ll_font_normal, ResourceParser.TEXT_MEDIUM); - sFontSizeBtnsMap.put(R.id.ll_font_super, ResourceParser.TEXT_SUPER); - } - - // 字体大小选择结果与按钮 ID 的映射。 - private static final Map sFontSelectorSelectionMap = new HashMap(); - static { - sFontSelectorSelectionMap.put(ResourceParser.TEXT_LARGE, R.id.iv_large_select); - sFontSelectorSelectionMap.put(ResourceParser.TEXT_SMALL, R.id.iv_small_select); - sFontSelectorSelectionMap.put(ResourceParser.TEXT_MEDIUM, R.id.iv_medium_select); - sFontSelectorSelectionMap.put(ResourceParser.TEXT_SUPER, R.id.iv_super_select); - } - - // 日志标签。 - private static final String TAG = "NoteEditActivity"; - - // 头部视图的 Holder。 - private HeadViewHolder mNoteHeaderHolder; - - // 头部视图面板、背景颜色选择器和字体大小选择器。 - private View mHeadViewPanel; - - private View mNoteBgColorSelector; - - private View mFontSizeSelector; - - // 编辑器和编辑器面板。 - private EditText mNoteEditor; - - private View mNoteEditorPanel; - - // 正在编辑的便签。 - private WorkingNote mWorkingNote; - - // SharedPreferences 和字体大小 ID。 - private SharedPreferences mSharedPrefs; - private int mFontSizeId; - - // SharedPreferences 中字体大小的键。 - 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; - - // 用户查询字符串和正则表达式模式。 - private String mUserQuery; - private Pattern mPattern; - - // onCreate 方法,初始化 Activity。 - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - this.setContentView(R.layout.note_edit); - - if (savedInstanceState == null && !initActivityState(getIntent())) { - finish(); - return; - } - initResources(); - } - - // onRestoreInstanceState 方法,恢复 Activity 状态。 - @Override - protected void onRestoreInstanceState(Bundle savedInstanceState) { - super.onRestoreInstanceState(savedInstanceState); - 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)); - if (!initActivityState(intent)) { - finish(); - return; - } - Log.d(TAG, "Restoring from killed activity"); - } - } - - // initActivityState 方法,初始化 Activity 状态。 - private boolean initActivityState(Intent intent) { - // 省略部分代码... - } - - // onResume 方法,恢复 Activity 时调用。 - @Override - protected void onResume() { - super.onResume(); - initNoteScreen(); - } - - // initNoteScreen 方法,初始化便签屏幕。 - private void initNoteScreen() { - // 省略部分代码... - } - - // onNewIntent 方法,处理新的 Intent。 - @Override - protected void onNewIntent(Intent intent) { - super.onNewIntent(intent); - initActivityState(intent); - } - - // onSaveInstanceState 方法,保存 Activity 状态。 - @Override - protected void onSaveInstanceState(Bundle outState) { - super.onSaveInstanceState(outState); - // 省略部分代码... - } - - // dispatchTouchEvent 方法,分发触摸事件。 - @Override - public boolean dispatchTouchEvent(MotionEvent ev) { - // 省略部分代码... - } - - // inRangeOfView 方法,判断触摸事件是否在视图范围内。 - private boolean inRangeOfView(View view, MotionEvent ev) { - // 省略部分代码... - } - - // initResources 方法,初始化资源。 - private void initResources() { - // 省略部分代码... - } - - // onPause 方法,暂停 Activity 时调用。 - @Override - protected void onPause() { - super.onPause(); - if(saveNote()) { - Log.d(TAG, "Note data was saved with length:" + mWorkingNote.getContent().length()); - } - clearSettingState(); - } - - // updateWidget 方法,更新小部件。 - private void updateWidget() { - // 省略部分代码... - } -} -/** - * 当点击某个视图时调用此方法。 - * @param v 被点击的视图。 - */ -public void onClick(View v) { - int id = v.getId(); // 获取被点击视图的ID。 - // 如果被点击的视图是设置背景颜色的按钮,则显示背景颜色选择器。 - if (id == R.id.btn_set_bg_color) { - mNoteBgColorSelector.setVisibility(View.VISIBLE); - findViewById(sBgSelectorSelectionMap.get(mWorkingNote.getBgColorId())).setVisibility(-View.VISIBLE); - } else if (sBgSelectorBtnsMap.containsKey(id)) { // 如果被点击的是背景颜色按钮。 - findViewById(sBgSelectorSelectionMap.get(mWorkingNote.getBgColorId())).setVisibility(View.GONE); - mWorkingNote.setBgColorId(sBgSelectorBtnsMap.get(id)); // 更改背景颜色ID。 - mNoteBgColorSelector.setVisibility(View.GONE); - } else if (sFontSizeBtnsMap.containsKey(id)) { // 如果被点击的是字体大小按钮。 - findViewById(sFontSelectorSelectionMap.get(mFontSizeId)).setVisibility(View.GONE); - mFontSizeId = sFontSizeBtnsMap.get(id); // 更改字体大小ID。 - 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(); -} - -/** - * 清除设置状态,例如隐藏背景颜色选择器和字体大小选择器。 - * @return 如果设置状态被清除,则返回true,否则返回false。 - */ -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()); -} - -/** - * 准备选项菜单。 - * @param menu 选项菜单。 - * @return 如果菜单已准备,则返回true,否则返回false。 - */ -@Override -public boolean onPrepareOptionsMenu(Menu menu) { - if (isFinishing()) { - return true; - } - clearSettingState(); - menu.clear(); - // 根据便签的文件夹ID决定加载哪个菜单。 - 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 { - menu.findItem(R.id.menu_delete_remind).setVisible(false); - } - return true; -} - -/** - * 处理选项菜单项的选择。 - * @param item 被选择的菜单项。 - * @return 如果项被处理,则返回true,否则返回false。 - */ -@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); - builder.setMessage(getString(R.string.alert_message_delete_note)); - builder.setPositiveButton(android.R.string.ok, - new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int which) { - deleteCurrentNote(); - finish(); - } - }); - builder.setNegativeButton(android.R.string.cancel, null); - 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: - mWorkingNote.setAlertDate(0, false); - break; - default: - break; - } - return true; -} - -/** - * 设置便签的提醒。 - */ -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); - } - }); - d.show(); -} - -/** - * 分享便签到支持{@link Intent#ACTION_SEND}动作和{text/plain}类型的应用。 - * @param context 上下文。 - * @param info 要分享的便签内容。 - */ -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); -} - -/** - * 创建一个新的便签。 - */ -private void createNewNote() { - // 在创建新便签之前保存当前正在编辑的便签。 - saveNote(); - 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 ids = new HashSet(); - long id = mWorkingNote.getNoteId(); - if (id != Notes.ID_ROOT_FOLDER) { - ids.add(id); - } else { - Log.d(TAG, "错误的便签ID,不应该发生"); - } - if (!isSyncMode()) { - if (!DataUtils.batchDeleteNotes(getContentResolver(), ids)) { - Log.e(TAG, "删除便签错误"); - } - } else { - if (!DataUtils.batchMoveToFolder(getContentResolver(), ids, Notes.ID_TRASH_FOLER)) { - Log.e(TAG, "将便签移动到废纸篓文件夹错误,不应该发生"); - } - } - } - mWorkingNote.markDeleted(true); -} - -/** - * 检查应用是否处于同步模式。 - * @return 如果处于同步模式,则返回true,否则返回false。 - */ -private boolean isSyncMode() { - return NotesPreferenceActivity.getSyncAccountName(this).trim().length() > 0; -} - -/** - * 当时钟提醒改变时调用。 - * @param date 新的提醒日期。 - * @param set 如果设置了提醒,则为true;如果取消了提醒,则为false。 - */ -public void onClockAlertChanged(long date, boolean set) { - if (!mWorkingNote.existInDatabase()) { - saveNote(); - } - if (mWorkingNote.getNoteId() > 0) { - 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); - AlarmManager alarmManager = ((AlarmManager) getSystemService(ALARM_SERVICE)); - showAlertHeader(); - if(!set) { - alarmManager.cancel(pendingIntent); - } else { - alarmManager.set(AlarmManager.RTC_WAKEUP, date, pendingIntent); - } - } else { - Log.e(TAG, "时钟提醒设置错误"); - showToast(R.string.error_note_empty_for_clock); - } -} - -/** - * 当小部件改变时调用。 - */ -public void onWidgetChanged() { - updateWidget(); -} - -/** - * 处理在清单中删除文本项。 - * @param index 要删除项的索引。 - * @param text 项的文本。 - */ diff --git a/NoteEditText.java b/NoteEditText.java deleted file mode 100644 index 0e34903..0000000 --- a/NoteEditText.java +++ /dev/null @@ -1,304 +0,0 @@ -/* - * Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package net.micode.notes.ui; - -import android.content.Context; -import android.graphics.Rect; -import android.text.Layout; -import android.text.Selection; -import android.text.Spanned; -import android.text.TextUtils; -import android.text.style.URLSpan; -import android.util.AttributeSet; -import android.util.Log; -import android.view.ContextMenu; -import android.view.KeyEvent; -import android.view.MenuItem; -import android.view.MenuItem.OnMenuItemClickListener; -import android.view.MotionEvent; -import android.widget.EditText; - -import net.micode.notes.R; - -import java.util.HashMap; -import java.util.Map; - -public class NoteEditText extends EditText { - private static final String TAG = "NoteEditText"; - private int mIndex; - private int mSelectionStartBeforeDelete; - - private static final String SCHEME_TEL = "tel:" ; - private static final String SCHEME_HTTP = "http:" ; - private static final String SCHEME_EMAIL = "mailto:" ; - - private static final Map sSchemaActionResMap = new HashMap(); - static { - sSchemaActionResMap.put(SCHEME_TEL, R.string.note_link_tel); - sSchemaActionResMap.put(SCHEME_HTTP, R.string.note_link_web); - sSchemaActionResMap.put(SCHEME_EMAIL, R.string.note_link_email); - } - - /** - * Call by the {@link NoteEditActivity} to delete or add edit text - */ - public interface OnTextViewChangeListener { - /** - * Delete current edit text when {@link KeyEvent#KEYCODE_DEL} happens - * and the text is null - */ - void onEditTextDelete(int index, String text); - - /** - * Add edit text after current edit text when {@link KeyEvent#KEYCODE_ENTER} - * happen - */ - void onEditTextEnter(int index, String text); - - /** - * Hide or show item option when text change - */ - void onTextChange(int index, boolean hasText); - } - - /* - * Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package net.micode.notes.ui; // 定义类所在的包路径 - -// 引入相关的 Android 类 -import android.content.Context; -import android.graphics.Rect; -import android.text.Layout; -import android.text.Selection; -import android.text.Spanned; -import android.text.TextUtils; -import android.text.style.URLSpan; -import android.util.AttributeSet; -import android.util.Log; -import android.view.ContextMenu; -import android.view.KeyEvent; -import android.view.MenuItem; -import android.view.MenuItem.OnMenuItemClickListener; -import android.view.MotionEvent; -import android.widget.EditText; - -import net.micode.notes.R; // 引入资源文件中的R类 - -import java.util.HashMap; -import java.util.Map; - -public class NoteEditText extends EditText { - private static final String TAG = "NoteEditText"; // 定义日志标签,用于调试输出 - private int mIndex; // 用于表示当前编辑文本的索引 - private int mSelectionStartBeforeDelete; // 用于记录删除前的文本选择开始位置 - - // 定义常见的URI Schemes - private static final String SCHEME_TEL = "tel:" ; - private static final String SCHEME_HTTP = "http:" ; - private static final String SCHEME_EMAIL = "mailto:" ; - - // 定义一个映射关系,存储不同URI Scheme对应的资源ID - private static final Map sSchemaActionResMap = new HashMap(); - static { - sSchemaActionResMap.put(SCHEME_TEL, R.string.note_link_tel); // 电话链接对应的资源ID - sSchemaActionResMap.put(SCHEME_HTTP, R.string.note_link_web); // 网站链接对应的资源ID - sSchemaActionResMap.put(SCHEME_EMAIL, R.string.note_link_email); // 邮件链接对应的资源ID - } - - /** - * 在 {@link NoteEditActivity} 中调用,用于删除或添加编辑文本 - */ - public interface OnTextViewChangeListener { - /** - * 当发生删除事件(例如按下删除键)且文本为空时,删除当前编辑文本 - */ - void onEditTextDelete(int index, String text); - - /** - * 当发生回车事件(例如按下回车键)时,添加编辑文本 - */ - void onEditTextEnter(int index, String text); - - /** - * 当文本发生变化时,隐藏或显示项的选项 - */ - void onTextChange(int index, boolean hasText); - } -} -// 定义一个文本视图变化监听器的接口 -private OnTextViewChangeListener mOnTextViewChangeListener; - -// NoteEditText的构造函数,当从AttributeSet创建时调用 -public NoteEditText(Context context) { - super(context, null); - mIndex = 0; -} - -// 设置当前文本编辑框的索引 -public void setIndex(int index) { - mIndex = index; -} - -// 设置文本视图变化监听器 -public void setOnTextViewChangeListener(OnTextViewChangeListener listener) { - mOnTextViewChangeListener = listener; -} - -// NoteEditText的构造函数,当从AttributeSet和 defStyle创建时调用 -public NoteEditText(Context context, AttributeSet attrs) { - super(context, attrs, android.R.attr.editTextStyle); -} - -// NoteEditText的构造函数,当从AttributeSet、defStyle和 defStyle创建时调用 -public NoteEditText(Context context, AttributeSet attrs, int defStyle) { - super(context, attrs, defStyle); - // TODO Auto-generated constructor stub -} - -// 处理触摸事件,用于实现自定义的文本选择行为 -@Override -public boolean onTouchEvent(MotionEvent event) { - switch (event.getAction()) { - case MotionEvent.ACTION_DOWN: - int x = (int) event.getX(); - int y = (int) event.getY(); - x -= getTotalPaddingLeft(); - y -= getTotalPaddingTop(); - x += getScrollX(); - y += getScrollY(); - - Layout layout = getLayout(); - int line = layout.getLineForVertical(y); - int off = layout.getOffsetForHorizontal(line, x); - Selection.setSelection(getText(), off); - break; - } - - return super.onTouchEvent(event); -} - -// 处理按键事件,例如Enter和Delete键 -@Override -public boolean onKeyDown(int keyCode, KeyEvent event) { - switch (keyCode) { - case KeyEvent.KEYCODE_ENTER: - if (mOnTextViewChangeListener != null) { - return false; - } - break; - case KeyEvent.KEYCODE_DEL: - mSelectionStartBeforeDelete = getSelectionStart(); - break; - default: - break; - } - return super.onKeyDown(keyCode, event); -} - -// 处理按键释放事件,例如Enter和Delete键 -@Override -public boolean onKeyUp(int keyCode, KeyEvent event) { - switch(keyCode) { - case KeyEvent.KEYCODE_DEL: - if (mOnTextViewChangeListener != null) { - if (0 == mSelectionStartBeforeDelete && mIndex != 0) { - mOnTextViewChangeListener.onEditTextDelete(mIndex, getText().toString()); - return true; - } - } else { - Log.d(TAG, "OnTextViewChangeListener was not seted"); - } - break; - case KeyEvent.KEYCODE_ENTER: - if (mOnTextViewChangeListener != null) { - int selectionStart = getSelectionStart(); - String text = getText().subSequence(selectionStart, length()).toString(); - setText(getText().subSequence(0, selectionStart)); - mOnTextViewChangeListener.onEditTextEnter(mIndex + 1, text); - } else { - Log.d(TAG, "OnTextViewChangeListener was not seted"); - } - break; - default: - break; - } - return super.onKeyUp(keyCode, event); -} - -// 处理焦点变化事件,用于在文本编辑框失去焦点时通知监听器 -@Override -protected void onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect) { - if (mOnTextViewChangeListener != null) { - if (!focused && TextUtils.isEmpty(getText())) { - mOnTextViewChangeListener.onTextChange(mIndex, false); - } else { - mOnTextViewChangeListener.onTextChange(mIndex, true); - } - } - super.onFocusChanged(focused, direction, previouslyFocusedRect); -} - -// 创建上下文菜单,用于实现长按文本时弹出的菜单 -@Override -protected void onCreateContextMenu(ContextMenu menu) { - if (getText() instanceof Spanned) { - int selStart = getSelectionStart(); - int selEnd = getSelectionEnd(); - - int min = Math.min(selStart, selEnd); - int max = Math.max(selStart, selEnd); - - final URLSpan[] urls = ((Spanned) getText()).getSpans(min, max, URLSpan.class); - if (urls.length == 1) { - int defaultResId = 0; - for(String schema: sSchemaActionResMap.keySet()) { - if(urls[0].getURL().indexOf(schema) >= 0) { - defaultResId = sSchemaActionResMap.get(schema); - break; - } - } - - if (defaultResId == 0) { - defaultResId = R.string.note_link_other; - } - - menu.add(0, 0, 0, defaultResId).setOnMenuItemClickListener( - new OnMenuItemClickListener() { - public boolean onMenuItemClick(MenuItem item) { - // goto a new intent - urls[0].onClick(NoteEditText.this); - return true; - } - }); - } - } - super.onCreateContextMenu(menu); -} diff --git a/NoteItemData.java b/NoteItemData.java deleted file mode 100644 index 023c94c..0000000 --- a/NoteItemData.java +++ /dev/null @@ -1,156 +0,0 @@ -// 定义一个文本视图变化监听器的接口,用于监听文本编辑框中的变化事件 -private OnTextViewChangeListener mOnTextViewChangeListener; - -// NoteEditText的构造函数,当从AttributeSet创建时调用 -public NoteEditText(Context context) { - super(context, null); - mIndex = 0; -} - -// 设置当前文本编辑框的索引,用于标识编辑框的位置 -public void setIndex(int index) { - mIndex = index; -} - -// 设置文本视图变化监听器 -public void setOnTextViewChangeListener(OnTextViewChangeListener listener) { - mOnTextViewChangeListener = listener; -} - -// NoteEditText的构造函数,当从AttributeSet和 defStyle创建时调用 -public NoteEditText(Context context, AttributeSet attrs) { - super(context, attrs, android.R.attr.editTextStyle); -} - -// NoteEditText的构造函数,当从AttributeSet、defStyle和 defStyle创建时调用 -public NoteEditText(Context context, AttributeSet attrs, int defStyle) { - super(context, attrs, defStyle); - // TODO Auto-generated constructor stub -} - -// 处理触摸事件,用于实现自定义的文本选择行为 -@Override -public boolean onTouchEvent(MotionEvent event) { - switch (event.getAction()) { - case MotionEvent.ACTION_DOWN: - // 计算触摸点在文本中的位置,并设置光标 - int x = (int) event.getX(); - int y = (int) event.getY(); - x -= getTotalPaddingLeft(); - y -= getTotalPaddingTop(); - x += getScrollX(); - y += getScrollY(); - - Layout layout = getLayout(); - int line = layout.getLineForVertical(y); - int off = layout.getOffsetForHorizontal(line, x); - Selection.setSelection(getText(), off); - break; - } - - return super.onTouchEvent(event); -} - -// 处理按键事件,例如Enter和Delete键 -@Override -public boolean onKeyDown(int keyCode, KeyEvent event) { - switch (keyCode) { - case KeyEvent.KEYCODE_ENTER: - // 如果设置了监听器,消费Enter键事件 - if (mOnTextViewChangeListener != null) { - return false; - } - break; - case KeyEvent.KEYCODE_DEL: - // 在删除之前记录光标的位置 - mSelectionStartBeforeDelete = getSelectionStart(); - break; - default: - break; - } - return super.onKeyDown(keyCode, event); -} - -// 处理按键释放事件,例如Enter和Delete键 -@Override -public boolean onKeyUp(int keyCode, KeyEvent event) { - switch(keyCode) { - case KeyEvent.KEYCODE_DEL: - // 如果设置了监听器,并且在删除之前光标位于文本开头,则通知监听器删除事件 - if (mOnTextViewChangeListener != null) { - if (0 == mSelectionStartBeforeDelete && mIndex != 0) { - mOnTextViewChangeListener.onEditTextDelete(mIndex, getText().toString()); - return true; - } - } else { - Log.d(TAG, "OnTextViewChangeListener was not seted"); - } - break; - case KeyEvent.KEYCODE_ENTER: - // 如果设置了监听器,通知监听器Enter键事件,创建新的文本行 - if (mOnTextViewChangeListener != null) { - int selectionStart = getSelectionStart(); - String text = getText().subSequence(selectionStart, length()).toString(); - setText(getText().subSequence(0, selectionStart)); - mOnTextViewChangeListener.onEditTextEnter(mIndex + 1, text); - } else { - Log.d(TAG, "OnTextViewChangeListener was not seted"); - } - break; - default: - break; - } - return super.onKeyUp(keyCode, event); -} - -// 处理焦点变化事件,用于在文本编辑框失去焦点时通知监听器 -@Override -protected void onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect) { - if (mOnTextViewChangeListener != null) { - // 如果文本编辑框失去焦点且文本为空,通知监听器文本变化 - if (!focused && TextUtils.isEmpty(getText())) { - mOnTextViewChangeListener.onTextChange(mIndex, false); - } else { - mOnTextViewChangeListener.onTextChange(mIndex, true); - } - } - super.onFocusChanged(focused, direction, previouslyFocusedRect); -} - -// 创建上下文菜单,用于实现长按文本时弹出的菜单 -@Override -protected void onCreateContextMenu(ContextMenu menu) { - if (getText() instanceof Spanned) { - int selStart = getSelectionStart(); - int selEnd = getSelectionEnd(); - - int min = Math.min(selStart, selEnd); - int max = Math.max(selStart, selEnd); - - // 如果选中的文本包含URL,添加一个菜单项用于打开链接 - final URLSpan[] urls = ((Spanned) getText()).getSpans(min, max, URLSpan.class); - if (urls.length == 1) { - int defaultResId = 0; - for(String schema: sSchemaActionResMap.keySet()) { - if(urls[0].getURL().indexOf(schema) >= 0) { - defaultResId = sSchemaActionResMap.get(schema); - break; - } - } - - if (defaultResId == 0) { - defaultResId = R.string.note_link_other; - } - - menu.add(0, 0, 0, defaultResId).setOnMenuItemClickListener( - new OnMenuItemClickListener() { - public boolean onMenuItemClick(MenuItem item) { - // 打开链接 - urls[0].onClick(NoteEditText.this); - return true; - } - }); - } - } - super.onCreateContextMenu(menu); -} \ No newline at end of file diff --git a/NotesListActivity.java b/NotesListActivity.java deleted file mode 100644 index 2c07c20..0000000 --- a/NotesListActivity.java +++ /dev/null @@ -1,368 +0,0 @@ -/* - * Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net) - * - * 根据Apache License, Version 2.0(以下简称“许可证”)授权; - * 您可能不会使用此文件,除非遵守许可证。 - * 您可以在以下网址获得许可证的副本: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 除非适用法律要求或书面同意,否则按照许可证分发的软件 - * 按“原样”分发,不附带任何明示或暗示的保证或条件。 - * 请参阅控制权限和许可证下的限制的具体语言的许可证。 - */ - -package net.micode.notes.ui; - -import android.app.Activity; -import android.app.AlertDialog; -import android.app.Dialog; -import android.appwidget.AppWidgetManager; -import android.content.AsyncQueryHandler; -import android.content.ContentResolver; -import android.content.ContentValues; -import android.content.Context; -import android.content.DialogInterface; -import android.content.Intent; -import android.content.SharedPreferences; -import android.database.Cursor; -import android.os.AsyncTask; -import android.os.Bundle; -import android.preference.PreferenceManager; -import android.text.Editable; -import android.text.TextUtils; -import android.text.TextWatcher; -import android.util.Log; -import android.view.ActionMode; -import android.view.ContextMenu; -import android.view.Display; -import android.view.HapticFeedbackConstants; -import android.view.LayoutInflater; -import android.view.Menu; -import android.view.MenuItem; -import android.view.MenuItem.OnMenuItemClickListener; -import android.view.MotionEvent; -import android.view.View; -import android.view.View.OnClickListener; -import android.view.View.OnCreateContextMenuListener; -import android.view.View.OnTouchListener; -import android.view.inputmethod.InputMethodManager; -import android.widget.AdapterView; -import android.widget.AdapterView.OnItemClickListener; -import android.widget.AdapterView.OnItemLongClickListener; -import android.widget.Button; -import android.widget.EditText; -import android.widget.ListView; -import android.widget.PopupMenu; -import android.widget.TextView; -import android.widget.Toast; - -import net.micode.notes.R; -import net.micode.notes.data.Notes; -import net.micode.notes.data.Notes.NoteColumns; -import net.micode.notes.gtask.remote.GTaskSyncService; -import net.micode.notes.model.WorkingNote; -import net.micode.notes.tool.BackupUtils; -import net.micode.notes.tool.DataUtils; -import net.micode.notes.tool.ResourceParser; -import net.micode.notes.ui.NotesListAdapter.AppWidgetAttribute; -import net.micode.notes.widget.NoteWidgetProvider_2x; -import net.micode.notes.widget.NoteWidgetProvider_4x; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.util.HashSet; - -// NotesListActivity 是一个用于显示便签列表的 Activity。 -public class NotesListActivity extends Activity implements OnClickListener, OnItemLongClickListener { - // 定义查询令牌,用于处理数据库查询。 - private static final int FOLDER_NOTE_LIST_QUERY_TOKEN = 0; - private static final int FOLDER_LIST_QUERY_TOKEN = 1; - - // 定义菜单项的常量。 - private static final int MENU_FOLDER_DELETE = 0; - private static final int MENU_FOLDER_VIEW = 1; - private static final int MENU_FOLDER_CHANGE_NAME = 2; - - // 定义 SharedPreferences 中保存的“添加介绍”的键。 - private static final String PREFERENCE_ADD_INTRODUCTION = "net.micode.notes.introduction"; - - // 枚举类,表示当前列表的编辑状态。 - private enum ListEditState { - NOTE_LIST, SUB_FOLDER, CALL_RECORD_FOLDER - }; - - private ListEditState mState; - - // 后台查询处理器。 - private BackgroundQueryHandler mBackgroundQueryHandler; - // 便签列表适配器。 - private NotesListAdapter mNotesListAdapter; - // 便签列表视图。 - private ListView mNotesListView; - // 添加新便签的按钮。 - private Button mAddNewNote; - // 处理触摸事件的变量。 - private boolean mDispatch; - private int mOriginY; - private int mDispatchY; - // 标题栏。 - private TextView mTitleBar; - // 当前文件夹ID。 - private long mCurrentFolderId; - // 内容解析器。 - private ContentResolver mContentResolver; - // 模式回调。 - private ModeCallback mModeCallBack; - // 日志标签。 - private static final String TAG = "NotesListActivity"; - - // 便签列表视图滚动速率。 - public static final int NOTES_LISTVIEW_SCROLL_RATE = 30; - // 焦点便签数据项。 - private NoteItemData mFocusNoteDataItem; - // 普通选择和根文件夹选择的SQL语句。 - private static final String NORMAL_SELECTION = NoteColumns.PARENT_ID + "=?"; - private static final String ROOT_FOLDER_SELECTION = "(" + NoteColumns.TYPE + "<>" - + Notes.TYPE_SYSTEM + " AND " + NoteColumns.PARENT_ID + "=?)" + " OR (" - + NoteColumns.ID + "=" + Notes.ID_CALL_RECORD_FOLDER + " AND " - + NoteColumns.NOTES_COUNT + ">0)"; - - // 请求代码常量。 - private final static int REQUEST_CODE_OPEN_NODE = 102; - private final static int REQUEST_CODE_NEW_NODE = 103; - - // onCreate 方法,初始化 Activity。 - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.note_list); - initResources(); - - /** - * 当用户首次使用此应用程序时插入介绍。 - */ - setAppInfoFromRawRes(); - } - - // onActivityResult 方法,处理 Activity 结果。 - @Override - protected void onActivityResult(int requestCode, int resultCode, Intent data) { - if (resultCode == RESULT_OK - && (requestCode == REQUEST_CODE_OPEN_NODE || requestCode == REQUEST_CODE_NEW_NODE)) { - mNotesListAdapter.changeCursor(null); - } else { - super.onActivityResult(requestCode, resultCode, data); - } - } - - // 从 raw 资源文件中设置应用程序信息。 - private void setAppInfoFromRawRes() { - SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this); - if (!sp.getBoolean(PREFERENCE_ADD_INTRODUCTION, false)) { - StringBuilder sb = new StringBuilder(); - InputStream in = null; - try { - in = getResources().openRawResource(R.raw.introduction); - if (in != null) { - InputStreamReader isr = new InputStreamReader(in); - BufferedReader br = new BufferedReader(isr); - char [] buf = new char[1024]; - int len = 0; - while ((len = br.read(buf)) > 0) { - sb.append(buf, 0, len); - } - } else { - Log.e(TAG, "Read introduction file error"); - return; - } - } catch (IOException e) { - e.printStackTrace(); - return; - } finally { - if(in != null) { - try { - in.close(); - } catch (IOException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - } - } - - WorkingNote note = WorkingNote.createEmptyNote(this, Notes.ID_ROOT_FOLDER, - AppWidgetManager.INVALID_APPWIDGET_ID, Notes.TYPE_WIDGET_INVALIDE, - ResourceParser.RED); - note.setWorkingText(sb.toString()); - if (note.saveNote()) { - sp.edit().putBoolean(PREFERENCE_ADD_INTRODUCTION, true).commit(); - } else { - Log.e(TAG, "Save introduction note error"); - return; - } - } - } -} -/** - * 当 Activity 开始时调用此方法。 - */ -@Override -protected void onStart() { - super.onStart(); // 调用父类的 onStart 方法。 - startAsyncNotesListQuery(); // 开始异步查询便签列表。 -} - -/** - * 初始化资源的方法。 - */ -private void initResources() { - mContentResolver = this.getContentResolver(); // 获取内容解析器。 - mBackgroundQueryHandler = new BackgroundQueryHandler(this.getContentResolver()); // 创建后台查询处理器。 - mCurrentFolderId = Notes.ID_ROOT_FOLDER; // 设置当前文件夹ID为根文件夹。 - mNotesListView = (ListView) findViewById(R.id.notes_list); // 获取便签列表视图。 - mNotesListView.addFooterView(LayoutInflater.from(this).inflate(R.layout.note_list_footer, null), null, false); // 添加列表底部视图。 - mNotesListView.setOnItemClickListener(new OnListItemClickListener()); // 设置列表项点击事件监听器。 - mNotesListView.setOnItemLongClickListener(this); // 设置列表项长按事件监听器。 - mNotesListAdapter = new NotesListAdapter(this); // 创建便签列表适配器。 - mNotesListView.setAdapter(mNotesListAdapter); // 设置列表适配器。 - mAddNewNote = (Button) findViewById(R.id.btn_new_note); // 获取添加新便签的按钮。 - mAddNewNote.setOnClickListener(this); // 设置按钮点击事件监听器。 - mAddNewNote.setOnTouchListener(new NewNoteOnTouchListener()); // 设置按钮触摸事件监听器。 - mDispatch = false; // 初始化 dispatch 变量。 - mDispatchY = 0; // 初始化 dispatchY 变量。 - mOriginY = 0; // 初始化 originY 变量。 - mTitleBar = (TextView) findViewById(R.id.tv_title_bar); // 获取标题栏。 - mState = ListEditState.NOTE_LIST; // 初始化列表编辑状态。 - mModeCallBack = new ModeCallback(); // 创建模式回调对象。 -} - -/** - * ModeCallback 内部类,实现 ListView 多选模式监听器和菜单项点击事件。 - */ -private class ModeCallback implements ListView.MultiChoiceModeListener, OnMenuItemClickListener { - private DropdownMenu mDropDownMenu; // 下拉菜单。 - private ActionMode mActionMode; // 动作模式。 - private MenuItem mMoveMenu; // 移动菜单项。 - - /** - * 创建动作模式时调用。 - * @param mode 动作模式。 - * @param menu 菜单。 - * @return 是否创建成功。 - */ - public boolean onCreateActionMode(ActionMode mode, Menu menu) { - // 省略部分代码... - } - - /** - * 更新菜单项。 - */ - private void updateMenu() { - // 省略部分代码... - } - - /** - * 准备动作模式时调用。 - * @param mode 动作模式。 - * @param menu 菜单。 - * @return 是否准备成功。 - */ - public boolean onPrepareActionMode(ActionMode mode, Menu menu) { - // TODO Auto-generated method stub - return false; - } - - /** - * 动作模式中的菜单项被点击时调用。 - * @param mode 动作模式。 - * @param item 菜单项。 - * @return 是否处理成功。 - */ - public boolean onActionItemClicked(ActionMode mode, MenuItem item) { - // TODO Auto-generated method stub - return false; - } - - /** - * 动作模式销毁时调用。 - * @param mode 动作模式。 - */ - public void onDestroyActionMode(ActionMode mode) { - // 省略部分代码... - } - - /** - * 结束动作模式。 - */ - public void finishActionMode() { - mActionMode.finish(); - } - - /** - * 列表项选中状态改变时调用。 - * @param mode 动作模式。 - * @param position 位置。 - * @param id ID。 - * @param checked 是否选中。 - */ - public void onItemCheckedStateChanged(ActionMode mode, int position, long id, boolean checked) { - // 省略部分代码... - } - - /** - * 菜单项点击事件。 - * @param item 菜单项。 - * @return 是否处理成功。 - */ - public boolean onMenuItemClick(MenuItem item) { - // 省略部分代码... - } -} - -/** - * NewNoteOnTouchListener 内部类,处理添加新便签按钮的触摸事件。 - */ -private class NewNoteOnTouchListener implements OnTouchListener { - /** - * 触摸事件处理。 - * @param v 视图。 - * @param event 触摸事件。 - * @return 是否处理成功。 - */ - public boolean onTouch(View v, MotionEvent event) { - // 省略部分代码... - } -} - -/** - * 开始异步查询便签列表。 - */ -private void startAsyncNotesListQuery() { - // 省略部分代码... -} - -/** - * BackgroundQueryHandler 内部类,继承自 AsyncQueryHandler,处理后台查询。 - */ -private final class BackgroundQueryHandler extends AsyncQueryHandler { - /** - * 构造函数。 - * @param contentResolver 内容解析器。 - */ - public BackgroundQueryHandler(ContentResolver contentResolver) { - super(contentResolver); - } - - /** - * 查询完成时调用。 - * @param token 令牌。 - * @param cookie 饼干。 - * @param cursor 游标。 - */ - @Override - protected void onQueryComplete(int token, Object cookie, Cursor cursor) { - // 省略部分代码... - } -} \ No newline at end of file