diff --git a/src/Notes-master/app/src/main/java/net/micode/notes/ui/NoteEditText.java b/src/Notes-master/app/src/main/java/net/micode/notes/ui/NoteEditText.java index 2afe2a8..6c92ad8 100644 --- a/src/Notes-master/app/src/main/java/net/micode/notes/ui/NoteEditText.java +++ b/src/Notes-master/app/src/main/java/net/micode/notes/ui/NoteEditText.java @@ -1,17 +1,9 @@ /* * 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. + * 版权声明:本代码受Apache许可证2.0版本保护 + * 您可以在遵守许可证的前提下使用、修改和分发本代码 + * 许可证全文可在http://www.apache.org/licenses/LICENSE-2.0获取 */ package net.micode.notes.ui; @@ -37,63 +29,90 @@ import net.micode.notes.R; import java.util.HashMap; import java.util.Map; +/** + * 笔记编辑文本框 + * 功能:自定义EditText,扩展了特殊功能,如链接识别、清单模式编辑等 + * 特点:支持处理Enter和Delete按键事件、URL链接上下文菜单、焦点变化监听 + */ public class NoteEditText extends EditText { private static final String TAG = "NoteEditText"; - private int mIndex; - private int mSelectionStartBeforeDelete; + 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:" ; + // 支持的URL协议前缀 + private static final String SCHEME_TEL = "tel:" ; // 电话协议 + private static final String SCHEME_HTTP = "http:" ; // HTTP协议 + private static final String SCHEME_EMAIL = "mailto:" ; // 邮件协议 + // URL协议与菜单项文本资源映射 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); + 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 + * 当按下删除键且文本为空时,删除当前编辑文本框 + * @param index 当前编辑文本框索引 + * @param text 当前文本内容 */ void onEditTextDelete(int index, String text); /** - * Add edit text after current edit text when {@link KeyEvent#KEYCODE_ENTER} - * happen + * 当按下回车键时,在当前位置后添加新的编辑文本框 + * @param index 当前编辑文本框索引 + * @param text 当前光标后的文本内容 */ void onEditTextEnter(int index, String text); /** - * Hide or show item option when text change + * 当文本内容变化时,隐藏或显示项目选项 + * @param index 当前编辑文本框索引 + * @param hasText 是否有文本内容 */ 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 @@ -101,9 +120,10 @@ public class NoteEditText extends EditText { @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(); @@ -123,13 +143,16 @@ public class NoteEditText extends EditText { @Override public boolean onKeyDown(int keyCode, KeyEvent event) { + // 处理按键按下事件 switch (keyCode) { case KeyEvent.KEYCODE_ENTER: + // 回车键由onKeyUp处理,这里返回false if (mOnTextViewChangeListener != null) { return false; } break; case KeyEvent.KEYCODE_DEL: + // 记录删除前的光标位置 mSelectionStartBeforeDelete = getSelectionStart(); break; default: @@ -140,8 +163,10 @@ public class NoteEditText extends EditText { @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 +177,7 @@ public class NoteEditText extends EditText { } break; case KeyEvent.KEYCODE_ENTER: + // 处理回车键:将当前文本在光标处分割,后半部分传递给下一个编辑框 if (mOnTextViewChangeListener != null) { int selectionStart = getSelectionStart(); String text = getText().subSequence(selectionStart, length()).toString(); @@ -169,6 +195,7 @@ public class NoteEditText extends EditText { @Override protected void onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect) { + // 处理焦点变化事件,通知监听器当前文本状态 if (mOnTextViewChangeListener != null) { if (!focused && TextUtils.isEmpty(getText())) { mOnTextViewChangeListener.onTextChange(mIndex, false); @@ -181,6 +208,7 @@ public class NoteEditText extends EditText { @Override protected void onCreateContextMenu(ContextMenu menu) { + // 创建上下文菜单,处理URL链接 if (getText() instanceof Spanned) { int selStart = getSelectionStart(); int selEnd = getSelectionEnd(); @@ -188,9 +216,11 @@ public class NoteEditText extends EditText { 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协议选择合适的菜单项文本 for(String schema: sSchemaActionResMap.keySet()) { if(urls[0].getURL().indexOf(schema) >= 0) { defaultResId = sSchemaActionResMap.get(schema); @@ -202,10 +232,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 + // 点击菜单项时执行URLSpan的onClick方法 urls[0].onClick(NoteEditText.this); return true; } @@ -214,4 +245,4 @@ public class NoteEditText extends EditText { } super.onCreateContextMenu(menu); } -} +} \ No newline at end of file