diff --git a/src/Notes-master/src/net/micode/notes/ui/DateTimePickerDialog.java b/src/Notes-master/src/net/micode/notes/ui/DateTimePickerDialog.java index 0dcfb80..38726a2 100644 --- a/src/Notes-master/src/net/micode/notes/ui/DateTimePickerDialog.java +++ b/src/Notes-master/src/net/micode/notes/ui/DateTimePickerDialog.java @@ -28,29 +28,29 @@ import android.content.DialogInterface; import android.content.DialogInterface.OnClickListener; import android.text.format.DateFormat; import android.text.format.DateUtils; - +//功能:创建选择日期和时间的对话框界面,提供日期时间选择和结果回调 public class DateTimePickerDialog extends AlertDialog implements OnClickListener { private Calendar mDate = Calendar.getInstance(); - //һCalendar͵ı mDateʱIJ + //创建一个Calendar类型的变量 mDate,方便时间的操作 private boolean mIs24HourView; private OnDateTimeSetListener mOnDateTimeSetListener; - //һʱڹѡؼ mOnDateTimeSetListener + //声明一个时间日期滚动选择控件 mOnDateTimeSetListener private DateTimePicker mDateTimePicker; - //DateTimePickerؼؼһûԴбѡ񵥸ֵ - //ʱؼϵͷʾΪ֣һбһѡڵ + //DateTimePicker控件,控件一般用于让用户可以从日期列表中选择单个值。 + //运行时,单击控件边上的下拉箭头,会显示为两个部分:一个下拉列表,一个用于选择日期的 public interface OnDateTimeSetListener { void OnDateTimeSet(AlertDialog dialog, long date); } public DateTimePickerDialog(Context context, long date) { - //ԸýԻʵ + //对该界面对话框的实例化 super(context); - //ݿIJ + //对数据库的操作 mDateTimePicker = new DateTimePicker(context); setView(mDateTimePicker); - //һͼ + //添加一个子视图 mDateTimePicker.setOnDateTimeChangedListener(new OnDateTimeChangedListener() { public void onDateTimeChanged(DateTimePicker view, int year, int month, int dayOfMonth, int hourOfDay, int minute) { @@ -59,30 +59,30 @@ public class DateTimePickerDialog extends AlertDialog implements OnClickListener mDate.set(Calendar.DAY_OF_MONTH, dayOfMonth); mDate.set(Calendar.HOUR_OF_DAY, hourOfDay); mDate.set(Calendar.MINUTE, minute); - //ͼеĸѡΪϵͳǰʱ + //将视图中的各选项设置为系统当前时间 updateTitle(mDate.getTimeInMillis()); } }); mDate.setTimeInMillis(date); - //õϵͳʱ + //得到系统时间 mDate.set(Calendar.SECOND, 0); - //Ϊ0 + //将秒数设置为0 mDateTimePicker.setCurrentDate(mDate.getTimeInMillis()); setButton(context.getString(R.string.datetime_dialog_ok), this); setButton2(context.getString(R.string.datetime_dialog_cancel), (OnClickListener)null); - //ðť + //设置按钮 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 = @@ -91,13 +91,13 @@ public class DateTimePickerDialog extends AlertDialog implements OnClickListener DateUtils.FORMAT_SHOW_TIME; flag |= mIs24HourView ? DateUtils.FORMAT_24HOUR : DateUtils.FORMAT_24HOUR; setTitle(DateUtils.formatDateTime(this.getContext(), date, flag)); - }//androidгڹࣨAPIDateUtilsʾʱ + }//android开发中常见日期管理工具类(API)——DateUtils:按照上下午显示时间 public void onClick(DialogInterface arg0, int arg1) { if (mOnDateTimeSetListener != null) { mOnDateTimeSetListener.OnDateTimeSet(this, mDate.getTimeInMillis()); } - }//һarg0ǽյ¼ĶԻ - //ڶarg1ǸöԻϵİť + }//第一个参数arg0是接收到点击事件的对话框 + //第二个参数arg1是该对话框上的按钮 } \ No newline at end of file diff --git a/src/Notes-master/src/net/micode/notes/ui/DropdownMenu.java b/src/Notes-master/src/net/micode/notes/ui/DropdownMenu.java index c8d0835..cf78a7c 100644 --- a/src/Notes-master/src/net/micode/notes/ui/DropdownMenu.java +++ b/src/Notes-master/src/net/micode/notes/ui/DropdownMenu.java @@ -26,40 +26,40 @@ 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; - + //创建下拉菜单的图形化界面 public DropdownMenu(Context context, Button button, int menuId) { mButton = button; mButton.setBackgroundResource(R.drawable.dropdown_icon); - //viewı + //设置这个view的背景 mPopupMenu = new PopupMenu(context, mButton); mMenu = mPopupMenu.getMenu(); mPopupMenu.getMenuInflater().inflate(menuId, mMenu); - //MenuInflaterʵMenuĿ¼µMenuļ - //IDȷmenuѡ + //MenuInflater是用来实例化Menu目录下的Menu布局文件 + //根据ID来确认menu的内容选项 mButton.setOnClickListener(new OnClickListener() { public void onClick(View v) { mPopupMenu.show(); } }); } - + //功能:设置菜单的监听 public void setOnDropdownMenuItemClickListener(OnMenuItemClickListener listener) { if (mPopupMenu != null) { mPopupMenu.setOnMenuItemClickListener(listener); - }//ò˵ļ + } } - + //功能:对于菜单选项的初始化,根据索引搜索菜单需要的选项 public MenuItem findItem(int id) { return mMenu.findItem(id); - }//ڲ˵ѡijʼ˵Ҫѡ - + } + //功能:布局文件,设置标题 public void setTitle(CharSequence title) { mButton.setText(title); - }//ļñ + } } \ No newline at end of file diff --git a/src/Notes-master/src/net/micode/notes/ui/FoldersListAdapter.java b/src/Notes-master/src/net/micode/notes/ui/FoldersListAdapter.java index 96b77da..cbb1ced 100644 --- a/src/Notes-master/src/net/micode/notes/ui/FoldersListAdapter.java +++ b/src/Notes-master/src/net/micode/notes/ui/FoldersListAdapter.java @@ -15,7 +15,7 @@ */ package net.micode.notes.ui; - + import android.content.Context; import android.database.Cursor; import android.view.View; @@ -23,32 +23,38 @@ 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; - - + +//功能:实现文件夹列表 public class FoldersListAdapter extends CursorAdapter { + //CursorAdapter是Cursor和ListView的接口 + //FoldersListAdapter继承了CursorAdapter的类 + //主要作用是便签数据库和用户的交互 + //这里就是用folder(文件夹)的形式展现给用户 public static final String [] PROJECTION = { NoteColumns.ID, NoteColumns.SNIPPET - }; - + };//调用数据库中便签的ID和片段 + public static final int ID_COLUMN = 0; public static final int NAME_COLUMN = 1; - + 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); + //ViewGroup是容器 + 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 @@ -56,25 +62,27 @@ public class FoldersListAdapter extends CursorAdapter { ((FolderListItem) view).bind(folderName); } } - + //功能:根据数据库中标签的ID得到标签的各项内容 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; - + 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/src/Notes-master/src/net/micode/notes/ui/NoteEditText.java b/src/Notes-master/src/net/micode/notes/ui/NoteEditText.java index 2afe2a8..d3fa67a 100644 --- a/src/Notes-master/src/net/micode/notes/ui/NoteEditText.java +++ b/src/Notes-master/src/net/micode/notes/ui/NoteEditText.java @@ -15,7 +15,7 @@ */ package net.micode.notes.ui; - + import android.content.Context; import android.graphics.Rect; import android.text.Layout; @@ -31,187 +31,239 @@ 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 { + +//继承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:" ; - + + //功能:建立一个字符和整数的hash表,用于链接电话,网站,还有邮箱 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 */ + //在NoteEditActivity中删除或添加文本的操作,可以看做是一个文本是否被变的标记,英文注释已说明的很清楚 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); } - + private OnTextViewChangeListener mOnTextViewChangeListener; - + + //根据context设置文本 public NoteEditText(Context context) { - super(context, null); + super(context, null);//用super引用父类变量 mIndex = 0; } - + + //设置当前光标 public void setIndex(int index) { mIndex = index; } - + + //初始化文本修改标记 public void setOnTextViewChangeListener(OnTextViewChangeListener listener) { mOnTextViewChangeListener = listener; } - - public NoteEditText(Context context, AttributeSet attrs) { + + //AttributeSet 百度了一下是自定义空控件属性,用于维护便签动态变化的属性 + //初始化便签 + public NoteEditText(Context context, AttributeSet attrs) { super(context, attrs, android.R.attr.editTextStyle); } - + + // 根据defstyle自动初始化 public NoteEditText(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); - // TODO Auto-generated constructor stub - } - + // TODO Auto-generated construct or 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根据x,y的新值设置新的位置 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) { + //根据按键的 Unicode 编码值来处理 case KeyEvent.KEYCODE_ENTER: + //“进入”按键 if (mOnTextViewChangeListener != null) { return false; } break; case KeyEvent.KEYCODE_DEL: + //“删除”按键 mSelectionStartBeforeDelete = getSelectionStart(); break; default: break; } + //继续执行父类的其他点击事件 return super.onKeyDown(keyCode, event); } - + @Override + //函数功能:处理用户松开一个键盘按键时会触发 的事件 public boolean onKeyUp(int keyCode, KeyEvent event) { switch(keyCode) { + //根据按键的 Unicode 编码值来处理,有删除和进入2种操作 case KeyEvent.KEYCODE_DEL: if (mOnTextViewChangeListener != null) { + //若是被修改过 if (0 == mSelectionStartBeforeDelete && mIndex != 0) { + //若之前有被修改并且文档不为空 mOnTextViewChangeListener.onEditTextDelete(mIndex, getText().toString()); + //利用上文OnTextViewChangeListener对KEYCODE_DEL按键情况的删除函数进行删除 return true; } } else { Log.d(TAG, "OnTextViewChangeListener was not seted"); + //其他情况报错,文档的改动监听器并没有建立 } break; case KeyEvent.KEYCODE_ENTER: + //同上也是分为监听器是否建立2种情况 if (mOnTextViewChangeListener != null) { int selectionStart = getSelectionStart(); + //获取当前位置 String text = getText().subSequence(selectionStart, length()).toString(); + //获取当前文本 setText(getText().subSequence(0, selectionStart)); + //根据获取的文本设置当前文本 mOnTextViewChangeListener.onEditTextEnter(mIndex + 1, text); + //当{@link KeyEvent#KEYCODE_ENTER}添加新文本 } 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 (mOnTextViewChangeListener != null) { + //若监听器已经建立 if (!focused && TextUtils.isEmpty(getText())) { + //获取到焦点并且文本不为空 mOnTextViewChangeListener.onTextChange(mIndex, false); + //mOnTextViewChangeListener子函数,置false隐藏事件选项 } else { mOnTextViewChangeListener.onTextChange(mIndex, true); + //mOnTextViewChangeListener子函数,置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); + //设置url的信息的范围值 if (urls.length == 1) { int defaultResId = 0; for(String schema: sSchemaActionResMap.keySet()) { + //获取计划表中所有的key值 if(urls[0].getURL().indexOf(schema) >= 0) { + //若url可以添加则在添加后将defaultResId置为key所映射的值 defaultResId = sSchemaActionResMap.get(schema); break; } } - + if (defaultResId == 0) { + //defaultResId == 0则说明url并没有添加任何东西,所以置为连接其他SchemaActionResMap的值 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); } -} +} \ No newline at end of file