Update NoteEditText.java

main
pf45q8f3g 7 months ago
parent 9685bc719e
commit b497502b53

@ -1,286 +1,237 @@
/* /*
* Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net) * (c) 2010-2011, MiCode (www.micode.net)
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * 使 Apache License, Version 2.0
* 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 * 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; package net.micode.notes.ui;
import android.content.Context; import android.content.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;
import android.text.Spanned; import android.text.Spanned;
import android.text.TextUtils; import android.text.TextUtils;
import android.text.style.URLSpan; import android.text.style.URLSpan;
import android.util.AttributeSet; import android.util.AttributeSet;
import android.util.Log; import android.util.Log;
import android.view.ContextMenu; import android.view.ContextMenu;
import android.view.KeyEvent; import android.view.KeyEvent;
import android.view.MenuItem; import android.view.MenuItem;
import android.view.MenuItem.OnMenuItemClickListener; import android.view.MenuItem.OnMenuItemClickListener;
import android.view.MotionEvent; import android.view.MotionEvent;
import android.widget.EditText; import android.widget.EditText;
import net.micode.notes.R; import net.micode.notes.R;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
//继承edittext设置便签设置文本框 /**
public class NoteEditText extends EditText { * NoteEditText EditText便
private static final String TAG = "NoteEditText"; *
private int mIndex; */
private int mSelectionStartBeforeDelete; public class NoteEditText extends EditText {
private static final String TAG = "NoteEditText";
private static final String SCHEME_TEL = "tel:" ; private int mIndex;
private static final String SCHEME_HTTP = "http:" ; private int mSelectionStartBeforeDelete;
private static final String SCHEME_EMAIL = "mailto:" ;
private static final String SCHEME_TEL = "tel:";
///建立一个字符和整数的hash表用于链接电话网站还有邮箱 private static final String SCHEME_HTTP = "http:";
private static final Map<String, Integer> sSchemaActionResMap = new HashMap<String, Integer>(); private static final String SCHEME_EMAIL = "mailto:";
static {
sSchemaActionResMap.put(SCHEME_TEL, R.string.note_link_tel); private static final Map<String, Integer> sSchemaActionResMap = new HashMap<String, Integer>();
sSchemaActionResMap.put(SCHEME_HTTP, R.string.note_link_web); static {
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 { */
/** public interface OnTextViewChangeListener {
* Delete current edit text when {@link KeyEvent#KEYCODE_DEL} happens /**
* and the text is null *
*/ */
//处理删除按键时的操作 void onEditTextDelete(int index, String text);
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);
*/
//处理进入按键时的操作 /**
void onEditTextEnter(int index, String text); *
*/
/** void onTextChange(int index, boolean hasText);
* Hide or show item option when text change }
*/
void onTextChange(int index, boolean hasText); private OnTextViewChangeListener mOnTextViewChangeListener;
}
/**
private OnTextViewChangeListener mOnTextViewChangeListener; * NoteEditText
* @param context
//根据context设置文本 */
public NoteEditText(Context context) { public NoteEditText(Context context) {
super(context, null);//用super引用父类变量 super(context, null);
mIndex = 0; mIndex = 0;
} }
//设置当前光标 /**
public void setIndex(int index) { *
mIndex = index; * @param index
} */
public void setIndex(int index) {
//初始化文本修改标记 mIndex = index;
public void setOnTextViewChangeListener(OnTextViewChangeListener listener) { }
mOnTextViewChangeListener = listener;
} /**
*
//AttributeSet 百度了一下是自定义空控件属性,用于维护便签动态变化的属性 * @param listener
//初始化便签 */
public NoteEditText(Context context, AttributeSet attrs) { public void setOnTextViewChangeListener(OnTextViewChangeListener listener) {
super(context, attrs, android.R.attr.editTextStyle); mOnTextViewChangeListener = listener;
} }
// 根据defstyle自动初始化 /**
public NoteEditText(Context context, AttributeSet attrs, int defStyle) { * NoteEditText
super(context, attrs, defStyle); * @param context
// TODO Auto-generated construct or stub * @param attrs
} */
public NoteEditText(Context context, AttributeSet attrs) {
@Override super(context, attrs, android.R.attr.editTextStyle);
//view里的函数处理手机屏幕的所有事件 }
/*event
*/ /**
public boolean onTouchEvent(MotionEvent event) { * NoteEditText
switch (event.getAction()) { * @param context
//重写了需要处理屏幕被按下的事件 * @param attrs
case MotionEvent.ACTION_DOWN: * @param defStyle
//跟新当前坐标值 */
int x = (int) event.getX(); public NoteEditText(Context context, AttributeSet attrs, int defStyle) {
int y = (int) event.getY(); super(context, attrs, defStyle);
x -= getTotalPaddingLeft(); }
y -= getTotalPaddingTop();
x += getScrollX(); @Override
y += getScrollY(); public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
//用布局控件layout根据x,y的新值设置新的位置 case MotionEvent.ACTION_DOWN:
Layout layout = getLayout(); int x = (int) event.getX();
int line = layout.getLineForVertical(y); int y = (int) event.getY();
int off = layout.getOffsetForHorizontal(line, x); x -= getTotalPaddingLeft();
y -= getTotalPaddingTop();
//更新光标新的位置 x += getScrollX();
Selection.setSelection(getText(), off); y += getScrollY();
break;
} Layout layout = getLayout();
int line = layout.getLineForVertical(y);
return super.onTouchEvent(event); int off = layout.getOffsetForHorizontal(line, x);
}
Selection.setSelection(getText(), off);
@Override break;
/* }
* return super.onTouchEvent(event);
* }
*/
public boolean onKeyDown(int keyCode, KeyEvent event) { @Override
switch (keyCode) { public boolean onKeyDown(int keyCode, KeyEvent event) {
//根据按键的 Unicode 编码值来处理 switch (keyCode) {
case KeyEvent.KEYCODE_ENTER: case KeyEvent.KEYCODE_ENTER:
//“进入”按键 if (mOnTextViewChangeListener != null) {
if (mOnTextViewChangeListener != null) { return false;
return false; }
} break;
break; case KeyEvent.KEYCODE_DEL:
case KeyEvent.KEYCODE_DEL: mSelectionStartBeforeDelete = getSelectionStart();
//“删除”按键 break;
mSelectionStartBeforeDelete = getSelectionStart(); default:
break; break;
default: }
break; return super.onKeyDown(keyCode, event);
} }
//继续执行父类的其他点击事件
return super.onKeyDown(keyCode, event); @Override
} public boolean onKeyUp(int keyCode, KeyEvent event) {
switch (keyCode) {
@Override case KeyEvent.KEYCODE_DEL:
/* if (mOnTextViewChangeListener != null) {
* if (0 == mSelectionStartBeforeDelete && mIndex != 0) {
* mOnTextViewChangeListener.onEditTextDelete(mIndex, getText().toString());
*/ return true;
public boolean onKeyUp(int keyCode, KeyEvent event) { }
switch(keyCode) { } else {
//根据按键的 Unicode 编码值来处理有删除和进入2种操作 Log.d(TAG, "OnTextViewChangeListener was not set");
case KeyEvent.KEYCODE_DEL: }
if (mOnTextViewChangeListener != null) { break;
//若是被修改过 case KeyEvent.KEYCODE_ENTER:
if (0 == mSelectionStartBeforeDelete && mIndex != 0) { if (mOnTextViewChangeListener != null) {
//若之前有被修改并且文档不为空 int selectionStart = getSelectionStart();
mOnTextViewChangeListener.onEditTextDelete(mIndex, getText().toString()); String text = getText().subSequence(selectionStart, length()).toString();
//利用上文OnTextViewChangeListener对KEYCODE_DEL按键情况的删除函数进行删除 setText(getText().subSequence(0, selectionStart));
return true; mOnTextViewChangeListener.onEditTextEnter(mIndex + 1, text);
} } else {
} else { Log.d(TAG, "OnTextViewChangeListener was not set");
Log.d(TAG, "OnTextViewChangeListener was not seted"); }
//其他情况报错,文档的改动监听器并没有建立 break;
} default:
break; break;
case KeyEvent.KEYCODE_ENTER: }
//同上也是分为监听器是否建立2种情况 return super.onKeyUp(keyCode, event);
if (mOnTextViewChangeListener != null) { }
int selectionStart = getSelectionStart();
//获取当前位置 @Override
String text = getText().subSequence(selectionStart, length()).toString(); protected void onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect) {
//获取当前文本 if (mOnTextViewChangeListener != null) {
setText(getText().subSequence(0, selectionStart)); if (!focused && TextUtils.isEmpty(getText())) {
//根据获取的文本设置当前文本 mOnTextViewChangeListener.onTextChange(mIndex, false);
mOnTextViewChangeListener.onEditTextEnter(mIndex + 1, text); } else {
//当{@link KeyEvent#KEYCODE_ENTER}添加新文本 mOnTextViewChangeListener.onTextChange(mIndex, true);
} else { }
Log.d(TAG, "OnTextViewChangeListener was not seted"); }
//其他情况报错,文档的改动监听器并没有建立 super.onFocusChanged(focused, direction, previouslyFocusedRect);
} }
break;
default: @Override
break; protected void onCreateContextMenu(ContextMenu menu) {
} if (getText() instanceof Spanned) {
//继续执行父类的其他按键弹起的事件 int selStart = getSelectionStart();
return super.onKeyUp(keyCode, event); int selEnd = getSelectionEnd();
}
int min = Math.min(selStart, selEnd);
@Override int max = Math.max(selStart, selEnd);
/*
* final URLSpan[] urls = ((Spanned) getText()).getSpans(min, max, URLSpan.class);
* if (urls.length == 1) {
* focusedViewFocusedtruefalse int defaultResId = 0;
direction for (String schema : sSchemaActionResMap.keySet()) {
RectViewnull if (urls[0].getURL().indexOf(schema) >= 0) {
*/ defaultResId = sSchemaActionResMap.get(schema);
protected void onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect) { break;
if (mOnTextViewChangeListener != null) { }
//若监听器已经建立 }
if (!focused && TextUtils.isEmpty(getText())) {
//获取到焦点并且文本不为空 if (defaultResId == 0) {
mOnTextViewChangeListener.onTextChange(mIndex, false); defaultResId = R.string.note_link_other;
//mOnTextViewChangeListener子函数置false隐藏事件选项 }
} else {
mOnTextViewChangeListener.onTextChange(mIndex, true); menu.add(0, 0, 0, defaultResId).setOnMenuItemClickListener(
//mOnTextViewChangeListener子函数置true显示事件选项 new OnMenuItemClickListener() {
} public boolean onMenuItemClick(MenuItem item) {
} urls[0].onClick(NoteEditText.this);
//继续执行父类的其他焦点变化的事件 return true;
super.onFocusChanged(focused, direction, previouslyFocusedRect); }
} });
}
@Override }
/* super.onCreateContextMenu(menu);
* }
* }
*/
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);
}
}
Loading…
Cancel
Save