ltx_branch
yfyl1005 2 years ago
parent 67bc7a5faf
commit d884e46b0f

@ -16,7 +16,7 @@
package net.micode.notes.ui; package net.micode.notes.ui;
import android.content.Context; import android.content.Context;//抽象类提供了一组通用的API,通过 Context才能识别调用者
import android.graphics.Rect; import android.graphics.Rect;
import android.text.Layout; import android.text.Layout;
import android.text.Selection; import android.text.Selection;
@ -37,16 +37,17 @@ import net.micode.notes.R;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
public class NoteEditText extends EditText {//Test public class NoteEditText extends EditText {//NoteEditText继承EditText的部分属性设置便签与文本框
private static final String TAG = "NoteEditText"; private static final String TAG = "NoteEditText";
private int mIndex; private int mIndex;
private int mSelectionStartBeforeDelete; private int mSelectionStartBeforeDelete;
private static final String SCHEME_TEL = "tel:" ; private static final String SCHEME_TEL = "tel:" ;//建立电话数据
private static final String SCHEME_HTTP = "http:" ; private static final String SCHEME_HTTP = "http:" ;//建立网站数据
private static final String SCHEME_EMAIL = "mailto:" ; private static final String SCHEME_EMAIL = "mailto:" ;//建立邮箱数据
private static final Map<String, Integer> sSchemaActionResMap = new HashMap<String, Integer>(); private static final Map<String, Integer> sSchemaActionResMap = new HashMap<String, Integer>();
//建立由字符和整数的hash表链接电话数据、网站数据与邮箱数据
static { static {
sSchemaActionResMap.put(SCHEME_TEL, R.string.note_link_tel); sSchemaActionResMap.put(SCHEME_TEL, R.string.note_link_tel);
sSchemaActionResMap.put(SCHEME_HTTP, R.string.note_link_web); sSchemaActionResMap.put(SCHEME_HTTP, R.string.note_link_web);
@ -56,54 +57,65 @@ public class NoteEditText extends EditText {//Test
/** /**
* Call by the {@link NoteEditActivity} to delete or add edit text * Call by the {@link NoteEditActivity} to delete or add edit text
*/ */
//在NoteEditActivity中进行删除或添加文本的操作并对进行更改的数据进行标记
public interface OnTextViewChangeListener { public interface OnTextViewChangeListener {
/** /**
* Delete current edit text when {@link KeyEvent#KEYCODE_DEL} happens * Delete current edit text when {@link KeyEvent#KEYCODE_DEL} happens
* and the text is null * and the text is null
*/ */
//当{@link KeyEvent#KEYCODE_DEL发生并且文本为空时删除当前编辑文本
void onEditTextDelete(int index, String text); void onEditTextDelete(int index, String text);
/** /**
* Add edit text after current edit text when {@link KeyEvent#KEYCODE_ENTER} * Add edit text after current edit text when {@link KeyEvent#KEYCODE_ENTER}
* happen * happen
*/ */
//当{@link KeyEvent#KEYCODE_ENTER发生时在当前编辑文本后添加编辑文本
void onEditTextEnter(int index, String text); void onEditTextEnter(int index, String text);
/** /**
* Hide or show item option when text change * Hide or show item option when text change
*/ */
//文本更改时隐藏或显示项目选项
void onTextChange(int index, boolean hasText); void onTextChange(int index, boolean hasText);
} }
private OnTextViewChangeListener mOnTextViewChangeListener; private OnTextViewChangeListener mOnTextViewChangeListener;
public NoteEditText(Context context) { public NoteEditText(Context context) {
super(context, null); super(context, null);//用super引用父类变量
mIndex = 0; mIndex = 0;
} }//根据context设置文本
public void setIndex(int index) { public void setIndex(int index) {
mIndex = index; mIndex = index;
} }//设置光标,并对光标进行初始化
public void setOnTextViewChangeListener(OnTextViewChangeListener listener) { public void setOnTextViewChangeListener(OnTextViewChangeListener listener) {
mOnTextViewChangeListener = listener; mOnTextViewChangeListener = listener;
} }//令listener赋值给mOnTextViewChangeListener实现文本修改标记初始化
public NoteEditText(Context context, AttributeSet attrs) { public NoteEditText(Context context, AttributeSet attrs) {
super(context, attrs, android.R.attr.editTextStyle); super(context, attrs, android.R.attr.editTextStyle);
} }//规定context控件属性便于维护便签动态变化的属性
public NoteEditText(Context context, AttributeSet attrs, int defStyle) { public NoteEditText(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle); super(context, attrs, defStyle);
// TODO Auto-generated constructor stub // TODO Auto-generated constructor stub
} }//通过类型定义和引用父类变量实现defStyle的自动初始化
@Override @Override
//view里的函数处理手机屏幕的所有事件
/*event
*/
public boolean onTouchEvent(MotionEvent event) { public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) { switch (event.getAction()) {
//对每一次屏幕被按下的情况进行重述
case MotionEvent.ACTION_DOWN: case MotionEvent.ACTION_DOWN:
//更新触屏坐标值
int x = (int) event.getX(); int x = (int) event.getX();
int y = (int) event.getY(); int y = (int) event.getY();
x -= getTotalPaddingLeft(); x -= getTotalPaddingLeft();
@ -112,106 +124,140 @@ public class NoteEditText extends EditText {//Test
y += getScrollY(); y += getScrollY();
Layout layout = getLayout(); Layout layout = getLayout();
//运用布局控件Layout对每一次的坐标新值xy进行设置新位置
int line = layout.getLineForVertical(y); int line = layout.getLineForVertical(y);
int off = layout.getOffsetForHorizontal(line, x); int off = layout.getOffsetForHorizontal(line, x);
Selection.setSelection(getText(), off); Selection.setSelection(getText(), off);
//同过selection寻找并更新当前光标新坐标值
break; break;
} }
return super.onTouchEvent(event); return super.onTouchEvent(event);
//回溯至函数,实现对每一次触屏事件的计算
} }
@Override @Override
public boolean onKeyDown(int keyCode, KeyEvent event) { // 函数功能:处理用户按下一个键盘按键时会触发 的事件
switch (keyCode) {
case KeyEvent.KEYCODE_ENTER: public boolean onKeyDown(int keyCode, KeyEvent event) //当作为一个构造函数(带有运算符 new调用时Boolean() 将把它的参数转换成一个布尔值,并且返回一个包含该值的 Boolean 对象
if (mOnTextViewChangeListener != null) { {
return false; switch (keyCode) {//根据按键的unicode编码值判断
case KeyEvent.KEYCODE_ENTER://按键编码值传入系统
if (mOnTextViewChangeListener != null)//对输入命令进行判空
{
return false;//对非法输入进行错误提示
} }
break; break;
case KeyEvent.KEYCODE_DEL: case KeyEvent.KEYCODE_DEL://删除按键
mSelectionStartBeforeDelete = getSelectionStart(); mSelectionStartBeforeDelete = getSelectionStart();
break; break;
default: default:
break; break;
} }
return super.onKeyDown(keyCode, event); return super.onKeyDown(keyCode, event);//继续进行父类其他点击事件
} }
@Override @Override
// 函数功能:处理用户松开一个键盘按键时会触发 的事件
public boolean onKeyUp(int keyCode, KeyEvent event) { public boolean onKeyUp(int keyCode, KeyEvent event) {
switch(keyCode) { switch(keyCode) {
//根据按键Unicode编码值进行操作包括进入和删除两种操作
case KeyEvent.KEYCODE_DEL: case KeyEvent.KEYCODE_DEL:
if (mOnTextViewChangeListener != null) { if (mOnTextViewChangeListener != null) //判断是否被修改
if (0 == mSelectionStartBeforeDelete && mIndex != 0) { {
if (0 == mSelectionStartBeforeDelete && mIndex != 0)//判断是否有被编辑修改并且文档不为空
{
mOnTextViewChangeListener.onEditTextDelete(mIndex, getText().toString()); mOnTextViewChangeListener.onEditTextDelete(mIndex, getText().toString());
////利用上文OnTextViewChangeListener对KEYCODE_DEL按键情况的删除函数进行删除
return true; return true;
} }
} else { } else {
Log.d(TAG, "OnTextViewChangeListener was not seted"); Log.d(TAG, "OnTextViewChangeListener was not seted");
//出现其他情况进行报错,文档修改监听器未被建立
} }
break; break;
case KeyEvent.KEYCODE_ENTER: case KeyEvent.KEYCODE_ENTER://对监听器错误情况进行判断
if (mOnTextViewChangeListener != null) { if (mOnTextViewChangeListener != null) {
int selectionStart = getSelectionStart(); int selectionStart = getSelectionStart();//获取当前起始位置
String text = getText().subSequence(selectionStart, length()).toString(); String text = getText().subSequence(selectionStart, length()).toString();//获取当前文本
setText(getText().subSequence(0, selectionStart)); setText(getText().subSequence(0, selectionStart));//根据获取文本设置当前文本
mOnTextViewChangeListener.onEditTextEnter(mIndex + 1, text); mOnTextViewChangeListener.onEditTextEnter(mIndex + 1, text);
//当错误发生及当{@link KeyEvent#KEYCODE_ENTER}时添加新文本
} else { } else {
Log.d(TAG, "OnTextViewChangeListener was not seted"); Log.d(TAG, "OnTextViewChangeListener was not seted");////其他情况报错,文档的改动监听器并没有建立
} }
break; break;
default: default:
break; break;
} }
return super.onKeyUp(keyCode, event); return super.onKeyUp(keyCode, event);
//回溯至前面函数继续执行父类的其他按键弹起的事件
} }
@Override @Override
//函数功能:当焦点发生变化时,会自动调用该方法来处理焦点改变的事件
// * 参数focused表示触发该事件的View是否获得了焦点当该控件获得焦点时Focused等于true否则等于false。
// direction表示焦点移动的方向用数值表示
// Rect表示在触发事件的View的坐标系中前一个获得焦点的矩形区域即表示焦点是从哪里来的。如果不可用则为null
protected void onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect) { protected void onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect) {
if (mOnTextViewChangeListener != null) { if (mOnTextViewChangeListener != null) //判断监听器是否建立
if (!focused && TextUtils.isEmpty(getText())) { {
if (!focused && TextUtils.isEmpty(getText())) //截取焦点并且判断文本是否为空
{
mOnTextViewChangeListener.onTextChange(mIndex, false); mOnTextViewChangeListener.onTextChange(mIndex, false);
//mOnTextViewChangeListener子函数置false隐藏事件选项
} else { } else {
mOnTextViewChangeListener.onTextChange(mIndex, true); mOnTextViewChangeListener.onTextChange(mIndex, true);
//mOnTextViewChangeListener子函数置true显示事件选项
} }
} }
super.onFocusChanged(focused, direction, previouslyFocusedRect); super.onFocusChanged(focused, direction, previouslyFocusedRect);
//回溯至前面函数继续执行父类的其他焦点变化事件
} }
@Override @Override
//函数意义:生成上下文菜单
protected void onCreateContextMenu(ContextMenu menu) { protected void onCreateContextMenu(ContextMenu menu) {
if (getText() instanceof Spanned) { if (getText() instanceof Spanned) //判断文本是否存在
{
int selStart = getSelectionStart(); int selStart = getSelectionStart();
int selEnd = getSelectionEnd(); int selEnd = getSelectionEnd();
//获取开始位置和截至位置
int min = Math.min(selStart, selEnd); int min = Math.min(selStart, selEnd);
int max = Math.max(selStart, selEnd); int max = Math.max(selStart, selEnd);
//计算开始到结尾的最大值和最小值
final URLSpan[] urls = ((Spanned) getText()).getSpans(min, max, URLSpan.class); final URLSpan[] urls = ((Spanned) getText()).getSpans(min, max, URLSpan.class);
//设置url信息范围值
if (urls.length == 1) { if (urls.length == 1) {
int defaultResId = 0; int defaultResId = 0;
for(String schema: sSchemaActionResMap.keySet()) { for(String schema: sSchemaActionResMap.keySet()) //获取计划表中的所有key值
if(urls[0].getURL().indexOf(schema) >= 0) { {
if(urls[0].getURL().indexOf(schema) >= 0) //若url可以添加则在添加后将defaultResId置为key所映射的值
{
defaultResId = sSchemaActionResMap.get(schema); defaultResId = sSchemaActionResMap.get(schema);
break; break;
} }
} }
if (defaultResId == 0) { if (defaultResId == 0) //defaultResId == 0则说明url并没有添加任何东西所以置为连接其他SchemaActionResMap的值
{
defaultResId = R.string.note_link_other; defaultResId = R.string.note_link_other;
} }
menu.add(0, 0, 0, defaultResId).setOnMenuItemClickListener( menu.add(0, 0, 0, defaultResId).setOnMenuItemClickListener//建立菜单
new OnMenuItemClickListener() { (
public boolean onMenuItemClick(MenuItem item) { new OnMenuItemClickListener() //新建按键监听器
// goto a new intent {
urls[0].onClick(NoteEditText.this); public boolean onMenuItemClick(MenuItem item) {
return true; // goto a new intent
} urls[0].onClick(NoteEditText.this);//根据文本进行按键设置
}); return true;
}
});
} }
} }
super.onCreateContextMenu(menu); super.onCreateContextMenu(menu);
//回溯至前面函数继续执行父类的其他菜单创建的事件
} }
} }

Loading…
Cancel
Save