From 2f7cda36158b2988c334c879e2c6d94495bf3f85 Mon Sep 17 00:00:00 2001 From: zhangjinhan <2403497099@qq.com> Date: Sat, 28 Dec 2024 09:10:40 +0800 Subject: [PATCH] =?UTF-8?q?ui=E6=96=87=E4=BB=B6=E5=A4=B9=E4=B8=AD=E6=89=80?= =?UTF-8?q?=E6=9C=89=E4=BB=A3=E7=A0=81=E5=B7=B2=E7=BB=8F=E4=BF=AE=E6=94=B9?= =?UTF-8?q?=E5=AE=8C=E6=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../micode/notes/ui/DateTimePickerDialog.java | 37 ++- .../src/net/micode/notes/ui/DropdownMenu.java | 29 +- .../micode/notes/ui/FoldersListAdapter.java | 13 +- .../net/micode/notes/ui/NoteEditActivity.java | 282 ++++++++---------- .../src/net/micode/notes/ui/NoteEditText.java | 66 ++-- .../src/net/micode/notes/ui/NoteItemData.java | 99 +++--- .../micode/notes/ui/NotesListActivity.java | 6 +- .../net/micode/notes/ui/NotesListAdapter.java | 64 ++-- .../net/micode/notes/ui/NotesListItem.java | 30 +- .../notes/ui/NotesPreferenceActivity.java | 146 +++++---- 10 files changed, 424 insertions(+), 348 deletions(-) diff --git a/Notes-master/src/net/micode/notes/ui/DateTimePickerDialog.java b/Notes-master/src/net/micode/notes/ui/DateTimePickerDialog.java index 2c47ba4..e3c2eb4 100644 --- a/Notes-master/src/net/micode/notes/ui/DateTimePickerDialog.java +++ b/Notes-master/src/net/micode/notes/ui/DateTimePickerDialog.java @@ -13,33 +13,40 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - + package net.micode.notes.ui; - + import java.util.Calendar; - + import net.micode.notes.R; import net.micode.notes.ui.DateTimePicker; import net.micode.notes.ui.DateTimePicker.OnDateTimeChangedListener; - + import android.app.AlertDialog; import android.content.Context; import android.content.DialogInterface; import android.content.DialogInterface.OnClickListener; import android.text.format.DateFormat; import android.text.format.DateUtils; - + +// 自定义的日期时间选择对话框,继承自AlertDialog并实现了OnClickListener接口 public class DateTimePickerDialog extends AlertDialog implements OnClickListener { - + + // 存储当前选择的日期时间 private Calendar mDate = Calendar.getInstance(); + // 是否使用24小时制 private boolean mIs24HourView; + // 回调接口,当日期时间设置完成后调用 private OnDateTimeSetListener mOnDateTimeSetListener; + // 日期时间选择器控件 private DateTimePicker mDateTimePicker; - + + // 定义日期时间设置完成后的回调接口 public interface OnDateTimeSetListener { void OnDateTimeSet(AlertDialog dialog, long date); } - + + // 构造函数,初始化对话框并设置初始日期时间 public DateTimePickerDialog(Context context, long date) { super(context); mDateTimePicker = new DateTimePicker(context); @@ -63,15 +70,18 @@ public class DateTimePickerDialog extends AlertDialog implements OnClickListener set24HourView(DateFormat.is24HourFormat(this.getContext())); updateTitle(mDate.getTimeInMillis()); } - + + // 设置是否使用24小时制显示时间 public void set24HourView(boolean is24HourView) { mIs24HourView = is24HourView; } - + + // 设置日期时间选择完成后的回调监听器 public void setOnDateTimeSetListener(OnDateTimeSetListener callBack) { mOnDateTimeSetListener = callBack; } - + + // 更新对话框的标题以显示当前选择的日期时间 private void updateTitle(long date) { int flag = DateUtils.FORMAT_SHOW_YEAR | @@ -80,11 +90,12 @@ public class DateTimePickerDialog extends AlertDialog implements OnClickListener flag |= mIs24HourView ? DateUtils.FORMAT_24HOUR : DateUtils.FORMAT_24HOUR; setTitle(DateUtils.formatDateTime(this.getContext(), date, flag)); } - + + // 处理用户点击对话框按钮的事件,如果是确认按钮则调用回调监听器 public void onClick(DialogInterface arg0, int arg1) { if (mOnDateTimeSetListener != null) { mOnDateTimeSetListener.OnDateTimeSet(this, mDate.getTimeInMillis()); } } - + } \ No newline at end of file diff --git a/Notes-master/src/net/micode/notes/ui/DropdownMenu.java b/Notes-master/src/net/micode/notes/ui/DropdownMenu.java index 613dc74..eb009a2 100644 --- a/Notes-master/src/net/micode/notes/ui/DropdownMenu.java +++ b/Notes-master/src/net/micode/notes/ui/DropdownMenu.java @@ -13,9 +13,9 @@ * 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.view.Menu; import android.view.MenuItem; @@ -24,14 +24,16 @@ import android.view.View.OnClickListener; import android.widget.Button; import android.widget.PopupMenu; import android.widget.PopupMenu.OnMenuItemClickListener; - + import net.micode.notes.R; - + +// 下拉菜单类,用于在按钮点击时显示一个弹出菜单 public class DropdownMenu { - private Button mButton; - private PopupMenu mPopupMenu; - private Menu mMenu; - + private Button mButton; // 用于触发下拉菜单的按钮 + private PopupMenu mPopupMenu; // 弹出菜单对象 + private Menu mMenu; // 菜单对象 + + // 构造函数,初始化下拉菜单,设置按钮背景,并将菜单资源加载到弹出菜单中 public DropdownMenu(Context context, Button button, int menuId) { mButton = button; mButton.setBackgroundResource(R.drawable.dropdown_icon); @@ -44,18 +46,21 @@ public class DropdownMenu { } }); } - + + // 设置下拉菜单项点击监听器 public void setOnDropdownMenuItemClickListener(OnMenuItemClickListener listener) { if (mPopupMenu != null) { mPopupMenu.setOnMenuItemClickListener(listener); } } - + + // 根据菜单项的ID查找菜单项 public MenuItem findItem(int id) { return mMenu.findItem(id); } - + + // 设置按钮的标题 public void setTitle(CharSequence title) { mButton.setText(title); } -} +} \ No newline at end of file diff --git a/Notes-master/src/net/micode/notes/ui/FoldersListAdapter.java b/Notes-master/src/net/micode/notes/ui/FoldersListAdapter.java index 96b77da..1c6a78a 100644 --- a/Notes-master/src/net/micode/notes/ui/FoldersListAdapter.java +++ b/Notes-master/src/net/micode/notes/ui/FoldersListAdapter.java @@ -28,26 +28,31 @@ import net.micode.notes.R; import net.micode.notes.data.Notes; import net.micode.notes.data.Notes.NoteColumns; - +// 自定义的 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 } + // 创建一个新的视图项 @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) { @@ -57,24 +62,28 @@ public class FoldersListAdapter extends CursorAdapter { } } + // 根据位置获取文件夹名称 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); } + // 内部类,定义文件夹列表项的视图结构 private class FolderListItem extends LinearLayout { private TextView mName; + // 构造函数,初始化 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/Notes-master/src/net/micode/notes/ui/NoteEditActivity.java b/Notes-master/src/net/micode/notes/ui/NoteEditActivity.java index 96a9ff8..3e45406 100644 --- a/Notes-master/src/net/micode/notes/ui/NoteEditActivity.java +++ b/Notes-master/src/net/micode/notes/ui/NoteEditActivity.java @@ -13,9 +13,9 @@ * 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; @@ -51,7 +51,7 @@ 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; @@ -64,26 +64,28 @@ 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; - - + +// 笔记编辑界面的Activity类 public class NoteEditActivity extends Activity implements OnClickListener, NoteSettingChangedListener, OnTextViewChangeListener { + // 用于存储笔记头部视图的ViewHolder类 private class HeadViewHolder { public TextView tvModified; - + public ImageView ivAlertIcon; - + public TextView tvAlertDate; - + public ImageView ibSetBgColor; } - + + // 背景色选择按钮和颜色ID的映射 private static final Map sBgSelectorBtnsMap = new HashMap(); static { sBgSelectorBtnsMap.put(R.id.iv_bg_yellow, ResourceParser.YELLOW); @@ -92,7 +94,8 @@ public class NoteEditActivity extends Activity implements OnClickListener, 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); @@ -101,7 +104,8 @@ public class NoteEditActivity extends Activity implements OnClickListener, 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); @@ -109,7 +113,8 @@ public class NoteEditActivity extends Activity implements OnClickListener, 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); @@ -117,54 +122,52 @@ public class NoteEditActivity extends Activity implements OnClickListener, 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"; - + private HeadViewHolder mNoteHeaderHolder; - + private View mHeadViewPanel; - + private View mNoteBgColorSelector; - + private View mFontSizeSelector; - + private EditText mNoteEditor; - + private View mNoteEditorPanel; - + private WorkingNote mWorkingNote; - + private SharedPreferences mSharedPrefs; private int mFontSizeId; - + 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; - + + // 初始化Activity视图 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); this.setContentView(R.layout.note_edit); - + if (savedInstanceState == null && !initActivityState(getIntent())) { finish(); return; } initResources(); } - - /** - * 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 - */ + + // 当Activity被系统杀死后,恢复其状态 @Override protected void onRestoreInstanceState(Bundle savedInstanceState) { super.onRestoreInstanceState(savedInstanceState); @@ -178,25 +181,19 @@ public class NoteEditActivity extends Activity implements OnClickListener, Log.d(TAG, "Restoring from killed activity"); } } - + + // 初始化Activity状态,根据Intent决定加载笔记或创建新笔记 private boolean initActivityState(Intent intent) { - /** - * If the user specified the {@link Intent#ACTION_VIEW} but not provided with id, - * then jump to the NotesListActivity - */ mWorkingNote = null; if (TextUtils.equals(Intent.ACTION_VIEW, intent.getAction())) { long noteId = intent.getLongExtra(Intent.EXTRA_UID, 0); mUserQuery = ""; - - /** - * Starting from the searched result - */ + if (intent.hasExtra(SearchManager.EXTRA_DATA_KEY)) { noteId = Long.parseLong(intent.getStringExtra(SearchManager.EXTRA_DATA_KEY)); mUserQuery = intent.getStringExtra(SearchManager.USER_QUERY); } - + if (!DataUtils.visibleInNoteDatabase(getContentResolver(), noteId, Notes.TYPE_NOTE)) { Intent jump = new Intent(this, NotesListActivity.class); startActivity(jump); @@ -215,7 +212,6 @@ public class NoteEditActivity extends Activity implements OnClickListener, WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN | WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE); } else if(TextUtils.equals(Intent.ACTION_INSERT_OR_EDIT, intent.getAction())) { - // New note long folderId = intent.getLongExtra(Notes.INTENT_EXTRA_FOLDER_ID, 0); int widgetId = intent.getIntExtra(Notes.INTENT_EXTRA_WIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID); @@ -223,8 +219,7 @@ public class NoteEditActivity extends Activity implements OnClickListener, Notes.TYPE_WIDGET_INVALIDE); int bgResId = intent.getIntExtra(Notes.INTENT_EXTRA_BACKGROUND_ID, ResourceParser.getDefaultBgId(this)); - - // Parse call-record note + String phoneNumber = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER); long callDate = intent.getLongExtra(Notes.INTENT_EXTRA_CALL_DATE, 0); if (callDate != 0 && phoneNumber != null) { @@ -249,7 +244,7 @@ public class NoteEditActivity extends Activity implements OnClickListener, mWorkingNote = WorkingNote.createEmptyNote(this, folderId, widgetId, widgetType, bgResId); } - + getWindow().setSoftInputMode( WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE | WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE); @@ -261,13 +256,15 @@ public class NoteEditActivity extends Activity implements OnClickListener, mWorkingNote.setOnSettingStatusChangedListener(this); return true; } - + + // Activity恢复时初始化笔记显示 @Override protected void onResume() { super.onResume(); initNoteScreen(); } - + + // 初始化笔记显示界面,包括背景颜色、字体大小、修改日期等 private void initNoteScreen() { mNoteEditor.setTextAppearance(this, TextAppearanceResources .getTexAppearanceResource(mFontSizeId)); @@ -282,19 +279,16 @@ public class NoteEditActivity extends Activity implements OnClickListener, } 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 | DateUtils.FORMAT_SHOW_YEAR)); - - /** - * TODO: Add the menu for setting alert. Currently disable it because the DateTimePicker - * is not ready - */ + showAlertHeader(); } - + + // 显示或隐藏提醒头部信息 private void showAlertHeader() { if (mWorkingNote.hasClockAlert()) { long time = System.currentTimeMillis(); @@ -311,28 +305,26 @@ public class NoteEditActivity extends Activity implements OnClickListener, mNoteHeaderHolder.ivAlertIcon.setVisibility(View.GONE); }; } - + + // 处理新的Intent,可能需要重新加载笔记或创建新笔记 @Override protected void onNewIntent(Intent intent) { super.onNewIntent(intent); initActivityState(intent); } - + + // 保存Activity状态,在系统需要恢复Activity时使用 @Override protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); - /** - * For new note without note id, we should firstly save it to - * generate a id. If the editing note is not worth saving, there - * is no id which is equivalent to create new note - */ if (!mWorkingNote.existInDatabase()) { saveNote(); } outState.putLong(Intent.EXTRA_UID, mWorkingNote.getNoteId()); Log.d(TAG, "Save working note id: " + mWorkingNote.getNoteId() + " onSaveInstanceState"); } - + + // 处理触摸事件,用于隐藏颜色和字体大小选择面板 @Override public boolean dispatchTouchEvent(MotionEvent ev) { if (mNoteBgColorSelector.getVisibility() == View.VISIBLE @@ -340,7 +332,7 @@ public class NoteEditActivity extends Activity implements OnClickListener, mNoteBgColorSelector.setVisibility(View.GONE); return true; } - + if (mFontSizeSelector.getVisibility() == View.VISIBLE && !inRangeOfView(mFontSizeSelector, ev)) { mFontSizeSelector.setVisibility(View.GONE); @@ -348,7 +340,8 @@ public class NoteEditActivity extends Activity implements OnClickListener, } return super.dispatchTouchEvent(ev); } - + + // 判断触摸事件是否发生在指定视图内 private boolean inRangeOfView(View view, MotionEvent ev) { int []location = new int[2]; view.getLocationOnScreen(location); @@ -362,7 +355,8 @@ public class NoteEditActivity extends Activity implements OnClickListener, } return true; } - + + // 初始化视图资源 private void initResources() { mHeadViewPanel = findViewById(R.id.note_title); mNoteHeaderHolder = new HeadViewHolder(); @@ -378,7 +372,7 @@ public class NoteEditActivity extends Activity implements OnClickListener, ImageView iv = (ImageView) findViewById(id); iv.setOnClickListener(this); } - + mFontSizeSelector = findViewById(R.id.font_size_selector); for (int id : sFontSizeBtnsMap.keySet()) { View view = findViewById(id); @@ -386,17 +380,13 @@ public class NoteEditActivity extends Activity implements OnClickListener, }; mSharedPrefs = PreferenceManager.getDefaultSharedPreferences(this); 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} - */ if(mFontSizeId >= TextAppearanceResources.getResourcesSize()) { mFontSizeId = ResourceParser.BG_DEFAULT_FONT_SIZE; } mEditTextList = (LinearLayout) findViewById(R.id.note_edit_list); } - + + // 暂停Activity时保存笔记并清理设置状态 @Override protected void onPause() { super.onPause(); @@ -405,7 +395,8 @@ public class NoteEditActivity extends Activity implements OnClickListener, } clearSettingState(); } - + + // 更新桌面小部件显示 private void updateWidget() { Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_UPDATE); if (mWorkingNote.getWidgetType() == Notes.TYPE_WIDGET_2X) { @@ -416,21 +407,22 @@ public class NoteEditActivity extends Activity implements OnClickListener, Log.e(TAG, "Unspported widget type"); return; } - + intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, new int[] { mWorkingNote.getWidgetId() }); - + sendBroadcast(intent); setResult(RESULT_OK, intent); } - + + // 处理视图点击事件,包括颜色和字体大小选择 public void onClick(View v) { 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.VISIBLE); } else if (sBgSelectorBtnsMap.containsKey(id)) { findViewById(sBgSelectorSelectionMap.get(mWorkingNote.getBgColorId())).setVisibility( View.GONE); @@ -451,17 +443,19 @@ public class NoteEditActivity extends Activity implements OnClickListener, mFontSizeSelector.setVisibility(View.GONE); } } - + + // 处理返回键事件,如果设置面板可见则隐藏,否则保存笔记后返回 @Override public void onBackPressed() { if(clearSettingState()) { return; } - + saveNote(); super.onBackPressed(); } - + + // 清理设置面板状态 private boolean clearSettingState() { if (mNoteBgColorSelector.getVisibility() == View.VISIBLE) { mNoteBgColorSelector.setVisibility(View.GONE); @@ -472,14 +466,16 @@ public class NoteEditActivity extends Activity implements OnClickListener, } return false; } - + + // 处理笔记背景颜色变化事件 public void onBackgroundColorChanged() { findViewById(sBgSelectorSelectionMap.get(mWorkingNote.getBgColorId())).setVisibility( View.VISIBLE); mNoteEditorPanel.setBackgroundResource(mWorkingNote.getBgColorResId()); mHeadViewPanel.setBackgroundResource(mWorkingNote.getTitleBgResId()); } - + + // 准备选项菜单,根据笔记状态动态更新菜单项 @Override public boolean onPrepareOptionsMenu(Menu menu) { if (isFinishing()) { @@ -504,7 +500,8 @@ public class NoteEditActivity extends Activity implements OnClickListener, } return true; } - + + // 处理选项菜单项点击事件 @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { @@ -552,7 +549,8 @@ public class NoteEditActivity extends Activity implements OnClickListener, } return true; } - + + // 设置提醒时间 private void setReminder() { DateTimePickerDialog d = new DateTimePickerDialog(this, System.currentTimeMillis()); d.setOnDateTimeSetListener(new OnDateTimeSetListener() { @@ -562,30 +560,27 @@ public class NoteEditActivity extends Activity implements OnClickListener, }); d.show(); } - - /** - * Share note to apps that support {@link Intent#ACTION_SEND} action - * and {@text/plain} type - */ + + // 分享笔记内容到支持ACTION_SEND的其他应用 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() { - // 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 ids = new HashSet(); @@ -607,16 +602,14 @@ public class NoteEditActivity extends Activity implements OnClickListener, } mWorkingNote.markDeleted(true); } - + + // 判断是否处于同步模式 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(); } @@ -632,31 +625,28 @@ public class NoteEditActivity extends Activity implements OnClickListener, alarmManager.set(AlarmManager.RTC_WAKEUP, date, pendingIntent); } } else { - /** - * There is the condition that user has input nothing (the note is - * not worthy saving), we have no note id, remind the user that he - * should input something - */ Log.e(TAG, "Clock alert setting error"); showToast(R.string.error_note_empty_for_clock); } } - + + // 处理小部件变化事件,更新小部件显示 public void onWidgetChanged() { updateWidget(); } - + + // 处理EditText删除事件,调整列表项索引 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; if(index == 0) { @@ -671,15 +661,13 @@ public class NoteEditActivity extends Activity implements OnClickListener, edit.requestFocus(); edit.setSelection(length); } - + + // 处理EditText输入事件,添加新列表项 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"); } - + View view = getListItem(text, index); mEditTextList.addView(view, index); NoteEditText edit = (NoteEditText) view.findViewById(R.id.et_edit_text); @@ -690,7 +678,8 @@ public class NoteEditActivity extends Activity implements OnClickListener, .setIndex(i); } } - + + // 切换到列表模式,根据笔记内容生成列表项 private void switchToListMode(String text) { mEditTextList.removeAllViews(); String[] items = text.split("\n"); @@ -703,11 +692,12 @@ public class NoteEditActivity extends Activity implements OnClickListener, } mEditTextList.addView(getListItem("", index)); 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 spannable = new SpannableString(fullText == null ? "" : fullText); if (!TextUtils.isEmpty(userQuery)) { @@ -724,7 +714,8 @@ public class NoteEditActivity extends Activity implements OnClickListener, } return spannable; } - + + // 生成一个新的列表项视图 private View getListItem(String item, int index) { View view = LayoutInflater.from(this).inflate(R.layout.note_edit_list_item, null); final NoteEditText edit = (NoteEditText) view.findViewById(R.id.et_edit_text); @@ -739,7 +730,7 @@ public class NoteEditActivity extends Activity implements OnClickListener, } } }); - + if (item.startsWith(TAG_CHECKED)) { cb.setChecked(true); edit.setPaintFlags(edit.getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG); @@ -749,13 +740,14 @@ public class NoteEditActivity extends Activity implements OnClickListener, edit.setPaintFlags(Paint.ANTI_ALIAS_FLAG | Paint.DEV_KERN_TEXT_FLAG); item = item.substring(TAG_UNCHECKED.length(), item.length()).trim(); } - + edit.setOnTextViewChangeListener(this); edit.setIndex(index); edit.setText(getHighlightQueryResult(item, mUserQuery)); return view; } - + + // 处理EditText文本变化事件,显示或隐藏复选框 public void onTextChange(int index, boolean hasText) { if (index >= mEditTextList.getChildCount()) { Log.e(TAG, "Wrong index, should not happen"); @@ -767,7 +759,8 @@ public class NoteEditActivity extends Activity implements OnClickListener, 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()); @@ -781,7 +774,8 @@ public class NoteEditActivity extends Activity implements OnClickListener, mNoteEditor.setVisibility(View.VISIBLE); } } - + + // 获取正在编辑的文本内容,根据列表模式添加标签 private boolean getWorkingText() { boolean hasChecked = false; if (mWorkingNote.getCheckListMode() == TextNote.MODE_CHECK_LIST) { @@ -804,33 +798,23 @@ public class NoteEditActivity extends Activity implements OnClickListener, } return hasChecked; } - + + // 保存笔记内容到数据库 private boolean saveNote() { getWorkingText(); boolean saved = mWorkingNote.saveNote(); if (saved) { - /** - * There are two modes from List view to edit view, open one note, - * create/edit a node. Opening node requires to the original - * position in the list when back from edit view, while creating a - * new node requires to the top of the list. This code - * {@link #RESULT_OK} is used to identify the create/edit state - */ setResult(RESULT_OK); } 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 - */ if (!mWorkingNote.existInDatabase()) { saveNote(); } - + if (mWorkingNote.getNoteId() > 0) { Intent sender = new Intent(); Intent shortcutIntent = new Intent(this, NoteEditActivity.class); @@ -846,28 +830,26 @@ public class NoteEditActivity extends Activity implements OnClickListener, showToast(R.string.info_note_enter_desktop); sendBroadcast(sender); } else { - /** - * There is the condition that user has input nothing (the note is - * not worthy saving), we have no note id, remind the user that he - * should input something - */ Log.e(TAG, "Send to desktop error"); showToast(R.string.error_note_empty_for_send_to_desktop); } } - + + // 生成桌面快捷方式的标题,截取笔记内容的一部分作为标题 private String makeShortcutIconTitle(String content) { content = content.replace(TAG_CHECKED, ""); 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(); } -} +} \ No newline at end of file diff --git a/Notes-master/src/net/micode/notes/ui/NoteEditText.java b/Notes-master/src/net/micode/notes/ui/NoteEditText.java index 2afe2a8..d350c57 100644 --- a/Notes-master/src/net/micode/notes/ui/NoteEditText.java +++ b/Notes-master/src/net/micode/notes/ui/NoteEditText.java @@ -13,9 +13,9 @@ * 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; @@ -31,28 +31,29 @@ 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; - + +// 自定义的EditText,用于笔记应用中,支持删除、添加文本事件监听 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 */ @@ -62,65 +63,69 @@ public class NoteEditText extends EditText { * 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); } - + private OnTextViewChangeListener mOnTextViewChangeListener; - + public NoteEditText(Context context) { super(context, null); mIndex = 0; } - + + // 设置当前文本框的索引 public void setIndex(int index) { mIndex = index; } - + + // 设置文本变化监听器 public void setOnTextViewChangeListener(OnTextViewChangeListener listener) { mOnTextViewChangeListener = listener; } - + public NoteEditText(Context context, AttributeSet attrs) { super(context, attrs, android.R.attr.editTextStyle); } - + 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); } - + + // 处理按键按下事件,记录删除操作前的光标位置 @Override public boolean onKeyDown(int keyCode, KeyEvent event) { switch (keyCode) { @@ -137,7 +142,8 @@ public class NoteEditText extends EditText { } return super.onKeyDown(keyCode, event); } - + + // 处理按键弹起事件,根据按键类型执行相应操作 @Override public boolean onKeyUp(int keyCode, KeyEvent event) { switch(keyCode) { @@ -166,7 +172,8 @@ public class NoteEditText extends EditText { } return super.onKeyUp(keyCode, event); } - + + // 当EditText焦点发生变化时调用,通知监听器文本是否有内容 @Override protected void onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect) { if (mOnTextViewChangeListener != null) { @@ -178,16 +185,17 @@ public class NoteEditText extends EditText { } super.onFocusChanged(focused, direction, previouslyFocusedRect); } - + + // 创建上下文菜单,处理URL点击事件 @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; @@ -197,11 +205,11 @@ public class NoteEditText extends EditText { break; } } - + if (defaultResId == 0) { defaultResId = R.string.note_link_other; } - + menu.add(0, 0, 0, defaultResId).setOnMenuItemClickListener( new OnMenuItemClickListener() { public boolean onMenuItemClick(MenuItem item) { @@ -214,4 +222,4 @@ public class NoteEditText extends EditText { } super.onCreateContextMenu(menu); } -} +} \ No newline at end of file diff --git a/Notes-master/src/net/micode/notes/ui/NoteItemData.java b/Notes-master/src/net/micode/notes/ui/NoteItemData.java index 0f5a878..632fe29 100644 --- a/Notes-master/src/net/micode/notes/ui/NoteItemData.java +++ b/Notes-master/src/net/micode/notes/ui/NoteItemData.java @@ -13,19 +13,19 @@ * 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.text.TextUtils; - + import net.micode.notes.data.Contact; import net.micode.notes.data.Notes; import net.micode.notes.data.Notes.NoteColumns; import net.micode.notes.tool.DataUtils; - - + +// 该类用于从数据库游标中提取笔记项数据,并处理与笔记位置相关的逻辑 public class NoteItemData { static final String [] PROJECTION = new String [] { NoteColumns.ID, @@ -41,7 +41,8 @@ public class NoteItemData { NoteColumns.WIDGET_ID, NoteColumns.WIDGET_TYPE, }; - + + // 定义了游标中各个列的索引位置 private static final int ID_COLUMN = 0; private static final int ALERTED_DATE_COLUMN = 1; private static final int BG_COLOR_ID_COLUMN = 2; @@ -54,7 +55,8 @@ public class NoteItemData { private static final int TYPE_COLUMN = 9; private static final int WIDGET_ID_COLUMN = 10; private static final int WIDGET_TYPE_COLUMN = 11; - + + // 笔记项的各种属性 private long mId; private long mAlertDate; private int mBgColorId; @@ -69,13 +71,15 @@ public class NoteItemData { private int mWidgetType; private String mName; private String mPhoneNumber; - + + // 笔记项在列表中的位置信息 private boolean mIsLastItem; private boolean mIsFirstItem; private boolean mIsOnlyOneItem; private boolean mIsOneNoteFollowingFolder; private boolean mIsMultiNotesFollowingFolder; - + + // 构造函数,从游标中提取笔记项数据 public NoteItemData(Context context, Cursor cursor) { mId = cursor.getLong(ID_COLUMN); mAlertDate = cursor.getLong(ALERTED_DATE_COLUMN); @@ -91,7 +95,7 @@ public class NoteItemData { mType = cursor.getInt(TYPE_COLUMN); mWidgetId = cursor.getInt(WIDGET_ID_COLUMN); mWidgetType = cursor.getInt(WIDGET_TYPE_COLUMN); - + mPhoneNumber = ""; if (mParentId == Notes.ID_CALL_RECORD_FOLDER) { mPhoneNumber = DataUtils.getCallNumberByNoteId(context.getContentResolver(), mId); @@ -102,20 +106,21 @@ public class NoteItemData { } } } - + if (mName == null) { mName = ""; } checkPostion(cursor); } - + + // 检查笔记项在列表中的位置信息 private void checkPostion(Cursor cursor) { mIsLastItem = cursor.isLast() ? true : false; mIsFirstItem = cursor.isFirst() ? true : false; mIsOnlyOneItem = (cursor.getCount() == 1); mIsMultiNotesFollowingFolder = false; mIsOneNoteFollowingFolder = false; - + if (mType == Notes.TYPE_NOTE && !mIsFirstItem) { int position = cursor.getPosition(); if (cursor.moveToPrevious()) { @@ -133,92 +138,114 @@ public class NoteItemData { } } } - + + // 判断该笔记项是否是单个笔记跟在一个文件夹后 public boolean isOneFollowingFolder() { return mIsOneNoteFollowingFolder; } - + + // 判断该笔记项是否是多个笔记跟在一个文件夹后 public boolean isMultiFollowingFolder() { return mIsMultiNotesFollowingFolder; } - + + // 判断该笔记项是否是列表中的最后一个项 public boolean isLast() { return mIsLastItem; } - + + // 获取与该笔记项关联的呼叫记录的联系人名称 public String getCallName() { return mName; } - + + // 判断该笔记项是否是列表中的第一个项 public boolean isFirst() { return mIsFirstItem; } - + + // 判断该笔记项是否是列表中唯一的项 public boolean isSingle() { return mIsOnlyOneItem; } - + + // 获取笔记项的ID public long getId() { return mId; } - + + // 获取笔记项的提醒日期 public long getAlertDate() { return mAlertDate; } - + + // 获取笔记项的创建日期 public long getCreatedDate() { return mCreatedDate; } - + + // 判断该笔记项是否有附件 public boolean hasAttachment() { return mHasAttachment; } - + + // 获取笔记项的修改日期 public long getModifiedDate() { return mModifiedDate; } - + + // 获取笔记项的背景颜色ID public int getBgColorId() { return mBgColorId; } - + + // 获取笔记项的父ID public long getParentId() { return mParentId; } - + + // 获取笔记项包含的笔记数量 public int getNotesCount() { return mNotesCount; } - + + // 获取笔记项所在的文件夹ID public long getFolderId () { return mParentId; } - + + // 获取笔记项的类型 public int getType() { return mType; } - + + // 获取笔记项的小部件类型 public int getWidgetType() { return mWidgetType; } - + + // 获取笔记项的小部件ID public int getWidgetId() { return mWidgetId; } - + + // 获取笔记项的摘要 public String getSnippet() { return mSnippet; } - + + // 判断该笔记项是否有提醒 public boolean hasAlert() { return (mAlertDate > 0); } - + + // 判断该笔记项是否是呼叫记录类型 public boolean isCallRecord() { return (mParentId == Notes.ID_CALL_RECORD_FOLDER && !TextUtils.isEmpty(mPhoneNumber)); } - + + // 静态方法,从游标中获取笔记项的类型 public static int getNoteType(Cursor cursor) { return cursor.getInt(TYPE_COLUMN); } -} +} \ No newline at end of file diff --git a/Notes-master/src/net/micode/notes/ui/NotesListActivity.java b/Notes-master/src/net/micode/notes/ui/NotesListActivity.java index e843aec..5893567 100644 --- a/Notes-master/src/net/micode/notes/ui/NotesListActivity.java +++ b/Notes-master/src/net/micode/notes/ui/NotesListActivity.java @@ -126,12 +126,12 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt private NoteItemData mFocusNoteDataItem; 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; @@ -951,4 +951,4 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt } return false; } -} +} \ No newline at end of file diff --git a/Notes-master/src/net/micode/notes/ui/NotesListAdapter.java b/Notes-master/src/net/micode/notes/ui/NotesListAdapter.java index 51c9cb9..fc77697 100644 --- a/Notes-master/src/net/micode/notes/ui/NotesListAdapter.java +++ b/Notes-master/src/net/micode/notes/ui/NotesListAdapter.java @@ -13,48 +13,52 @@ * 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.util.Log; import android.view.View; import android.view.ViewGroup; import android.widget.CursorAdapter; - + import net.micode.notes.data.Notes; - + import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; - - + +// 自定义的CursorAdapter,用于显示笔记列表 public class NotesListAdapter extends CursorAdapter { private static final String TAG = "NotesListAdapter"; private Context mContext; private HashMap mSelectedIndex; private int mNotesCount; private boolean mChoiceMode; - + + // 用于存储小部件属性的内部类 public static class AppWidgetAttribute { public int widgetId; public int widgetType; }; - + + // 构造函数,初始化上下文和选择索引 public NotesListAdapter(Context context) { super(context, null); mSelectedIndex = new HashMap(); mContext = context; mNotesCount = 0; } - + + // 创建新的视图项 @Override public View newView(Context context, Cursor cursor, ViewGroup parent) { return new NotesListItem(context); } - + + // 绑定数据到视图项 @Override public void bindView(View view, Context context, Cursor cursor) { if (view instanceof NotesListItem) { @@ -63,21 +67,25 @@ public class NotesListAdapter extends CursorAdapter { isSelectedItem(cursor.getPosition())); } } - + + // 设置指定位置的项是否被选中,并通知数据集发生变化 public void setCheckedItem(final int position, final boolean checked) { mSelectedIndex.put(position, checked); notifyDataSetChanged(); } - + + // 检查当前是否处于多选模式 public boolean isInChoiceMode() { return mChoiceMode; } - + + // 设置多选模式,清空选择索引 public void setChoiceMode(boolean mode) { mSelectedIndex.clear(); mChoiceMode = mode; } - + + // 全选或全不选所有笔记 public void selectAll(boolean checked) { Cursor cursor = getCursor(); for (int i = 0; i < getCount(); i++) { @@ -88,7 +96,8 @@ public class NotesListAdapter extends CursorAdapter { } } } - + + // 获取所有选中的笔记ID集合 public HashSet getSelectedItemIds() { HashSet itemSet = new HashSet(); for (Integer position : mSelectedIndex.keySet()) { @@ -101,10 +110,11 @@ public class NotesListAdapter extends CursorAdapter { } } } - + return itemSet; } - + + // 获取所有选中的小部件属性集合 public HashSet getSelectedWidget() { HashSet itemSet = new HashSet(); for (Integer position : mSelectedIndex.keySet()) { @@ -127,7 +137,8 @@ public class NotesListAdapter extends CursorAdapter { } return itemSet; } - + + // 获取选中的笔记数量 public int getSelectedCount() { Collection values = mSelectedIndex.values(); if (null == values) { @@ -142,31 +153,36 @@ public class NotesListAdapter extends CursorAdapter { } return count; } - + + // 检查是否所有笔记都被选中 public boolean isAllSelected() { int checkedCount = getSelectedCount(); return (checkedCount != 0 && checkedCount == mNotesCount); } - + + // 检查指定位置的项是否被选中 public boolean isSelectedItem(final int position) { if (null == mSelectedIndex.get(position)) { return false; } return mSelectedIndex.get(position); } - + + // 当数据内容发生变化时,更新笔记数量 @Override protected void onContentChanged() { super.onContentChanged(); calcNotesCount(); } - + + // 更改Cursor时,更新笔记数量 @Override public void changeCursor(Cursor cursor) { super.changeCursor(cursor); calcNotesCount(); } - + + // 计算笔记数量 private void calcNotesCount() { mNotesCount = 0; for (int i = 0; i < getCount(); i++) { @@ -181,4 +197,4 @@ public class NotesListAdapter extends CursorAdapter { } } } -} +} \ No newline at end of file diff --git a/Notes-master/src/net/micode/notes/ui/NotesListItem.java b/Notes-master/src/net/micode/notes/ui/NotesListItem.java index 1221e80..1546bbe 100644 --- a/Notes-master/src/net/micode/notes/ui/NotesListItem.java +++ b/Notes-master/src/net/micode/notes/ui/NotesListItem.java @@ -13,9 +13,9 @@ * 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.text.format.DateUtils; import android.view.View; @@ -23,13 +23,13 @@ import android.widget.CheckBox; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.TextView; - + import net.micode.notes.R; import net.micode.notes.data.Notes; import net.micode.notes.tool.DataUtils; import net.micode.notes.tool.ResourceParser.NoteItemBgResources; - - + +// NotesListItem 类继承自 LinearLayout,用于表示笔记列表中的一个项 public class NotesListItem extends LinearLayout { private ImageView mAlert; private TextView mTitle; @@ -37,7 +37,8 @@ public class NotesListItem extends LinearLayout { private TextView mCallName; private NoteItemData mItemData; private CheckBox mCheckBox; - + + // 构造函数,初始化 NotesListItem 的视图组件 public NotesListItem(Context context) { super(context); inflate(context, R.layout.note_item, this); @@ -47,7 +48,8 @@ public class NotesListItem extends LinearLayout { mCallName = (TextView) findViewById(R.id.tv_name); mCheckBox = (CheckBox) findViewById(android.R.id.checkbox); } - + + // 绑定数据到 NotesListItem 的视图组件,并设置选择模式和选中状态 public void bind(Context context, NoteItemData data, boolean choiceMode, boolean checked) { if (choiceMode && data.getType() == Notes.TYPE_NOTE) { mCheckBox.setVisibility(View.VISIBLE); @@ -55,7 +57,7 @@ public class NotesListItem extends LinearLayout { } else { mCheckBox.setVisibility(View.GONE); } - + mItemData = data; if (data.getId() == Notes.ID_CALL_RECORD_FOLDER) { mCallName.setVisibility(View.GONE); @@ -78,7 +80,7 @@ public class NotesListItem extends LinearLayout { } else { mCallName.setVisibility(View.GONE); mTitle.setTextAppearance(context, R.style.TextAppearancePrimaryItem); - + if (data.getType() == Notes.TYPE_FOLDER) { mTitle.setText(data.getSnippet() + context.getString(R.string.format_folder_files_count, @@ -95,10 +97,11 @@ public class NotesListItem extends LinearLayout { } } mTime.setText(DateUtils.getRelativeTimeSpanString(data.getModifiedDate())); - + setBackground(data); } - + + // 根据数据设置 NotesListItem 的背景资源 private void setBackground(NoteItemData data) { int id = data.getBgColorId(); if (data.getType() == Notes.TYPE_NOTE) { @@ -115,8 +118,9 @@ public class NotesListItem extends LinearLayout { setBackgroundResource(NoteItemBgResources.getFolderBgRes()); } } - + + // 获取绑定到此 NotesListItem 的数据 public NoteItemData getItemData() { return mItemData; } -} +} \ No newline at end of file diff --git a/Notes-master/src/net/micode/notes/ui/NotesPreferenceActivity.java b/Notes-master/src/net/micode/notes/ui/NotesPreferenceActivity.java index 07c5f7e..48125be 100644 --- a/Notes-master/src/net/micode/notes/ui/NotesPreferenceActivity.java +++ b/Notes-master/src/net/micode/notes/ui/NotesPreferenceActivity.java @@ -13,9 +13,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - + package net.micode.notes.ui; - + import android.accounts.Account; import android.accounts.AccountManager; import android.app.ActionBar; @@ -41,59 +41,60 @@ import android.view.View; import android.widget.Button; 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; - - + +// 设置界面活动类,继承自PreferenceActivity public class NotesPreferenceActivity extends PreferenceActivity { public static final String PREFERENCE_NAME = "notes_preferences"; - + public static final String PREFERENCE_SYNC_ACCOUNT_NAME = "pref_key_account_name"; - + public static final String PREFERENCE_LAST_SYNC_TIME = "pref_last_sync_time"; - + public static final String PREFERENCE_SET_BG_COLOR_KEY = "pref_key_bg_random_appear"; - + private static final String PREFERENCE_SYNC_ACCOUNT_KEY = "pref_sync_account_key"; - + private static final String AUTHORITIES_FILTER_KEY = "authorities"; - + private PreferenceCategory mAccountCategory; - + private GTaskReceiver mReceiver; - + private Account[] mOriAccounts; - + private boolean mHasAddedAccount; - + + // 创建活动时初始化界面 @Override protected void onCreate(Bundle icicle) { super.onCreate(icicle); - - /* using the app icon for navigation */ + + /* 使用应用图标进行导航 */ getActionBar().setDisplayHomeAsUpEnabled(true); - + addPreferencesFromResource(R.xml.preferences); mAccountCategory = (PreferenceCategory) findPreference(PREFERENCE_SYNC_ACCOUNT_KEY); mReceiver = new GTaskReceiver(); IntentFilter filter = new IntentFilter(); filter.addAction(GTaskSyncService.GTASK_SERVICE_BROADCAST_NAME); registerReceiver(mReceiver, filter); - + mOriAccounts = null; View header = LayoutInflater.from(this).inflate(R.layout.settings_header, null); getListView().addHeaderView(header, null, true); } - + + // 恢复活动时刷新界面 @Override protected void onResume() { super.onResume(); - - // need to set sync account automatically if user has added a new - // account + + // 如果用户添加了新账户,自动设置同步账户 if (mHasAddedAccount) { Account[] accounts = getGoogleAccounts(); if (mOriAccounts != null && accounts.length > mOriAccounts.length) { @@ -112,10 +113,11 @@ public class NotesPreferenceActivity extends PreferenceActivity { } } } - + refreshUI(); } - + + // 销毁活动时注销广播接收器 @Override protected void onDestroy() { if (mReceiver != null) { @@ -123,10 +125,11 @@ public class NotesPreferenceActivity extends PreferenceActivity { } super.onDestroy(); } - + + // 加载账户偏好设置 private void loadAccountPreference() { mAccountCategory.removeAll(); - + Preference accountPref = new Preference(this); final String defaultAccount = getSyncAccountName(this); accountPref.setTitle(getString(R.string.preferences_account_title)); @@ -135,11 +138,10 @@ public class NotesPreferenceActivity extends PreferenceActivity { public boolean onPreferenceClick(Preference preference) { if (!GTaskSyncService.isSyncing()) { if (TextUtils.isEmpty(defaultAccount)) { - // the first time to set account + // 第一次设置账户 showSelectAccountAlertDialog(); } else { - // if the account has already been set, we need to promp - // user about the risk + // 如果账户已经设置,提示用户切换账户的风险 showChangeAccountConfirmAlertDialog(); } } else { @@ -150,15 +152,16 @@ public class NotesPreferenceActivity extends PreferenceActivity { return true; } }); - + mAccountCategory.addPreference(accountPref); } - + + // 加载同步按钮 private void loadSyncButton() { Button syncButton = (Button) findViewById(R.id.preference_sync_button); TextView lastSyncTimeView = (TextView) findViewById(R.id.prefenerece_sync_status_textview); - - // set button state + + // 设置按钮状态 if (GTaskSyncService.isSyncing()) { syncButton.setText(getString(R.string.preferences_button_sync_cancel)); syncButton.setOnClickListener(new View.OnClickListener() { @@ -175,8 +178,8 @@ public class NotesPreferenceActivity extends PreferenceActivity { }); } syncButton.setEnabled(!TextUtils.isEmpty(getSyncAccountName(this))); - - // set last sync time + + // 设置上次同步时间 if (GTaskSyncService.isSyncing()) { lastSyncTimeView.setText(GTaskSyncService.getProgressString()); lastSyncTimeView.setVisibility(View.VISIBLE); @@ -192,30 +195,32 @@ public class NotesPreferenceActivity extends PreferenceActivity { } } } - + + // 刷新用户界面 private void refreshUI() { loadAccountPreference(); loadSyncButton(); } - + + // 显示选择账户的对话框 private void showSelectAccountAlertDialog() { AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(this); - + View titleView = LayoutInflater.from(this).inflate(R.layout.account_dialog_title, null); TextView titleTextView = (TextView) titleView.findViewById(R.id.account_dialog_title); titleTextView.setText(getString(R.string.preferences_dialog_select_account_title)); TextView subtitleTextView = (TextView) titleView.findViewById(R.id.account_dialog_subtitle); subtitleTextView.setText(getString(R.string.preferences_dialog_select_account_tips)); - + dialogBuilder.setCustomTitle(titleView); dialogBuilder.setPositiveButton(null, null); - + Account[] accounts = getGoogleAccounts(); String defAccount = getSyncAccountName(this); - + mOriAccounts = accounts; mHasAddedAccount = false; - + if (accounts.length > 0) { CharSequence[] items = new CharSequence[accounts.length]; final CharSequence[] itemMapping = items; @@ -236,10 +241,10 @@ public class NotesPreferenceActivity extends PreferenceActivity { } }); } - + View addAccountView = LayoutInflater.from(this).inflate(R.layout.add_account_text, null); dialogBuilder.setView(addAccountView); - + final AlertDialog dialog = dialogBuilder.show(); addAccountView.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { @@ -253,10 +258,11 @@ public class NotesPreferenceActivity extends PreferenceActivity { } }); } - + + // 显示更改账户确认对话框 private void showChangeAccountConfirmAlertDialog() { AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(this); - + View titleView = LayoutInflater.from(this).inflate(R.layout.account_dialog_title, null); TextView titleTextView = (TextView) titleView.findViewById(R.id.account_dialog_title); titleTextView.setText(getString(R.string.preferences_dialog_change_account_title, @@ -264,7 +270,7 @@ public class NotesPreferenceActivity extends PreferenceActivity { TextView subtitleTextView = (TextView) titleView.findViewById(R.id.account_dialog_subtitle); subtitleTextView.setText(getString(R.string.preferences_dialog_change_account_warn_msg)); dialogBuilder.setCustomTitle(titleView); - + CharSequence[] menuItemArray = new CharSequence[] { getString(R.string.preferences_menu_change_account), getString(R.string.preferences_menu_remove_account), @@ -282,12 +288,14 @@ public class NotesPreferenceActivity extends PreferenceActivity { }); dialogBuilder.show(); } - + + // 获取Google账户列表 private Account[] getGoogleAccounts() { AccountManager accountManager = AccountManager.get(this); return accountManager.getAccountsByType("com.google"); } - + + // 设置同步账户 private void setSyncAccount(String account) { if (!getSyncAccountName(this).equals(account)) { SharedPreferences settings = getSharedPreferences(PREFERENCE_NAME, Context.MODE_PRIVATE); @@ -298,11 +306,11 @@ public class NotesPreferenceActivity extends PreferenceActivity { editor.putString(PREFERENCE_SYNC_ACCOUNT_NAME, ""); } editor.commit(); - - // clean up last sync time + + // 清除上次同步时间 setLastSyncTime(this, 0); - - // clean up local gtask related info + + // 清除本地Gtask相关信息 new Thread(new Runnable() { public void run() { ContentValues values = new ContentValues(); @@ -311,13 +319,14 @@ public class NotesPreferenceActivity extends PreferenceActivity { getContentResolver().update(Notes.CONTENT_NOTE_URI, values, null, null); } }).start(); - + Toast.makeText(NotesPreferenceActivity.this, getString(R.string.preferences_toast_success_set_accout, account), Toast.LENGTH_SHORT).show(); } } - + + // 移除同步账户 private void removeSyncAccount() { SharedPreferences settings = getSharedPreferences(PREFERENCE_NAME, Context.MODE_PRIVATE); SharedPreferences.Editor editor = settings.edit(); @@ -328,8 +337,8 @@ public class NotesPreferenceActivity extends PreferenceActivity { editor.remove(PREFERENCE_LAST_SYNC_TIME); } editor.commit(); - - // clean up local gtask related info + + // 清除本地Gtask相关信息 new Thread(new Runnable() { public void run() { ContentValues values = new ContentValues(); @@ -339,13 +348,15 @@ public class NotesPreferenceActivity extends PreferenceActivity { } }).start(); } - + + // 获取同步账户名称 public static String getSyncAccountName(Context context) { SharedPreferences settings = context.getSharedPreferences(PREFERENCE_NAME, Context.MODE_PRIVATE); return settings.getString(PREFERENCE_SYNC_ACCOUNT_NAME, ""); } - + + // 设置上次同步时间 public static void setLastSyncTime(Context context, long time) { SharedPreferences settings = context.getSharedPreferences(PREFERENCE_NAME, Context.MODE_PRIVATE); @@ -353,15 +364,17 @@ public class NotesPreferenceActivity extends PreferenceActivity { editor.putLong(PREFERENCE_LAST_SYNC_TIME, time); editor.commit(); } - + + // 获取上次同步时间 public static long getLastSyncTime(Context context) { SharedPreferences settings = context.getSharedPreferences(PREFERENCE_NAME, Context.MODE_PRIVATE); return settings.getLong(PREFERENCE_LAST_SYNC_TIME, 0); } - + + // 广播接收器,用于接收同步状态更新 private class GTaskReceiver extends BroadcastReceiver { - + @Override public void onReceive(Context context, Intent intent) { refreshUI(); @@ -370,10 +383,11 @@ public class NotesPreferenceActivity extends PreferenceActivity { syncStatus.setText(intent .getStringExtra(GTaskSyncService.GTASK_SERVICE_BROADCAST_PROGRESS_MSG)); } - + } } - + + // 选项菜单项点击事件处理 public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case android.R.id.home: @@ -385,4 +399,4 @@ public class NotesPreferenceActivity extends PreferenceActivity { return false; } } -} +} \ No newline at end of file