From 8e88359dfea766ef278df66560ba10f8de2c257a Mon Sep 17 00:00:00 2001 From: eazzy <1044745821@qq.com> Date: Sun, 10 Dec 2023 00:01:22 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B3=A8=E9=87=8A=E4=BA=86ui=E5=8C=85=E5=A4=A7?= =?UTF-8?q?=E9=83=A8=E5=88=86=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../micode/notes/ui/AlarmInitReceiver.java | 31 +++----- .../net/micode/notes/ui/AlarmReceiver.java | 22 ++---- .../net/micode/notes/ui/DateTimePicker.java | 78 ++++++++++--------- .../micode/notes/ui/DateTimePickerDialog.java | 43 +++++----- .../net/micode/notes/ui/DropdownMenu.java | 28 ++----- .../micode/notes/ui/FoldersListAdapter.java | 39 ++++------ .../net/micode/notes/ui/NoteEditText.java | 67 +++++++++++++++- 7 files changed, 166 insertions(+), 142 deletions(-) diff --git a/src/main/java/net/micode/notes/ui/AlarmInitReceiver.java b/src/main/java/net/micode/notes/ui/AlarmInitReceiver.java index f221202..4163ccd 100644 --- a/src/main/java/net/micode/notes/ui/AlarmInitReceiver.java +++ b/src/main/java/net/micode/notes/ui/AlarmInitReceiver.java @@ -1,19 +1,3 @@ -/* - * 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.AlarmManager; @@ -31,21 +15,25 @@ import net.micode.notes.data.Notes.NoteColumns; public class AlarmInitReceiver extends BroadcastReceiver { private static final String [] PROJECTION = new String [] { - NoteColumns.ID, - NoteColumns.ALERTED_DATE + NoteColumns.ID, + NoteColumns.ALERTED_DATE }; - + //对数据库的操作,调用标签ID和闹钟时间 private static final int COLUMN_ID = 0; private static final int COLUMN_ALERTED_DATE = 1; @Override public void onReceive(Context context, Intent intent) { long currentDate = System.currentTimeMillis(); + //System.currentTimeMillis()产生一个当前的毫秒 + //这个毫秒其实就是自1970年1月1日0时起的毫秒数 Cursor c = context.getContentResolver().query(Notes.CONTENT_NOTE_URI, PROJECTION, NoteColumns.ALERTED_DATE + ">? AND " + NoteColumns.TYPE + "=" + Notes.TYPE_NOTE, new String[] { String.valueOf(currentDate) }, + //将long变量currentDate转化为字符串 null); + //Cursor在这里的作用是通过查找数据库中的标签内容,找到和当前系统时间相等的标签 if (c != null) { if (c.moveToFirst()) { @@ -61,5 +49,8 @@ public class AlarmInitReceiver extends BroadcastReceiver { } c.close(); } + //然而通过网上查找资料发现,对于闹钟机制的启动,通常需要上面的几个步骤 + //如新建Intent、PendingIntent以及AlarmManager等 + //这里就是根据数据库里的闹钟时间创建一个闹钟机制 } -} +} \ No newline at end of file diff --git a/src/main/java/net/micode/notes/ui/AlarmReceiver.java b/src/main/java/net/micode/notes/ui/AlarmReceiver.java index 54e503b..6e22aff 100644 --- a/src/main/java/net/micode/notes/ui/AlarmReceiver.java +++ b/src/main/java/net/micode/notes/ui/AlarmReceiver.java @@ -1,19 +1,3 @@ -/* - * 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.content.BroadcastReceiver; @@ -24,7 +8,13 @@ public class AlarmReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { intent.setClass(context, AlarmAlertActivity.class); + //启动AlarmAlertActivity intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + //activity要存在于activity的栈中,而非activity的途径启动activity时必然不存在一个activity的栈 + //所以要新起一个栈装入启动的activity context.startActivity(intent); } } +//这是实现alarm这个功能最接近用户层的包,基于上面的两个包, +//作用还需要深究但是对于setClass和addFlags的 + \ No newline at end of file diff --git a/src/main/java/net/micode/notes/ui/DateTimePicker.java b/src/main/java/net/micode/notes/ui/DateTimePicker.java index 496b0cd..8d74062 100644 --- a/src/main/java/net/micode/notes/ui/DateTimePicker.java +++ b/src/main/java/net/micode/notes/ui/DateTimePicker.java @@ -1,19 +1,3 @@ -/* - * 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 java.text.DateFormatSymbols; @@ -29,7 +13,8 @@ import android.widget.FrameLayout; import android.widget.NumberPicker; public class DateTimePicker extends FrameLayout { - + //FrameLayout是布局模板之一 + //所有的子元素全部在屏幕的右上方 private static final boolean DEFAULT_ENABLE_STATE = true; private static final int HOURS_IN_HALF_DAY = 12; @@ -45,13 +30,15 @@ public class DateTimePicker extends FrameLayout { private static final int MINUT_SPINNER_MAX_VAL = 59; private static final int AMPM_SPINNER_MIN_VAL = 0; private static final int AMPM_SPINNER_MAX_VAL = 1; - + //初始化控件 private final NumberPicker mDateSpinner; private final NumberPicker mHourSpinner; private final NumberPicker mMinuteSpinner; private final NumberPicker mAmPmSpinner; + //NumberPicker是数字选择器 + //这里定义的四个变量全部是在设置闹钟时需要选择的变量(如日期、时、分、上午或者下午) private Calendar mDate; - + //定义了Calendar类型的变量mDate,用于操作时间 private String[] mDateDisplayValues = new String[DAYS_IN_ALL_WEEK]; private boolean mIsAm; @@ -71,41 +58,49 @@ public class DateTimePicker extends FrameLayout { updateDateControl(); onDateTimeChanged(); } - }; + };//OnValueChangeListener,这是时间改变监听器,这里主要是对日期的监听 + //将现在日期的值传递给mDate;updateDateControl是同步操作 private NumberPicker.OnValueChangeListener mOnHourChangedListener = new NumberPicker.OnValueChangeListener() { + //这里是对 小时(Hour) 的监听 @Override public void onValueChange(NumberPicker picker, int oldVal, int newVal) { boolean isDateChanged = false; Calendar cal = Calendar.getInstance(); + //声明一个Calendar的变量cal,便于后续的操作 if (!mIs24HourView) { if (!mIsAm && oldVal == HOURS_IN_HALF_DAY - 1 && newVal == HOURS_IN_HALF_DAY) { cal.setTimeInMillis(mDate.getTimeInMillis()); cal.add(Calendar.DAY_OF_YEAR, 1); isDateChanged = true; + //这里是对于12小时制时,晚上11点和12点交替时对日期的更改 } else if (mIsAm && oldVal == HOURS_IN_HALF_DAY && newVal == HOURS_IN_HALF_DAY - 1) { cal.setTimeInMillis(mDate.getTimeInMillis()); cal.add(Calendar.DAY_OF_YEAR, -1); isDateChanged = true; } + //这里是对于12小时制时,凌晨11点和12点交替时对日期的更改 if (oldVal == HOURS_IN_HALF_DAY - 1 && newVal == HOURS_IN_HALF_DAY || oldVal == HOURS_IN_HALF_DAY && newVal == HOURS_IN_HALF_DAY - 1) { mIsAm = !mIsAm; updateAmPmControl(); - } + }//这里是对于12小时制时,中午11点和12点交替时对AM和PM的更改 } else { if (oldVal == HOURS_IN_ALL_DAY - 1 && newVal == 0) { cal.setTimeInMillis(mDate.getTimeInMillis()); cal.add(Calendar.DAY_OF_YEAR, 1); isDateChanged = true; + //这里是对于24小时制时,晚上11点和12点交替时对日期的更改 } else if (oldVal == 0 && newVal == HOURS_IN_ALL_DAY - 1) { cal.setTimeInMillis(mDate.getTimeInMillis()); cal.add(Calendar.DAY_OF_YEAR, -1); isDateChanged = true; } - } + } //这里是对于12小时制时,凌晨11点和12点交替时对日期的更改 int newHour = mHourSpinner.getValue() % HOURS_IN_HALF_DAY + (mIsAm ? 0 : HOURS_IN_HALF_DAY); + //通过数字选择器对newHour的赋值 mDate.set(Calendar.HOUR_OF_DAY, newHour); + //通过set函数将新的Hour值传给mDate onDateTimeChanged(); if (isDateChanged) { setCurrentYear(cal.get(Calendar.YEAR)); @@ -117,15 +112,19 @@ public class DateTimePicker extends FrameLayout { private NumberPicker.OnValueChangeListener mOnMinuteChangedListener = new NumberPicker.OnValueChangeListener() { @Override + //这里是对 分钟(Minute)改变的监听 public void onValueChange(NumberPicker picker, int oldVal, int newVal) { int minValue = mMinuteSpinner.getMinValue(); int maxValue = mMinuteSpinner.getMaxValue(); int offset = 0; + //设置offset,作为小时改变的一个记录数据 if (oldVal == maxValue && newVal == minValue) { offset += 1; } else if (oldVal == minValue && newVal == maxValue) { offset -= 1; } + //如果原值为59,新值为0,则offset加1 + //如果原值为0,新值为59,则offset减1 if (offset != 0) { mDate.add(Calendar.HOUR_OF_DAY, offset); mHourSpinner.setValue(getCurrentHour()); @@ -145,6 +144,7 @@ public class DateTimePicker extends FrameLayout { }; private NumberPicker.OnValueChangeListener mOnAmPmChangedListener = new NumberPicker.OnValueChangeListener() { + //对AM和PM的监听 @Override public void onValueChange(NumberPicker picker, int oldVal, int newVal) { mIsAm = !mIsAm; @@ -160,24 +160,27 @@ public class DateTimePicker extends FrameLayout { public interface OnDateTimeChangedListener { void onDateTimeChanged(DateTimePicker view, int year, int month, - int dayOfMonth, int hourOfDay, int minute); + int dayOfMonth, int hourOfDay, int minute); } public DateTimePicker(Context context) { this(context, System.currentTimeMillis()); - } + }//通过对数据库的访问,获取当前的系统时间 public DateTimePicker(Context context, long date) { this(context, date, DateFormat.is24HourFormat(context)); - } + }//上面函数的得到的是一个天文数字(1970至今的秒数),需要DateFormat将其变得有意义 public DateTimePicker(Context context, long date, boolean is24HourView) { super(context); + //获取系统时间 mDate = Calendar.getInstance(); mInitialising = true; mIsAm = getCurrentHourOfDay() >= HOURS_IN_HALF_DAY; inflate(context, R.layout.datetime_picker, this); - + //如果当前Activity里用到别的layout,比如对话框layout + //还要设置这个layout上的其他组件的内容,就必须用inflate()方法先将对话框的layout找出来 + //然后再用findViewById()找到它上面的其它组件 mDateSpinner = (NumberPicker) findViewById(R.id.date); mDateSpinner.setMinValue(DATE_SPINNER_MIN_VAL); mDateSpinner.setMaxValue(DATE_SPINNER_MAX_VAL); @@ -185,7 +188,7 @@ public class DateTimePicker extends FrameLayout { mHourSpinner = (NumberPicker) findViewById(R.id.hour); mHourSpinner.setOnValueChangedListener(mOnHourChangedListener); - mMinuteSpinner = (NumberPicker) findViewById(R.id.minute); + mMinuteSpinner = (NumberPicker) findViewById(R.id.minute); mMinuteSpinner.setMinValue(MINUT_SPINNER_MIN_VAL); mMinuteSpinner.setMaxValue(MINUT_SPINNER_MAX_VAL); mMinuteSpinner.setOnLongPressUpdateInterval(100); @@ -226,7 +229,9 @@ public class DateTimePicker extends FrameLayout { mAmPmSpinner.setEnabled(enabled); mIsEnabled = enabled; } - + //存在疑问!!!!!!!!!!!!!setEnabled的作用 + //下面的代码通过原程序的注释已经比较清晰,另外可以通过函数名来判断 + //下面的各函数主要是对上面代码引用到的各函数功能的实现 @Override public boolean isEnabled() { return mIsEnabled; @@ -239,7 +244,7 @@ public class DateTimePicker extends FrameLayout { */ public long getCurrentDateInTimeMillis() { return mDate.getTimeInMillis(); - } + }//实现函数——得到当前的秒数 /** * Set the current date @@ -251,7 +256,7 @@ public class DateTimePicker extends FrameLayout { cal.setTimeInMillis(date); setCurrentDate(cal.get(Calendar.YEAR), cal.get(Calendar.MONTH), cal.get(Calendar.DAY_OF_MONTH), cal.get(Calendar.HOUR_OF_DAY), cal.get(Calendar.MINUTE)); - } + }//实现函数功能——设置当前的时间,参数是date /** * Set the current date @@ -263,19 +268,20 @@ public class DateTimePicker extends FrameLayout { * @param minute The current minute */ public void setCurrentDate(int year, int month, - int dayOfMonth, int hourOfDay, int minute) { + int dayOfMonth, int hourOfDay, int minute) { setCurrentYear(year); setCurrentMonth(month); setCurrentDay(dayOfMonth); setCurrentHour(hourOfDay); setCurrentMinute(minute); - } + }//实现函数功能——设置当前的时间,参数是各详细的变量 /** * Get current year * * @return The current year */ + //下面是得到year、month、day等值 public int getCurrentYear() { return mDate.get(Calendar.YEAR); } @@ -446,7 +452,7 @@ public class DateTimePicker extends FrameLayout { mDateSpinner.setDisplayedValues(mDateDisplayValues); mDateSpinner.setValue(DAYS_IN_ALL_WEEK / 2); mDateSpinner.invalidate(); - } + }// 对于星期几的算法 private void updateAmPmControl() { if (mIs24HourView) { @@ -455,7 +461,7 @@ public class DateTimePicker extends FrameLayout { int index = mIsAm ? Calendar.AM : Calendar.PM; mAmPmSpinner.setValue(index); mAmPmSpinner.setVisibility(View.VISIBLE); - } + }// 对于上下午操作的算法 } private void updateHourControl() { @@ -465,7 +471,7 @@ public class DateTimePicker extends FrameLayout { } else { mHourSpinner.setMinValue(HOUR_SPINNER_MIN_VAL_12_HOUR_VIEW); mHourSpinner.setMaxValue(HOUR_SPINNER_MAX_VAL_12_HOUR_VIEW); - } + }// 对与小时的算法 } /** @@ -482,4 +488,4 @@ public class DateTimePicker extends FrameLayout { getCurrentMonth(), getCurrentDay(), getCurrentHourOfDay(), getCurrentMinute()); } } -} +} \ No newline at end of file diff --git a/src/main/java/net/micode/notes/ui/DateTimePickerDialog.java b/src/main/java/net/micode/notes/ui/DateTimePickerDialog.java index 2c47ba4..d6ad95e 100644 --- a/src/main/java/net/micode/notes/ui/DateTimePickerDialog.java +++ b/src/main/java/net/micode/notes/ui/DateTimePickerDialog.java @@ -1,19 +1,3 @@ -/* - * 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 java.util.Calendar; @@ -32,35 +16,47 @@ import android.text.format.DateUtils; public class DateTimePickerDialog extends AlertDialog implements OnClickListener { private Calendar mDate = Calendar.getInstance(); + //创建一个Calendar类型的变量 mDate,方便时间的操作 private boolean mIs24HourView; private OnDateTimeSetListener mOnDateTimeSetListener; + //声明一个时间日期滚动选择控件 mOnDateTimeSetListener private DateTimePicker mDateTimePicker; + //DateTimePicker控件,控件一般用于让用户可以从日期列表中选择单个值。 + //运行时,单击控件边上的下拉箭头,会显示为两个部分:一个下拉列表,一个用于选择日期的 public interface OnDateTimeSetListener { void OnDateTimeSet(AlertDialog dialog, long date); } public DateTimePickerDialog(Context context, long date) { + //对该界面对话框的实例化 super(context); + //对数据库的操作 mDateTimePicker = new DateTimePicker(context); setView(mDateTimePicker); + //添加一个子视图 mDateTimePicker.setOnDateTimeChangedListener(new OnDateTimeChangedListener() { public void onDateTimeChanged(DateTimePicker view, int year, int month, - int dayOfMonth, int hourOfDay, int minute) { + int dayOfMonth, int hourOfDay, int minute) { mDate.set(Calendar.YEAR, year); mDate.set(Calendar.MONTH, month); mDate.set(Calendar.DAY_OF_MONTH, dayOfMonth); mDate.set(Calendar.HOUR_OF_DAY, hourOfDay); mDate.set(Calendar.MINUTE, minute); + //将视图中的各选项设置为系统当前时间 updateTitle(mDate.getTimeInMillis()); } }); mDate.setTimeInMillis(date); + //得到系统时间 mDate.set(Calendar.SECOND, 0); + //将秒数设置为0 mDateTimePicker.setCurrentDate(mDate.getTimeInMillis()); setButton(context.getString(R.string.datetime_dialog_ok), this); setButton2(context.getString(R.string.datetime_dialog_cancel), (OnClickListener)null); + //设置按钮 set24HourView(DateFormat.is24HourFormat(this.getContext())); + //时间标准化打印 updateTitle(mDate.getTimeInMillis()); } @@ -70,21 +66,22 @@ public class DateTimePickerDialog extends AlertDialog implements OnClickListener public void setOnDateTimeSetListener(OnDateTimeSetListener callBack) { mOnDateTimeSetListener = callBack; - } + }//将时间日期滚动选择控件实例化 private void updateTitle(long date) { int flag = - DateUtils.FORMAT_SHOW_YEAR | - DateUtils.FORMAT_SHOW_DATE | - DateUtils.FORMAT_SHOW_TIME; + DateUtils.FORMAT_SHOW_YEAR | + DateUtils.FORMAT_SHOW_DATE | + DateUtils.FORMAT_SHOW_TIME; flag |= mIs24HourView ? DateUtils.FORMAT_24HOUR : DateUtils.FORMAT_24HOUR; setTitle(DateUtils.formatDateTime(this.getContext(), date, flag)); - } + }//android开发中常见日期管理工具类(API)——DateUtils:按照上下午显示时间 public void onClick(DialogInterface arg0, int arg1) { if (mOnDateTimeSetListener != null) { mOnDateTimeSetListener.OnDateTimeSet(this, mDate.getTimeInMillis()); } - } + }//第一个参数arg0是接收到点击事件的对话框 + //第二个参数arg1是该对话框上的按钮 } \ No newline at end of file diff --git a/src/main/java/net/micode/notes/ui/DropdownMenu.java b/src/main/java/net/micode/notes/ui/DropdownMenu.java index 613dc74..c831a9b 100644 --- a/src/main/java/net/micode/notes/ui/DropdownMenu.java +++ b/src/main/java/net/micode/notes/ui/DropdownMenu.java @@ -1,19 +1,3 @@ -/* - * 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.content.Context; @@ -30,14 +14,18 @@ import net.micode.notes.R; public class DropdownMenu { private Button mButton; private PopupMenu mPopupMenu; + //声明一个下拉菜单 private Menu mMenu; public DropdownMenu(Context context, Button button, int menuId) { mButton = button; mButton.setBackgroundResource(R.drawable.dropdown_icon); + //设置这个view的背景 mPopupMenu = new PopupMenu(context, mButton); mMenu = mPopupMenu.getMenu(); mPopupMenu.getMenuInflater().inflate(menuId, mMenu); + //MenuInflater是用来实例化Menu目录下的Menu布局文件 + //根据ID来确认menu的内容选项 mButton.setOnClickListener(new OnClickListener() { public void onClick(View v) { mPopupMenu.show(); @@ -48,14 +36,14 @@ public class DropdownMenu { public void setOnDropdownMenuItemClickListener(OnMenuItemClickListener listener) { if (mPopupMenu != null) { mPopupMenu.setOnMenuItemClickListener(listener); - } + }//设置菜单的监听 } public MenuItem findItem(int id) { return mMenu.findItem(id); - } + }//对于菜单选项的初始化,根据索引搜索菜单需要的选项 public void setTitle(CharSequence title) { mButton.setText(title); - } -} + }//布局文件,设置标题 +} \ No newline at end of file diff --git a/src/main/java/net/micode/notes/ui/FoldersListAdapter.java b/src/main/java/net/micode/notes/ui/FoldersListAdapter.java index 96b77da..b6867fb 100644 --- a/src/main/java/net/micode/notes/ui/FoldersListAdapter.java +++ b/src/main/java/net/micode/notes/ui/FoldersListAdapter.java @@ -1,19 +1,3 @@ -/* - * 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.content.Context; @@ -30,10 +14,14 @@ import net.micode.notes.data.Notes.NoteColumns; public class FoldersListAdapter extends CursorAdapter { + //CursorAdapter是Cursor和ListView的接口 + //FoldersListAdapter继承了CursorAdapter的类 + //主要作用是便签数据库和用户的交互 + //这里就是用folder(文件夹)的形式展现给用户 public static final String [] PROJECTION = { - NoteColumns.ID, - NoteColumns.SNIPPET - }; + NoteColumns.ID, + NoteColumns.SNIPPET + };//调用数据库中便签的ID和片段 public static final int ID_COLUMN = 0; public static final int NAME_COLUMN = 1; @@ -41,12 +29,13 @@ public class FoldersListAdapter extends CursorAdapter { public FoldersListAdapter(Context context, Cursor c) { super(context, c); // TODO Auto-generated constructor stub - } + }//数据库操作 @Override public View newView(Context context, Cursor cursor, ViewGroup parent) { + //ViewGroup是容器 return new FolderListItem(context); - } + }//创建一个文件夹,对于各文件夹中子标签的初始化 @Override public void bindView(View view, Context context, Cursor cursor) { @@ -55,20 +44,22 @@ public class FoldersListAdapter extends CursorAdapter { .getString(R.string.menu_move_parent_folder) : cursor.getString(NAME_COLUMN); ((FolderListItem) view).bind(folderName); } - } + }//将各个布局文件绑定起来 public String getFolderName(Context context, int position) { Cursor cursor = (Cursor) getItem(position); return (cursor.getLong(ID_COLUMN) == Notes.ID_ROOT_FOLDER) ? context .getString(R.string.menu_move_parent_folder) : cursor.getString(NAME_COLUMN); - } + }//根据数据库中标签的ID得到标签的各项内容 private class FolderListItem extends LinearLayout { private TextView mName; public FolderListItem(Context context) { super(context); + //操作数据库 inflate(context, R.layout.folder_list_item, this); + //根据布局文件的名字等信息将其找出来 mName = (TextView) findViewById(R.id.tv_folder_name); } @@ -77,4 +68,4 @@ public class FoldersListAdapter extends CursorAdapter { } } -} +} \ No newline at end of file diff --git a/src/main/java/net/micode/notes/ui/NoteEditText.java b/src/main/java/net/micode/notes/ui/NoteEditText.java index 2afe2a8..8f5b468 100644 --- a/src/main/java/net/micode/notes/ui/NoteEditText.java +++ b/src/main/java/net/micode/notes/ui/NoteEditText.java @@ -37,15 +37,21 @@ import net.micode.notes.R; import java.util.HashMap; import java.util.Map; +//类:便签编辑文本类,继承了Android控件EditText public class NoteEditText extends EditText { + //语句:常量标识 private static final String TAG = "NoteEditText"; + //语句:声明整型变量,文本索引 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:" ; + //语句块:设置映射,将文本内容(电话、网址、邮件)做链接处理 private static final Map sSchemaActionResMap = new HashMap(); static { sSchemaActionResMap.put(SCHEME_TEL, R.string.note_link_tel); @@ -55,50 +61,60 @@ public class NoteEditText extends EditText { /** * Call by the {@link NoteEditActivity} to delete or add edit text + * 接口:该接口用于实现对TextView组件中的文字信息进行修改 */ public interface OnTextViewChangeListener { /** * Delete current edit text when {@link KeyEvent#KEYCODE_DEL} happens * and the text is null + * 方法:当delete键按下时删除当前编辑的文字块 */ void onEditTextDelete(int index, String text); /** * Add edit text after current edit text when {@link KeyEvent#KEYCODE_ENTER} * happen + * 方法:当enter键按下时添加一个文字编辑块 */ void onEditTextEnter(int index, String text); /** * Hide or show item option when text change + * 方法:当文字发生变化时隐藏或者显示设置 */ void onTextChange(int index, boolean hasText); } + //语句:声明文本视图变化监听器 private OnTextViewChangeListener mOnTextViewChangeListener; + //方法:构造方法,实例化NoteEditText public NoteEditText(Context context) { super(context, null); mIndex = 0; } + //方法:设置索引号 public void setIndex(int index) { mIndex = index; } + //方法:设置文本视图变化监听器 public void setOnTextViewChangeListener(OnTextViewChangeListener listener) { mOnTextViewChangeListener = listener; } + //方法:构造方法,是由参数集(文本编辑风格)实例化NoteEditText public NoteEditText(Context context, AttributeSet attrs) { super(context, attrs, android.R.attr.editTextStyle); } - + //方法:构造方法,是由参数集(文本编辑风格、定义风格)实例化NoteEditText 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()) { @@ -111,25 +127,38 @@ public class NoteEditText extends EditText { 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); } + /** + * 方法:监听键盘按键按下 + * @param keyCode 键盘按键的编码 + * @param event 按键事件 + * @return boolean + */ @Override public boolean onKeyDown(int keyCode, KeyEvent event) { switch (keyCode) { + //语句块:按下回车键 case KeyEvent.KEYCODE_ENTER: + //语句块:如果文本视图没有变化 if (mOnTextViewChangeListener != null) { return false; } break; + //语句块:按下删除键 case KeyEvent.KEYCODE_DEL: + //语句:获取删除文本的开始位置 mSelectionStartBeforeDelete = getSelectionStart(); break; default: @@ -138,26 +167,45 @@ public class NoteEditText extends EditText { return super.onKeyDown(keyCode, event); } + + /** + * 方法:监听按键抬起 + * @param keyCode + * @param event + * @return + */ @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()); return true; } } else { + //语句:报告文本视图变化监听器没有设置 Log.d(TAG, "OnTextViewChangeListener was not seted"); } break; + //语句块:抬起回车键 case KeyEvent.KEYCODE_ENTER: + //语句块:如果文本视图发生变化 if (mOnTextViewChangeListener != null) { + //语句:获取选择区域的起点位置 int selectionStart = getSelectionStart(); + //语句:获取选择区域后面的文本信息 String text = getText().subSequence(selectionStart, length()).toString(); + //语句:实现文本换行的功能 setText(getText().subSequence(0, selectionStart)); + //语句:将选择区域内的文字移到下一行 mOnTextViewChangeListener.onEditTextEnter(mIndex + 1, text); } else { + //语句:报告文本视图变化监听器没有设置 Log.d(TAG, "OnTextViewChangeListener was not seted"); } break; @@ -167,9 +215,17 @@ public class NoteEditText extends EditText { return super.onKeyUp(keyCode, event); } + /** + * 处理当前视图下的焦点改变事件 + * @param focused 代表获得或失去焦点 + * @param direction + * @param previouslyFocusedRect 上一个访问的焦点区域 + */ @Override protected void onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect) { + //语句块:如果文本视图发生变化 if (mOnTextViewChangeListener != null) { + //语句块:当焦点存在或者当前文本不为空时,监听文本的变化 if (!focused && TextUtils.isEmpty(getText())) { mOnTextViewChangeListener.onTextChange(mIndex, false); } else { @@ -179,9 +235,13 @@ 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(); @@ -189,6 +249,7 @@ public class NoteEditText extends EditText { int max = Math.max(selStart, selEnd); final URLSpan[] urls = ((Spanned) getText()).getSpans(min, max, URLSpan.class); + //语句块:针对不同的高亮元素,使用不同的操作进行处理 if (urls.length == 1) { int defaultResId = 0; for(String schema: sSchemaActionResMap.keySet()) { @@ -201,7 +262,7 @@ public class NoteEditText extends EditText { if (defaultResId == 0) { defaultResId = R.string.note_link_other; } - + //语句块:添加环境菜单的点击事件 menu.add(0, 0, 0, defaultResId).setOnMenuItemClickListener( new OnMenuItemClickListener() { public boolean onMenuItemClick(MenuItem item) {