@ -1,3 +1,19 @@
/ *
* 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 .
* /
package net.micode.notes.ui ;
import android.app.Activity ;
@ -58,8 +74,6 @@ import java.util.regex.Pattern;
public class NoteEditActivity extends Activity implements OnClickListener ,
NoteSettingChangedListener , OnTextViewChangeListener {
//该类主要是针对标签的编辑
//继承了系统内部许多和监听有关的类
private class HeadViewHolder {
public TextView tvModified ;
@ -69,7 +83,7 @@ public class NoteEditActivity extends Activity implements OnClickListener,
public ImageView ibSetBgColor ;
}
//使用Map实现数据存储
private static final Map < Integer , Integer > sBgSelectorBtnsMap = new HashMap < Integer , Integer > ( ) ;
static {
sBgSelectorBtnsMap . put ( R . id . iv_bg_yellow , ResourceParser . YELLOW ) ;
@ -77,7 +91,6 @@ public class NoteEditActivity extends Activity implements OnClickListener,
sBgSelectorBtnsMap . put ( R . id . iv_bg_blue , ResourceParser . BLUE ) ;
sBgSelectorBtnsMap . put ( R . id . iv_bg_green , ResourceParser . GREEN ) ;
sBgSelectorBtnsMap . put ( R . id . iv_bg_white , ResourceParser . WHITE ) ;
//put函数是将指定值和指定键相连
}
private static final Map < Integer , Integer > sBgSelectorSelectionMap = new HashMap < Integer , Integer > ( ) ;
@ -87,7 +100,6 @@ public class NoteEditActivity extends Activity implements OnClickListener,
sBgSelectorSelectionMap . put ( ResourceParser . BLUE , R . id . iv_bg_blue_select ) ;
sBgSelectorSelectionMap . put ( ResourceParser . GREEN , R . id . iv_bg_green_select ) ;
sBgSelectorSelectionMap . put ( ResourceParser . WHITE , R . id . iv_bg_white_select ) ;
//put函数是将指定值和指定键相连
}
private static final Map < Integer , Integer > sFontSizeBtnsMap = new HashMap < Integer , Integer > ( ) ;
@ -96,7 +108,6 @@ public class NoteEditActivity extends Activity implements OnClickListener,
sFontSizeBtnsMap . put ( R . id . ll_font_small , ResourceParser . TEXT_SMALL ) ;
sFontSizeBtnsMap . put ( R . id . ll_font_normal , ResourceParser . TEXT_MEDIUM ) ;
sFontSizeBtnsMap . put ( R . id . ll_font_super , ResourceParser . TEXT_SUPER ) ;
//put函数是将指定值和指定键相连
}
private static final Map < Integer , Integer > sFontSelectorSelectionMap = new HashMap < Integer , Integer > ( ) ;
@ -105,7 +116,6 @@ public class NoteEditActivity extends Activity implements OnClickListener,
sFontSelectorSelectionMap . put ( ResourceParser . TEXT_SMALL , R . id . iv_small_select ) ;
sFontSelectorSelectionMap . put ( ResourceParser . TEXT_MEDIUM , R . id . iv_medium_select ) ;
sFontSelectorSelectionMap . put ( ResourceParser . TEXT_SUPER , R . id . iv_super_select ) ;
//put函数是将指定值和指定键相连
}
private static final String TAG = "NoteEditActivity" ;
@ -113,23 +123,20 @@ public class NoteEditActivity extends Activity implements OnClickListener,
private HeadViewHolder mNoteHeaderHolder ;
private View mHeadViewPanel ;
//私有化一个界面操作mHeadViewPanel, 对表头的操作
private View mNoteBgColorSelector ;
//私有化一个界面操作mNoteBgColorSelector, 对背景颜色的操作
private View mFontSizeSelector ;
//私有化一个界面操作mFontSizeSelector, 对标签字体的操作
private EditText mNoteEditor ;
//声明编辑控件,对文本操作
private View mNoteEditorPanel ;
//私有化一个界面操作mNoteEditorPanel, 文本编辑的控制板
//private WorkingNote mWorkingNote;
public WorkingNote mWorkingNote ;
//对模板WorkingNote的初始化
private WorkingNote mWorkingNote ;
private SharedPreferences mSharedPrefs ;
//私有化SharedPreferences的数据存储方式
//它的本质是基于XML文件存储key-value键值对数据
private int mFontSizeId ;
//用于操作字体的大小
private static final String PREFERENCE_FONT_SIZE = "pref_font_size" ;
private static final int SHORTCUT_ICON_TITLE_MAX_LEN = 10 ;
@ -138,7 +145,7 @@ public class NoteEditActivity extends Activity implements OnClickListener,
public static final String TAG_UNCHECKED = String . valueOf ( '\u25A1' ) ;
private LinearLayout mEditTextList ;
//线性布局
private String mUserQuery ;
private Pattern mPattern ;
@ -146,7 +153,7 @@ public class NoteEditActivity extends Activity implements OnClickListener,
protected void onCreate ( Bundle savedInstanceState ) {
super . onCreate ( savedInstanceState ) ;
this . setContentView ( R . layout . note_edit ) ;
//对数据库的访问操作
if ( savedInstanceState = = null & & ! initActivityState ( getIntent ( ) ) ) {
finish ( ) ;
return ;
@ -169,7 +176,7 @@ public class NoteEditActivity extends Activity implements OnClickListener,
return ;
}
Log . d ( TAG , "Restoring from killed activity" ) ;
} //为防止内存不足时程序的终止,在这里有一个保存现场的函数
}
}
private boolean initActivityState ( Intent intent ) {
@ -181,42 +188,34 @@ public class NoteEditActivity extends Activity implements OnClickListener,
if ( TextUtils . equals ( Intent . ACTION_VIEW , intent . getAction ( ) ) ) {
long noteId = intent . getLongExtra ( Intent . EXTRA_UID , 0 ) ;
mUserQuery = "" ;
//如果用户实例化标签时, 系统并未给出标签ID
/ * *
* Starting from the searched result
* /
//根据键值查找ID
if ( intent . hasExtra ( SearchManager . EXTRA_DATA_KEY ) ) {
noteId = Long . parseLong ( intent . getStringExtra ( SearchManager . EXTRA_DATA_KEY ) ) ;
mUserQuery = intent . getStringExtra ( SearchManager . USER_QUERY ) ;
}
//如果ID在数据库中未找到
if ( ! DataUtils . visibleInNoteDatabase ( getContentResolver ( ) , noteId , Notes . TYPE_NOTE ) ) {
Intent jump = new Intent ( this , NotesListActivity . class ) ;
startActivity ( jump ) ;
//程序将跳转到上面声明的intent——jump
showToast ( R . string . error_note_not_exist ) ;
finish ( ) ;
return false ;
}
//ID在数据库中找到
else {
} else {
mWorkingNote = WorkingNote . load ( this , noteId ) ;
if ( mWorkingNote = = null ) {
Log . e ( TAG , "load note failed with note id" + noteId ) ;
//打印出红色的错误信息
finish ( ) ;
return false ;
}
}
//setSoftInputMode——软键盘输入模式
getWindow ( ) . setSoftInputMode (
WindowManager . LayoutParams . SOFT_INPUT_STATE_HIDDEN
| WindowManager . LayoutParams . SOFT_INPUT_ADJUST_RESIZE ) ;
} else if ( TextUtils . equals ( Intent . ACTION_INSERT_OR_EDIT , intent . getAction ( ) ) ) {
// intent.getAction()
// 大多用于broadcast发送广播时给机制( intent) 设置一个action, 就是一个字符串
// 用户可以通过receive( 接受) intent, 通过 getAction得到的字符串, 来决定做什么
// New note
long folderId = intent . getLongExtra ( Notes . INTENT_EXTRA_FOLDER_ID , 0 ) ;
int widgetId = intent . getIntExtra ( Notes . INTENT_EXTRA_WIDGET_ID ,
AppWidgetManager . INVALID_APPWIDGET_ID ) ;
@ -224,7 +223,7 @@ public class NoteEditActivity extends Activity implements OnClickListener,
Notes . TYPE_WIDGET_INVALIDE ) ;
int bgResId = intent . getIntExtra ( Notes . INTENT_EXTRA_BACKGROUND_ID ,
ResourceParser . getDefaultBgId ( this ) ) ;
// intent.getInt( Long、String) Extra是对各变量的语法分析
// Parse call-record note
String phoneNumber = intent . getStringExtra ( Intent . EXTRA_PHONE_NUMBER ) ;
long callDate = intent . getLongExtra ( Notes . INTENT_EXTRA_CALL_DATE , 0 ) ;
@ -241,17 +240,15 @@ public class NoteEditActivity extends Activity implements OnClickListener,
finish ( ) ;
return false ;
}
//将电话号码与手机的号码簿相关
} else {
mWorkingNote = WorkingNote . createEmptyNote ( this , folderId , widgetId ,
widgetType , bgResId ) ;
mWorkingNote . convertToCallNote ( phoneNumber , callDate ) ;
//
}
} else {
mWorkingNote = WorkingNote . createEmptyNote ( this , folderId , widgetId , widgetType ,
bgResId ) ;
} //创建一个新的WorkingNote
}
getWindow ( ) . setSoftInputMode (
WindowManager . LayoutParams . SOFT_INPUT_ADJUST_RESIZE
@ -272,10 +269,8 @@ public class NoteEditActivity extends Activity implements OnClickListener,
}
private void initNoteScreen ( ) {
//对界面的初始化操作
mNoteEditor . setTextAppearance ( this , TextAppearanceResources
. getTexAppearanceResource ( mFontSizeId ) ) ;
//设置外观
if ( mWorkingNote . getCheckListMode ( ) = = TextNote . MODE_CHECK_LIST ) {
switchToListMode ( mWorkingNote . getContent ( ) ) ;
} else {
@ -299,21 +294,18 @@ public class NoteEditActivity extends Activity implements OnClickListener,
* /
showAlertHeader ( ) ;
}
//设置闹钟的显示
private void showAlertHeader ( ) {
if ( mWorkingNote . hasClockAlert ( ) ) {
long time = System . currentTimeMillis ( ) ;
if ( time > mWorkingNote . getAlertDate ( ) ) {
mNoteHeaderHolder . tvAlertDate . setText ( R . string . note_alert_expired ) ;
}
//如果系统时间大于了闹钟设置的时间,那么闹钟失效
else {
} else {
mNoteHeaderHolder . tvAlertDate . setText ( DateUtils . getRelativeTimeSpanString (
mWorkingNote . getAlertDate ( ) , time , DateUtils . MINUTE_IN_MILLIS ) ) ;
}
mNoteHeaderHolder . tvAlertDate . setVisibility ( View . VISIBLE ) ;
mNoteHeaderHolder . ivAlertIcon . setVisibility ( View . VISIBLE ) ;
//显示闹钟开启的图标
} else {
mNoteHeaderHolder . tvAlertDate . setVisibility ( View . GONE ) ;
mNoteHeaderHolder . ivAlertIcon . setVisibility ( View . GONE ) ;
@ -337,29 +329,26 @@ public class NoteEditActivity extends Activity implements OnClickListener,
if ( ! mWorkingNote . existInDatabase ( ) ) {
saveNote ( ) ;
}
//在创建一个新的标签时,先在数据库中匹配
//如果不存在,那么先在数据库中存储
outState . putLong ( Intent . EXTRA_UID , mWorkingNote . getNoteId ( ) ) ;
Log . d ( TAG , "Save working note id: " + mWorkingNote . getNoteId ( ) + " onSaveInstanceState" ) ;
}
@Override
//MotionEvent是对屏幕触控的传递机制
public boolean dispatchTouchEvent ( MotionEvent ev ) {
if ( mNoteBgColorSelector . getVisibility ( ) = = View . VISIBLE
& & ! inRangeOfView ( mNoteBgColorSelector , ev ) ) {
mNoteBgColorSelector . setVisibility ( View . GONE ) ;
return true ;
} //颜色选择器在屏幕上可见
}
if ( mFontSizeSelector . getVisibility ( ) = = View . VISIBLE
& & ! inRangeOfView ( mFontSizeSelector , ev ) ) {
mFontSizeSelector . setVisibility ( View . GONE ) ;
return true ;
} //字体大小选择器在屏幕上可见
}
return super . dispatchTouchEvent ( ev ) ;
}
//对屏幕触控的坐标进行操作
private boolean inRangeOfView ( View view , MotionEvent ev ) {
int [ ] location = new int [ 2 ] ;
view . getLocationOnScreen ( location ) ;
@ -368,9 +357,7 @@ public class NoteEditActivity extends Activity implements OnClickListener,
if ( ev . getX ( ) < x
| | ev . getX ( ) > ( x + view . getWidth ( ) )
| | ev . getY ( ) < y
| | ev . getY ( ) > ( y + view . getHeight ( ) ) )
//如果触控的位置超出了给定的范围, 返回false
{
| | ev . getY ( ) > ( y + view . getHeight ( ) ) ) {
return false ;
}
return true ;
@ -390,13 +377,13 @@ public class NoteEditActivity extends Activity implements OnClickListener,
for ( int id : sBgSelectorBtnsMap . keySet ( ) ) {
ImageView iv = ( ImageView ) findViewById ( id ) ;
iv . setOnClickListener ( this ) ;
} //对标签各项属性内容的初始化
}
mFontSizeSelector = findViewById ( R . id . font_size_selector ) ;
for ( int id : sFontSizeBtnsMap . keySet ( ) ) {
View view = findViewById ( id ) ;
view . setOnClickListener ( this ) ;
} ; //对字体大小的选择
} ;
mSharedPrefs = PreferenceManager . getDefaultSharedPreferences ( this ) ;
mFontSizeId = mSharedPrefs . getInt ( PREFERENCE_FONT_SIZE , ResourceParser . BG_DEFAULT_FONT_SIZE ) ;
/ * *
@ -418,7 +405,7 @@ public class NoteEditActivity extends Activity implements OnClickListener,
}
clearSettingState ( ) ;
}
//和桌面小工具的同步
private void updateWidget ( ) {
Intent intent = new Intent ( AppWidgetManager . ACTION_APPWIDGET_UPDATE ) ;
if ( mWorkingNote . getWidgetType ( ) = = Notes . TYPE_WIDGET_2X ) {
@ -463,7 +450,7 @@ public class NoteEditActivity extends Activity implements OnClickListener,
}
mFontSizeSelector . setVisibility ( View . GONE ) ;
}
} //************************存在问题
}
@Override
public void onBackPressed ( ) {
@ -494,7 +481,6 @@ public class NoteEditActivity extends Activity implements OnClickListener,
}
@Override
//对选择菜单的准备
public boolean onPrepareOptionsMenu ( Menu menu ) {
if ( isFinishing ( ) ) {
return true ;
@ -503,7 +489,6 @@ public class NoteEditActivity extends Activity implements OnClickListener,
menu . clear ( ) ;
if ( mWorkingNote . getFolderId ( ) = = Notes . ID_CALL_RECORD_FOLDER ) {
getMenuInflater ( ) . inflate ( R . menu . call_note_edit , menu ) ;
// MenuInflater是用来实例化Menu目录下的Menu布局文件的
} else {
getMenuInflater ( ) . inflate ( R . menu . note_edit , menu ) ;
}
@ -521,71 +506,45 @@ public class NoteEditActivity extends Activity implements OnClickListener,
}
@Override
/ *
* 函 数 功 能 : 动 态 改 变 菜 单 选 项 内 容
* 函 数 实 现 : 如 下 注 释
* /
public boolean onOptionsItemSelected ( MenuItem item ) {
switch ( item . getItemId ( ) ) {
//根据菜单的id来编剧相关项目
case R . id . menu_new_note :
//创建一个新的便签
createNewNote ( ) ;
break ;
case R . id . menu_delete :
//删除便签
AlertDialog . Builder builder = new AlertDialog . Builder ( this ) ;
//创建关于删除操作的对话框
builder . setTitle ( getString ( R . string . alert_title_delete ) ) ;
// 设置标签的标题为alert_title_delete
builder . setIcon ( android . R . drawable . ic_dialog_alert ) ;
//设置对话框图标
builder . setMessage ( getString ( R . string . alert_message_delete_note ) ) ;
//设置对话框内容
builder . setPositiveButton ( android . R . string . ok ,
new DialogInterface . OnClickListener ( ) {
//建立按键监听器
public void onClick ( DialogInterface dialog , int which ) {
//点击所触发事件
deleteCurrentNote ( ) ;
// 删除单签便签
finish ( ) ;
}
} ) ;
//添加“YES”按钮
builder . setNegativeButton ( android . R . string . cancel , null ) ;
//添加“NO”的按钮
builder . show ( ) ;
//显示对话框
break ;
case R . id . menu_font_size :
//字体大小的编辑
mFontSizeSelector . setVisibility ( View . VISIBLE ) ;
// 将字体选择器置为可见
findViewById ( sFontSelectorSelectionMap . get ( mFontSizeId ) ) . setVisibility ( View . VISIBLE ) ;
// 通过id找到相应的大小
break ;
case R . id . menu_list_mode :
//选择列表模式
mWorkingNote . setCheckListMode ( mWorkingNote . getCheckListMode ( ) = = 0 ?
TextNote . MODE_CHECK_LIST : 0 ) ;
break ;
case R . id . menu_share :
//菜单共享
getWorkingText ( ) ;
sendTo ( this , mWorkingNote . getContent ( ) ) ;
// 用sendto函数将运行文本发送到遍历的本文内
break ;
case R . id . menu_send_to_desktop :
//发送到桌面
sendToDesktop ( ) ;
break ;
case R . id . menu_alert :
//创建提醒器
setReminder ( ) ;
break ;
case R . id . menu_delete_remind :
//删除日期提醒
mWorkingNote . setAlertDate ( 0 , false ) ;
break ;
default :
@ -594,170 +553,111 @@ public class NoteEditActivity extends Activity implements OnClickListener,
return true ;
}
/ *
* 函 数 功 能 : 建 立 事 件 提 醒 器
* 函 数 实 现 : 如 下 注 释
* /
private void setReminder ( ) {
DateTimePickerDialog d = new DateTimePickerDialog ( this , System . currentTimeMillis ( ) ) ;
// 建立修改时间日期的对话框
d . setOnDateTimeSetListener ( new OnDateTimeSetListener ( ) {
public void OnDateTimeSet ( AlertDialog dialog , long date ) {
mWorkingNote . setAlertDate ( date , true ) ;
//选择提醒的日期
}
} ) ;
//建立时间日期的监听器
d . show ( ) ;
//显示对话框
}
/ * *
* Share note to apps that support { @link Intent # ACTION_SEND } action
* and { @text / plain } type
* /
/ *
* 函 数 功 能 : 共 享 便 签
* 函 数 实 现 : 如 下 注 释
* /
private void sendTo ( Context context , String info ) {
Intent intent = new Intent ( Intent . ACTION_SEND ) ;
//建立intent链接选项
intent . putExtra ( Intent . EXTRA_TEXT , info ) ;
//将需要传递的便签信息放入text文件中
intent . setType ( "text/plain" ) ;
//编辑连接器的类型
context . startActivity ( intent ) ;
//在acti中进行链接
}
/ *
* 函 数 功 能 : 创 建 一 个 新 的 便 签
* 函 数 实 现 : 如 下 注 释
* /
private void createNewNote ( ) {
// Firstly, save current editing notes
//保存当前便签
saveNote ( ) ;
// For safety, start a new NoteEditActivity
finish ( ) ;
Intent intent = new Intent ( this , NoteEditActivity . class ) ;
//设置链接器
intent . setAction ( Intent . ACTION_INSERT_OR_EDIT ) ;
//该活动定义为创建或编辑
intent . putExtra ( Notes . INTENT_EXTRA_FOLDER_ID , mWorkingNote . getFolderId ( ) ) ;
//将运行便签的id添加到INTENT_EXTRA_FOLDER_ID标记中
startActivity ( intent ) ;
//开始activity并链接
}
/ *
* 函 数 功 能 : 删 除 当 前 便 签
* 函 数 实 现 : 如 下 注 释
* /
private void deleteCurrentNote ( ) {
if ( mWorkingNote . existInDatabase ( ) ) {
//假如当前运行的便签内存有数据
HashSet < Long > ids = new HashSet < Long > ( ) ;
long id = mWorkingNote . getNoteId ( ) ;
if ( id ! = Notes . ID_ROOT_FOLDER ) {
ids . add ( id ) ;
//如果不是头文件夹建立一个hash表把便签id存起来
} else {
Log . d ( TAG , "Wrong note id, should not happen" ) ;
//否则报错
}
if ( ! isSyncMode ( ) ) {
//在非同步模式情况下
//删除操作
if ( ! DataUtils . batchDeleteNotes ( getContentResolver ( ) , ids ) ) {
Log . e ( TAG , "Delete Note error" ) ;
}
} else {
//同步模式
//移动至垃圾文件夹的操作
if ( ! DataUtils . batchMoveToFolder ( getContentResolver ( ) , ids , Notes . ID_TRASH_FOLER ) ) {
Log . e ( TAG , "Move notes to trash folder error, should not happens" ) ;
}
}
}
mWorkingNote . markDeleted ( true ) ;
//将这些标签的删除标记置为true
}
/ *
* 函 数 功 能 : 判 断 是 否 为 同 步 模 式
* 函 数 实 现 : 直 接 看 NotesPreferenceActivity 中 同 步 名 称 是 否 为 空
* /
private boolean isSyncMode ( ) {
return NotesPreferenceActivity . getSyncAccountName ( this ) . trim ( ) . length ( ) > 0 ;
}
/ *
* 函 数 功 能 : 设 置 提 醒 时 间
* 函 数 实 现 : 如 下 注 释
* /
public void onClockAlertChanged ( long date , boolean set ) {
/ * *
* User could set clock to an unsaved note , so before setting the
* alert clock , we should save the note first
* /
if ( ! mWorkingNote . existInDatabase ( ) ) {
//首先保存已有的便签
saveNote ( ) ;
}
if ( mWorkingNote . getNoteId ( ) > 0 ) {
Intent intent = new Intent ( this , AlarmReceiver . class ) ;
intent . setData ( ContentUris . withAppendedId ( Notes . CONTENT_NOTE_URI , mWorkingNote . getNoteId ( ) ) ) ;
//若有有运行的便签就是建立一个链接器将标签id都存在uri中
PendingIntent pendingIntent = PendingIntent . getBroadcast ( this , 0 , intent , 0 ) ;
AlarmManager alarmManager = ( ( AlarmManager ) getSystemService ( ALARM_SERVICE ) ) ;
//设置提醒管理器
showAlertHeader ( ) ;
if ( ! set ) {
alarmManager . cancel ( pendingIntent ) ;
} else {
alarmManager . set ( AlarmManager . RTC_WAKEUP , date , pendingIntent ) ;
}
//如果用户设置了时间,就通过提醒管理器设置一个监听事项
} else {
/ * *
* There is the condition that user has input nothing ( the note is
* not worthy saving ) , we have no note id , remind the user that he
* should input something
* /
//没有运行的便签就报错
Log . e ( TAG , "Clock alert setting error" ) ;
showToast ( R . string . error_note_empty_for_clock ) ;
}
}
/ *
* 函 数 功 能 : Widget 发 生 改 变 的 所 触 发 的 事 件
* /
public void onWidgetChanged ( ) {
updateWidget ( ) ; //更新Widget
updateWidget ( ) ;
}
/ *
* 函 数 功 能 : 删 除 编 辑 文 本 框 所 触 发 的 事 件
* 函 数 实 现 : 如 下 注 释
* /
public void onEditTextDelete ( int index , String text ) {
int childCount = mEditTextList . getChildCount ( ) ;
if ( childCount = = 1 ) {
return ;
}
//没有编辑框的话直接返回
for ( int i = index + 1 ; i < childCount ; i + + ) {
( ( NoteEditText ) mEditTextList . getChildAt ( i ) . findViewById ( R . id . et_edit_text ) )
. setIndex ( i - 1 ) ;
//通过id把编辑框存在便签编辑框中
}
mEditTextList . removeViewAt ( index ) ;
//删除特定位置的视图
NoteEditText edit = null ;
if ( index = = 0 ) {
edit = ( NoteEditText ) mEditTextList . getChildAt ( 0 ) . findViewById (
@ -766,101 +666,69 @@ public class NoteEditActivity extends Activity implements OnClickListener,
edit = ( NoteEditText ) mEditTextList . getChildAt ( index - 1 ) . findViewById (
R . id . et_edit_text ) ;
}
//通过id把编辑框存在空的NoteEditText中
int length = edit . length ( ) ;
edit . append ( text ) ;
edit . requestFocus ( ) ; //请求优先完成该此 编辑
edit . setSelection ( length ) ; //定位到length位置处的条目
edit . requestFocus ( ) ;
edit . setSelection ( length ) ;
}
/ *
* 函 数 功 能 : 进 入 编 辑 文 本 框 所 触 发 的 事 件
* 函 数 实 现 : 如 下 注 释
* /
public void onEditTextEnter ( int index , String text ) {
/ * *
* Should not happen , check for debug
* /
if ( index > mEditTextList . getChildCount ( ) ) {
Log . e ( TAG , "Index out of mEditTextList boundrary, should not happen" ) ;
//越界把偶偶
}
View view = getListItem ( text , index ) ;
mEditTextList . addView ( view , index ) ;
//建立一个新的视图并添加到编辑文本框内
NoteEditText edit = ( NoteEditText ) view . findViewById ( R . id . et_edit_text ) ;
edit . requestFocus ( ) ; //请求优先操作
edit . setSelection ( 0 ) ; //定位到起始位置
edit . requestFocus ( ) ;
edit . setSelection ( 0 ) ;
for ( int i = index + 1 ; i < mEditTextList . getChildCount ( ) ; i + + ) {
( ( NoteEditText ) mEditTextList . getChildAt ( i ) . findViewById ( R . id . et_edit_text ) )
. setIndex ( i ) ;
//遍历子文本框并设置对应对下标
}
}
/ *
* 函 数 功 能 : 切 换 至 列 表 模 式
* 函 数 实 现 : 如 下 注 释
* /
private void switchToListMode ( String text ) {
mEditTextList . removeAllViews ( ) ;
String [ ] items = text . split ( "\n" ) ;
int index = 0 ;
//清空所有视图,初始化下标
for ( String item : items ) {
if ( ! TextUtils . isEmpty ( item ) ) {
mEditTextList . addView ( getListItem ( item , index ) ) ;
index + + ;
//遍历所有文本单元并添加到文本框中
}
}
mEditTextList . addView ( getListItem ( "" , index ) ) ;
mEditTextList . getChildAt ( index ) . findViewById ( R . id . et_edit_text ) . requestFocus ( ) ;
//优先请求此操作
mNoteEditor . setVisibility ( View . GONE ) ;
//便签编辑器不可见
mEditTextList . setVisibility ( View . VISIBLE ) ;
//将文本编辑框置为可见
}
/ *
* 函 数 功 能 : 获 取 高 亮 效 果 的 反 馈 情 况
* 函 数 实 现 : 如 下 注 释
* /
private Spannable getHighlightQueryResult ( String fullText , String userQuery ) {
SpannableString spannable = new SpannableString ( fullText = = null ? "" : fullText ) ;
//新建一个效果选项
if ( ! TextUtils . isEmpty ( userQuery ) ) {
mPattern = Pattern . compile ( userQuery ) ;
//将用户的询问进行解析
Matcher m = mPattern . matcher ( fullText ) ;
//建立一个状态机检查Pattern并进行匹配
int start = 0 ;
while ( m . find ( start ) ) {
spannable . setSpan (
new BackgroundColorSpan ( this . getResources ( ) . getColor (
R . color . user_query_highlight ) ) , m . start ( ) , m . end ( ) ,
Spannable . SPAN_INCLUSIVE_EXCLUSIVE ) ;
//设置背景颜色
start = m . end ( ) ;
//跟新起始位置
}
}
return spannable ;
}
/ *
* 函 数 功 能 : 获 取 列 表 项
* 函 数 实 现 : 如 下 注 释
* /
private View getListItem ( String item , int index ) {
View view = LayoutInflater . from ( this ) . inflate ( R . layout . note_edit_list_item , null ) ;
//创建一个视图
final NoteEditText edit = ( NoteEditText ) view . findViewById ( R . id . et_edit_text ) ;
edit . setTextAppearance ( this , TextAppearanceResources . getTexAppearanceResource ( mFontSizeId ) ) ;
//创建一个文本编辑框并设置可见性
CheckBox cb = ( ( CheckBox ) view . findViewById ( R . id . cb_edit_item ) ) ;
cb . setOnCheckedChangeListener ( new OnCheckedChangeListener ( ) {
public void onCheckedChanged ( CompoundButton buttonView , boolean isChecked ) {
@ -871,15 +739,12 @@ public class NoteEditActivity extends Activity implements OnClickListener,
}
}
} ) ;
//建立一个打钩框并设置监听器
if ( item . startsWith ( TAG_CHECKED ) ) {
//选择勾选
cb . setChecked ( true ) ;
edit . setPaintFlags ( edit . getPaintFlags ( ) | Paint . STRIKE_THRU_TEXT_FLAG ) ;
item = item . substring ( TAG_CHECKED . length ( ) , item . length ( ) ) . trim ( ) ;
} else if ( item . startsWith ( TAG_UNCHECKED ) ) {
//选择不勾选
cb . setChecked ( false ) ;
edit . setPaintFlags ( Paint . ANTI_ALIAS_FLAG | Paint . DEV_KERN_TEXT_FLAG ) ;
item = item . substring ( TAG_UNCHECKED . length ( ) , item . length ( ) ) . trim ( ) ;
@ -888,94 +753,61 @@ public class NoteEditActivity extends Activity implements OnClickListener,
edit . setOnTextViewChangeListener ( this ) ;
edit . setIndex ( index ) ;
edit . setText ( getHighlightQueryResult ( item , mUserQuery ) ) ;
//运行编辑框的监听器对该行为作出反应,并设置下标及文本内容
return view ;
}
/ *
* 函 数 功 能 : 便 签 内 容 发 生 改 变 所 触 发 的 事 件
* 函 数 实 现 : 如 下 注 释
* /
public void onTextChange ( int index , boolean hasText ) {
if ( index > = mEditTextList . getChildCount ( ) ) {
Log . e ( TAG , "Wrong index, should not happen" ) ;
return ;
//越界报错
}
if ( hasText ) {
mEditTextList . getChildAt ( index ) . findViewById ( R . id . cb_edit_item ) . setVisibility ( View . VISIBLE ) ;
} else {
mEditTextList . getChildAt ( index ) . findViewById ( R . id . cb_edit_item ) . setVisibility ( View . GONE ) ;
}
//如果内容不为空则将其子编辑框可见性置为可见,否则不可见
}
/ *
* 函 数 功 能 : 检 查 模 式 和 列 表 模 式 的 切 换
* 函 数 实 现 : 如 下 注 释
* /
public void onCheckListModeChanged ( int oldMode , int newMode ) {
if ( newMode = = TextNote . MODE_CHECK_LIST ) {
switchToListMode ( mNoteEditor . getText ( ) . toString ( ) ) ;
//检查模式切换到列表模式
} else {
if ( ! getWorkingText ( ) ) {
mWorkingNote . setWorkingText ( mWorkingNote . getContent ( ) . replace ( TAG_UNCHECKED + " " ,
"" ) ) ;
}
//若是获取到文本就改变其检查标记
mNoteEditor . setText ( getHighlightQueryResult ( mWorkingNote . getContent ( ) , mUserQuery ) ) ;
mEditTextList . setVisibility ( View . GONE ) ;
mNoteEditor . setVisibility ( View . VISIBLE ) ;
//修改文本编辑器的内容和可见性
}
}
/ *
* 函 数 功 能 : 设 置 勾 选 选 项 表 并 返 回 是 否 勾 选 的 标 记
* 函 数 实 现 : 如 下 注 释
* /
private boolean getWorkingText ( ) {
boolean hasChecked = false ;
//初始化check标记
if ( mWorkingNote . getCheckListMode ( ) = = TextNote . MODE_CHECK_LIST ) {
// 若模式为CHECK_LIST
StringBuilder sb = new StringBuilder ( ) ;
//创建可变字符串
for ( int i = 0 ; i < mEditTextList . getChildCount ( ) ; i + + ) {
View view = mEditTextList . getChildAt ( i ) ;
//遍历所有子编辑框的视图
NoteEditText edit = ( NoteEditText ) view . findViewById ( R . id . et_edit_text ) ;
if ( ! TextUtils . isEmpty ( edit . getText ( ) ) ) {
//若文本不为空
if ( ( ( CheckBox ) view . findViewById ( R . id . cb_edit_item ) ) . isChecked ( ) ) {
//该选项框已打钩
sb . append ( TAG_CHECKED ) . append ( " " ) . append ( edit . getText ( ) ) . append ( "\n" ) ;
hasChecked = true ;
//扩展字符串为已打钩并把标记置true
} else {
sb . append ( TAG_UNCHECKED ) . append ( " " ) . append ( edit . getText ( ) ) . append ( "\n" ) ;
//扩展字符串添加未打钩
}
}
}
mWorkingNote . setWorkingText ( sb . toString ( ) ) ;
//利用编辑好的字符串设置运行便签的内容
} else {
mWorkingNote . setWorkingText ( mNoteEditor . getText ( ) . toString ( ) ) ;
// 若不是该模式直接用编辑器中的内容设置运行中标签的内容
}
return hasChecked ;
}
/ *
* 函 数 功 能 : 保 存 便 签
* 函 数 实 现 : 如 下 注 释
* /
private boolean saveNote ( ) {
getWorkingText ( ) ;
boolean saved = mWorkingNote . saveNote ( ) ;
//运行 getWorkingText()之后保存
if ( saved ) {
/ * *
* There are two modes from List view to edit view , open one note ,
@ -984,16 +816,11 @@ public class NoteEditActivity extends Activity implements OnClickListener,
* new node requires to the top of the list . This code
* { @link # RESULT_OK } is used to identify the create / edit state
* /
//如英文注释所说链接RESULT_OK是为了识别保存的2种情况, 一是创建后保存, 二是修改后保存
setResult ( RESULT_OK ) ;
}
return saved ;
}
/ *
* 函 数 功 能 : 将 便 签 发 送 至 桌 面
* 函 数 实 现 : 如 下 注 释
* /
private void sendToDesktop ( ) {
/ * *
* Before send message to home , we should make sure that current
@ -1002,16 +829,12 @@ public class NoteEditActivity extends Activity implements OnClickListener,
* /
if ( ! mWorkingNote . existInDatabase ( ) ) {
saveNote ( ) ;
//若不存在数据也就是新的标签就保存起来先
}
if ( mWorkingNote . getNoteId ( ) > 0 ) {
//若是有内容
Intent sender = new Intent ( ) ;
Intent shortcutIntent = new Intent ( this , NoteEditActivity . class ) ;
//建立发送到桌面的连接器
shortcutIntent . setAction ( Intent . ACTION_VIEW ) ;
//链接为一个视图
shortcutIntent . putExtra ( Intent . EXTRA_UID , mWorkingNote . getNoteId ( ) ) ;
sender . putExtra ( Intent . EXTRA_SHORTCUT_INTENT , shortcutIntent ) ;
sender . putExtra ( Intent . EXTRA_SHORTCUT_NAME ,
@ -1019,12 +842,9 @@ public class NoteEditActivity extends Activity implements OnClickListener,
sender . putExtra ( Intent . EXTRA_SHORTCUT_ICON_RESOURCE ,
Intent . ShortcutIconResource . fromContext ( this , R . drawable . icon_app ) ) ;
sender . putExtra ( "duplicate" , true ) ;
//将便签的相关信息都添加到要发送的文件里
sender . setAction ( "com.android.launcher.action.INSTALL_SHORTCUT" ) ;
//设置sneder的行为是发送
showToast ( R . string . info_note_enter_desktop ) ;
sendBroadcast ( sender ) ;
//显示到桌面
} else {
/ * *
* There is the condition that user has input nothing ( the note is
@ -1033,34 +853,20 @@ public class NoteEditActivity extends Activity implements OnClickListener,
* /
Log . e ( TAG , "Send to desktop error" ) ;
showToast ( R . string . error_note_empty_for_send_to_desktop ) ;
//空便签直接报错
}
}
/ *
* 函 数 功 能 : 编 辑 小 图 标 的 标 题
* 函 数 实 现 : 如 下 注 释
* /
private String makeShortcutIconTitle ( String content ) {
content = content . replace ( TAG_CHECKED , "" ) ;
content = content . replace ( TAG_UNCHECKED , "" ) ;
return content . length ( ) > SHORTCUT_ICON_TITLE_MAX_LEN ? content . substring ( 0 ,
SHORTCUT_ICON_TITLE_MAX_LEN ) : content ;
//直接设置为content中的内容并返回, 有勾选和未勾选2种
}
/ *
* 函 数 功 能 : 显 示 提 示 的 视 图
* 函 数 实 现 : 根 据 下 标 显 示 对 应 的 提 示
* /
private void showToast ( int resId ) {
showToast ( resId , Toast . LENGTH_SHORT ) ;
}
/ *
* 函 数 功 能 : 持 续 显 示 提 示 的 视 图
* 函 数 实 现 : 根 据 下 标 和 持 续 的 时 间 ( duration ) 编 辑 提 示 视 图 并 显 示
* /
private void showToast ( int resId , int duration ) {
Toast . makeText ( this , resId , duration ) . show ( ) ;
}