diff --git a/src/Notes/src/net/micode/notes/ui/NoteEditText.java b/src/Notes/src/net/micode/notes/ui/NoteEditText.java index 2afe2a8..f1cec84 100644 --- a/src/Notes/src/net/micode/notes/ui/NoteEditText.java +++ b/src/Notes/src/net/micode/notes/ui/NoteEditText.java @@ -1,17 +1,16 @@ /* - * Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net) + * 版权所有 (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 + * 根据 Apache 许可证 2.0 版本(“许可证”)许可; + * 除非符合许可证,否则您不能使用此文件。 + * 您可以在以下网址获得许可证副本: * * 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; @@ -38,14 +37,19 @@ import java.util.HashMap; import java.util.Map; public class NoteEditText extends EditText { + // Log 标签 private static final String TAG = "NoteEditText"; + // 笔记索引 private int mIndex; + // 记录删除前的光标位置 private int mSelectionStartBeforeDelete; + // 不同 URL Scheme 的定义 private static final String SCHEME_TEL = "tel:" ; private static final String SCHEME_HTTP = "http:" ; private static final String SCHEME_EMAIL = "mailto:" ; + // 不同 URL Scheme 对应的显示字符串资源映射 private static final Map sSchemaActionResMap = new HashMap(); static { sSchemaActionResMap.put(SCHEME_TEL, R.string.note_link_tel); @@ -54,82 +58,89 @@ public class NoteEditText extends EditText { } /** - * Call by the {@link NoteEditActivity} to delete or add edit text + * 由 {@link NoteEditActivity} 调用,用于删除或添加编辑文本 */ public interface OnTextViewChangeListener { /** - * Delete current edit text when {@link KeyEvent#KEYCODE_DEL} happens - * and the text is null + * 当 {@link KeyEvent#KEYCODE_DEL} 事件发生且文本为空时,删除当前编辑文本 */ void onEditTextDelete(int index, String text); /** - * Add edit text after current edit text when {@link KeyEvent#KEYCODE_ENTER} - * happen + * 当 {@link KeyEvent#KEYCODE_ENTER} 事件发生时,在当前编辑文本后添加新的编辑文本 */ void onEditTextEnter(int index, String text); /** - * Hide or show item option when text change + * 文本改变时,隐藏或显示项目选项 */ void onTextChange(int index, boolean hasText); } private OnTextViewChangeListener mOnTextViewChangeListener; + // 构造函数,设置笔记索引为0 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) { case KeyEvent.KEYCODE_ENTER: + // 如果文本视图改变监听器不为空,则返回 false if (mOnTextViewChangeListener != null) { return false; } break; case KeyEvent.KEYCODE_DEL: + // 记录删除前的光标位置 mSelectionStartBeforeDelete = getSelectionStart(); break; default: @@ -138,10 +149,12 @@ public class NoteEditText extends EditText { return super.onKeyDown(keyCode, event); } + // 按键释放事件处理 @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()); @@ -152,6 +165,7 @@ public class NoteEditText extends EditText { } break; case KeyEvent.KEYCODE_ENTER: + // 如果文本视图改变监听器不为空,则处理回车事件 if (mOnTextViewChangeListener != null) { int selectionStart = getSelectionStart(); String text = getText().subSequence(selectionStart, length()).toString(); @@ -167,9 +181,11 @@ public class NoteEditText extends EditText { 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 { @@ -179,18 +195,22 @@ public class NoteEditText extends EditText { 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); + // 获取选中文本中的 URLSpan final URLSpan[] urls = ((Spanned) getText()).getSpans(min, max, URLSpan.class); if (urls.length == 1) { int defaultResId = 0; + // 根据 URL 的 Scheme 获取对应的资源 ID for(String schema: sSchemaActionResMap.keySet()) { if(urls[0].getURL().indexOf(schema) >= 0) { defaultResId = sSchemaActionResMap.get(schema); @@ -202,10 +222,11 @@ public class NoteEditText extends EditText { defaultResId = R.string.note_link_other; } + // 添加菜单项,并设置点击监听器 menu.add(0, 0, 0, defaultResId).setOnMenuItemClickListener( new OnMenuItemClickListener() { public boolean onMenuItemClick(MenuItem item) { - // goto a new intent + // 打开新的 Intent urls[0].onClick(NoteEditText.this); return true; }