Compare commits

...

42 Commits

Author SHA1 Message Date
STRIV1 155d0f59db 1
2 years ago
prmw2qx5j 5a9b11dbf1 1
2 years ago
brook 7a6e77b5af 1
2 years ago
prmw2qx5j 46519fc572 1
2 years ago
pfuxnwlgc 4e1feafae0 Merge pull request '精读' (#10) from develop into Master
2 years ago
Ryuki 7335568c5d s
2 years ago
Ryuki ecaabdc260 z
2 years ago
pfuxnwlgc 0f091d4f41 Merge pull request 'ui包新增类' (#9) from develop into main
2 years ago
prmw2qx5j 6d7b66f39f Delete 'doc/~$模板-开源软件泛读、标注和维护报告文档.docx'
2 years ago
prmw2qx5j d01a4fb86a 质量分报告
2 years ago
Ryuki 9cc6b3e288 新创建的类
2 years ago
brook c5d457e679 1
2 years ago
Ryuki 099628c89a AndroidManifest添加
2 years ago
Ryuki 77a0074490 密码部分功能
2 years ago
pfuxnwlgc fc12ea5e31 Merge pull request 'ui包部分精读' (#7) from develop into main
2 years ago
Ryuki 2ae54b9a3c 精读
2 years ago
Ryuki 778390b68e 精读
2 years ago
Ryuki 0d3f85a5e7 AlarmInitReceiver 精读
2 years ago
Ryuki 597d45355d AlarmAlertActivity 精读
2 years ago
Ryuki ebf907f8ef NoteEditText完善
2 years ago
pfuxnwlgc 166444c13a Merge pull request 'NoteEditText 精读完毕' (#6) from develop into main
2 years ago
Ryuki fb06a1fe54 NoteEditText精读
2 years ago
Ryuki 781d41f9db a little edit
2 years ago
pfuxnwlgc c01d839827 Merge pull request 'NoteEditActivity 类 精读完毕' (#5) from develop into main
2 years ago
Ryuki 48075b7c34 NoteEditActivity精读完毕
2 years ago
pfuxnwlgc eca2e81161 Merge pull request 'NoteEditActivity精读' (#4) from develop into main
2 years ago
Ryuki 0c371247d5 NoteEditActivity精读
2 years ago
Ryuki 6197e8ce68 Merge branch 'develop' of https://bdgit.educoder.net/pfuxnwlgc/git-test into develop
2 years ago
Ryuki d8a282d65d NoteEditActivity精读
2 years ago
prmw2qx5j 4ce50a9387 Merge pull request 'gtask中data' (#3) from xia_branch into main
2 years ago
brook 60a672a037 modified
2 years ago
brook 04a9cdd10b 课件
2 years ago
brook 01844c955f Merge branch 'develop' of https://bdgit.educoder.net/pfuxnwlgc/git-test into xia_branch
2 years ago
Ryuki 0dec88e9e3 delete
2 years ago
Ryuki 63de394f4d delete
2 years ago
brook dc1b1e9221 Merge branch 'main' of https://bdgit.educoder.net/pfuxnwlgc/git-test into xia_branch
2 years ago
Ryuki 8a2497437a doc
2 years ago
brook 18e40d5795 1
2 years ago
Ryuki a3f1bbced4 ui
2 years ago
brook b1ed93660a 1
2 years ago
brook c9a46d7fa7 1
2 years ago
brook d025c48105 1
2 years ago

Binary file not shown.

@ -0,0 +1,194 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- 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.
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="net.micode.notes"
android:versionCode="1"
android:versionName="0.1" >
<uses-sdk android:minSdkVersion="14" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="com.android.launcher.permission.INSTALL_SHORTCUT" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.MANAGE_ACCOUNTS" />
<uses-permission android:name="android.permission.AUTHENTICATE_ACCOUNTS" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.USE_CREDENTIALS" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<application
android:icon="@drawable/icon_app"
android:label="@string/app_name"
android:requestLegacyExternalStorage="true">
<activity
android:name=".ui.NotesListActivity"
android:configChanges="keyboardHidden|orientation|screenSize"
android:label="@string/app_name"
android:launchMode="singleTop"
android:theme="@style/NoteTheme"
android:uiOptions="splitActionBarWhenNarrow"
android:windowSoftInputMode="adjustPan" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".ui.NoteEditActivity"
android:configChanges="keyboardHidden|orientation|screenSize"
android:launchMode="singleTop"
android:theme="@style/NoteTheme" >
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="vnd.android.cursor.item/text_note" />
<data android:mimeType="vnd.android.cursor.item/call_note" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.INSERT_OR_EDIT" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="vnd.android.cursor.item/text_note" />
<data android:mimeType="vnd.android.cursor.item/call_note" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.SEARCH" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
<meta-data
android:name="android.app.searchable"
android:resource="@xml/searchable" />
</activity>
<provider
android:name="net.micode.notes.data.NotesProvider"
android:authorities="micode_notes"
android:multiprocess="true" />
<receiver
android:name=".widget.NoteWidgetProvider_2x"
android:label="@string/app_widget2x2" >
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
<action android:name="android.appwidget.action.APPWIDGET_DELETED" />
<action android:name="android.intent.action.PRIVACY_MODE_CHANGED" />
</intent-filter>
<meta-data
android:name="android.appwidget.provider"
android:resource="@xml/widget_2x_info" />
</receiver>
<receiver
android:name=".widget.NoteWidgetProvider_4x"
android:label="@string/app_widget4x4" >
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
<action android:name="android.appwidget.action.APPWIDGET_DELETED" />
<action android:name="android.intent.action.PRIVACY_MODE_CHANGED" />
</intent-filter>
<meta-data
android:name="android.appwidget.provider"
android:resource="@xml/widget_4x_info" />
</receiver>
<receiver android:name=".ui.AlarmInitReceiver" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
<receiver
android:name="net.micode.notes.ui.AlarmReceiver"
android:process=":remote" >
</receiver>
<activity
android:name=".ui.AlarmAlertActivity"
android:label="@string/app_name"
android:launchMode="singleInstance"
android:theme="@android:style/Theme.Holo.Wallpaper.NoTitleBar" >
</activity>
<activity
android:name="net.micode.notes.ui.NotesPreferenceActivity"
android:label="@string/preferences_title"
android:launchMode="singleTop"
android:theme="@android:style/Theme.Holo.Light" >
</activity>
<activity
android:name=".ui.LoginActivity"
android:configChanges="keyboardHidden|orientation|screenSize"
android:label="@string/app_name"
android:launchMode="singleTop"
android:theme="@style/NoteTheme"
android:windowSoftInputMode="adjustPan" >
<!--android:uiOptions="splitActionBarWhenNarrow"-->
<!--<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>-->
</activity>
<activity
android:name=".ui.ChangingPassword"
android:configChanges="keyboardHidden|orientation|screenSize"
android:label="@string/app_name"
android:launchMode="singleTop"
android:theme="@style/NoteTheme"
android:windowSoftInputMode="adjustPan" >
</activity>
<activity
android:name=".ui.SettingPassword"
android:configChanges="keyboardHidden|orientation|screenSize"
android:label="@string/app_name"
android:launchMode="singleTop"
android:theme="@style/NoteTheme"
android:windowSoftInputMode="adjustPan" >
</activity>
<activity
android:name=".ui.DeletingPassword"
android:configChanges="keyboardHidden|orientation|screenSize"
android:label="@string/app_name"
android:launchMode="singleTop"
android:theme="@style/NoteTheme"
android:windowSoftInputMode="adjustPan" >
</activity>
<service
android:name="net.micode.notes.gtask.remote.GTaskSyncService"
android:exported="false" >
</service>
<meta-data
android:name="android.app.default_searchable"
android:value=".ui.NoteEditActivity" />
</application>
</manifest>

@ -26,29 +26,54 @@ import org.json.JSONObject;
public class MetaData extends Task {
/* TAG
* getSimpleName ()
*/
private final static String TAG = MetaData.class.getSimpleName();
private String mRelatedGid = null;
/*
*
* JSONObjectput ()TasksetNotes ()setName ()
*/
public void setMeta(String gid, JSONObject metaInfo) {
try {
//对函数块进行注释
metaInfo.put(GTaskStringUtils.META_HEAD_GTASK_ID, gid);
/*
* metaInfojsonobject
*/
} catch (JSONException e) {
Log.e(TAG, "failed to put related gid");
/*
*
*/
}
setNotes(metaInfo.toString());
setName(GTaskStringUtils.META_NOTE_NAME);
}
/*
* Gid
*/
public String getRelatedGid() {
return mRelatedGid;
}
/*
*
*/
@Override
public boolean isWorthSaving() {
return getNotes() != null;
}
/*
* 使json
* TasksetContentByRemoteJSON ()
*
*/
@Override
public void setContentByRemoteJSON(JSONObject js) {
super.setContentByRemoteJSON(js);
@ -58,6 +83,9 @@ public class MetaData extends Task {
mRelatedGid = metaInfo.getString(GTaskStringUtils.META_HEAD_GTASK_ID);
} catch (JSONException e) {
Log.w(TAG, "failed to get related gid");
/*
*
*/
mRelatedGid = null;
}
}
@ -69,14 +97,33 @@ public class MetaData extends Task {
throw new IllegalAccessError("MetaData:setContentByLocalJSON should not be called");
}
/*
* json
*/
@Override
public JSONObject getLocalJSONFromContent() {
throw new IllegalAccessError("MetaData:getLocalJSONFromContent should not be called");
}
/*
*
*/
}
/*
*
*/
@Override
public int getSyncAction(Cursor c) {
throw new IllegalAccessError("MetaData:getSyncAction should not be called");
}
/*
*
*/
}

@ -20,32 +20,38 @@ import android.database.Cursor;
import org.json.JSONObject;
/*
*
* abstract
*/
public abstract class Node {
public static final int SYNC_ACTION_NONE = 0;
//定义了各种用于表征同步状态的常量
public static final int SYNC_ACTION_NONE = 0;// 本地和云端都无可更新内容(即本地和云端内容一致)
public static final int SYNC_ACTION_ADD_REMOTE = 1;
public static final int SYNC_ACTION_ADD_REMOTE = 1;// 需要在远程云端增加内容
public static final int SYNC_ACTION_ADD_LOCAL = 2;
public static final int SYNC_ACTION_ADD_LOCAL = 2;// 需要在本地增加内容
public static final int SYNC_ACTION_DEL_REMOTE = 3;
public static final int SYNC_ACTION_DEL_REMOTE = 3;// 需要在远程云端删除内容
public static final int SYNC_ACTION_DEL_LOCAL = 4;
public static final int SYNC_ACTION_DEL_LOCAL = 4;// 需要在本地删除内容
public static final int SYNC_ACTION_UPDATE_REMOTE = 5;
public static final int SYNC_ACTION_UPDATE_REMOTE = 5;// 需要将本地内容更新到远程云端
public static final int SYNC_ACTION_UPDATE_LOCAL = 6;
public static final int SYNC_ACTION_UPDATE_LOCAL = 6;// 需要将远程云端内容更新到本地
public static final int SYNC_ACTION_UPDATE_CONFLICT = 7;
public static final int SYNC_ACTION_UPDATE_CONFLICT = 7;// 同步出现冲突
public static final int SYNC_ACTION_ERROR = 8;
public static final int SYNC_ACTION_ERROR = 8;// 同步出现错误
private String mGid;
private String mName;
private long mLastModified;
private long mLastModified;//记录最后一次修改时间
private boolean mDeleted;
private boolean mDeleted;//表征是否被删除
public Node() {
mGid = null;

@ -14,8 +14,21 @@
* limitations under the License.
*/
/*
* Description便sqlnotedatanote
* SqlData
*/
package net.micode.notes.gtask.data;
/*
*
*
*
* Made By CuiCan
*/
import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.ContentValues;
@ -36,15 +49,30 @@ import org.json.JSONObject;
public class SqlData {
/*
* TAG
* getSimpleName ()
*/
private static final String TAG = SqlData.class.getSimpleName();
private static final int INVALID_ID = -99999;
private static final int INVALID_ID = -99999;//为mDataId置初始值-99999
/*
* NotesDataColumn
*/
// 集合了interface DataColumns中所有SF常量
public static final String[] PROJECTION_DATA = new String[] {
DataColumns.ID, DataColumns.MIME_TYPE, DataColumns.CONTENT, DataColumns.DATA1,
DataColumns.DATA3
};
//以下变量作为sql表中5列的编号
public static final int DATA_ID_COLUMN = 0;
public static final int DATA_MIME_TYPE_COLUMN = 1;
@ -56,7 +84,7 @@ public class SqlData {
public static final int DATA_CONTENT_DATA_3_COLUMN = 4;
private ContentResolver mContentResolver;
//判断是否直接用Content生成是为true否则为false
private boolean mIsCreate;
private long mDataId;
@ -71,6 +99,13 @@ public class SqlData {
private ContentValues mDiffDataValues;
/*
*
* mContentResolverContentProvider
* mIsCreate
*/
public SqlData(Context context) {
mContentResolver = context.getContentResolver();
mIsCreate = true;
@ -82,6 +117,13 @@ public class SqlData {
mDiffDataValues = new ContentValues();
}
/*
*
* mContentResolverContentProvider
* mIsCreate
*/
public SqlData(Context context, Cursor c) {
mContentResolver = context.getContentResolver();
mIsCreate = false;
@ -89,6 +131,12 @@ public class SqlData {
mDiffDataValues = new ContentValues();
}
/*
*
*
*/
private void loadFromCursor(Cursor c) {
mDataId = c.getLong(DATA_ID_COLUMN);
mDataMimeType = c.getString(DATA_MIME_TYPE_COLUMN);
@ -97,7 +145,13 @@ public class SqlData {
mDataContentData3 = c.getString(DATA_CONTENT_DATA_3_COLUMN);
}
/*
*
*/
public void setContent(JSONObject js) throws JSONException {
//如果传入的JSONObject对象中有DataColumns.ID这一项则设置否则设为INVALID_ID
long dataId = js.has(DataColumns.ID) ? js.getLong(DataColumns.ID) : INVALID_ID;
if (mIsCreate || mDataId != dataId) {
mDiffDataValues.put(DataColumns.ID, dataId);
@ -130,11 +184,18 @@ public class SqlData {
mDataContentData3 = dataContentData3;
}
/*
*
*
*/
public JSONObject getContent() throws JSONException {
if (mIsCreate) {
Log.e(TAG, "it seems that we haven't created this in database yet");
return null;
}
//创建JSONObject对象。并将相关数据放入其中并返回。
JSONObject js = new JSONObject();
js.put(DataColumns.ID, mDataId);
js.put(DataColumns.MIME_TYPE, mDataMimeType);
@ -143,7 +204,9 @@ public class SqlData {
js.put(DataColumns.DATA3, mDataContentData3);
return js;
}
/*
* commit
*/
public void commit(long noteId, boolean validateVersion, long version) {
if (mIsCreate) {
@ -183,6 +246,12 @@ public class SqlData {
mIsCreate = false;
}
/*
* id
*
*/
public long getId() {
return mDataId;
}

@ -13,7 +13,10 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* Description便sqldatanotedata
* SqlDataSqlNote
*/
package net.micode.notes.gtask.data;
import android.appwidget.AppWidgetManager;
@ -37,12 +40,21 @@ import org.json.JSONObject;
import java.util.ArrayList;
/*
*
*
*/
public class SqlNote {
private static final String TAG = SqlNote.class.getSimpleName();
/*
* TAG
* getSimpleName ()
*/
private static final int INVALID_ID = -99999;
// 集合了interface NoteColumns中所有SF常量17个
public static final String[] PROJECTION_NOTE = new String[] {
NoteColumns.ID, NoteColumns.ALERTED_DATE, NoteColumns.BG_COLOR_ID,
NoteColumns.CREATED_DATE, NoteColumns.HAS_ATTACHMENT, NoteColumns.MODIFIED_DATE,
@ -51,7 +63,7 @@ public class SqlNote {
NoteColumns.LOCAL_MODIFIED, NoteColumns.ORIGIN_PARENT_ID, NoteColumns.GTASK_ID,
NoteColumns.VERSION
};
//以下设置17个列的编号
public static final int ID_COLUMN = 0;
public static final int ALERTED_DATE_COLUMN = 1;
@ -85,7 +97,7 @@ public class SqlNote {
public static final int GTASK_ID_COLUMN = 15;
public static final int VERSION_COLUMN = 16;
//以下定义了17个内部的变量其中12个可以由content中获得5个需要初始化为0或者new
private Context mContext;
private ContentResolver mContentResolver;
@ -121,7 +133,12 @@ public class SqlNote {
private ContentValues mDiffNoteValues;
private ArrayList<SqlData> mDataList;
/*
*
* mIsCreate
*/
//构造函数只有context对所有的变量进行初始化
public SqlNote(Context context) {
mContext = context;
mContentResolver = context.getContentResolver();
@ -129,9 +146,9 @@ public class SqlNote {
mId = INVALID_ID;
mAlertDate = 0;
mBgColorId = ResourceParser.getDefaultBgId(context);
mCreatedDate = System.currentTimeMillis();
mCreatedDate = System.currentTimeMillis();//调用系统函数获得创建时间
mHasAttachment = 0;
mModifiedDate = System.currentTimeMillis();
mModifiedDate = System.currentTimeMillis();//最后一次修改时间初始化为创建时间
mParentId = 0;
mSnippet = "";
mType = Notes.TYPE_NOTE;
@ -142,6 +159,12 @@ public class SqlNote {
mDiffNoteValues = new ContentValues();
mDataList = new ArrayList<SqlData>();
}
/*
*
* mIsCreate
*/
//构造函数有context和一个数据库的cursor多数变量通过cursor指向的一条记录直接进行初始化
public SqlNote(Context context, Cursor c) {
mContext = context;
@ -153,7 +176,10 @@ public class SqlNote {
loadDataContent();
mDiffNoteValues = new ContentValues();
}
/*
*
* mIsCreate
*/
public SqlNote(Context context, long id) {
mContext = context;
mContentResolver = context.getContentResolver();
@ -173,9 +199,10 @@ public class SqlNote {
new String[] {
String.valueOf(id)
}, null);
if (c != null) {
if (c != null) {//通过id获得对应的ContentResolver中的cursor
c.moveToNext();
loadFromCursor(c);
loadFromCursor(c);//然后加载数据进行初始化,这样函数
//SqlNote(Context context, long id)与SqlNote(Context context, long id)的实现方式基本相同
} else {
Log.w(TAG, "loadFromCursor: cursor = null");
}
@ -184,8 +211,11 @@ public class SqlNote {
c.close();
}
}
/*
*
*/
private void loadFromCursor(Cursor c) {
//直接从一条记录中的获得以下变量的初始值
mId = c.getLong(ID_COLUMN);
mAlertDate = c.getLong(ALERTED_DATE_COLUMN);
mBgColorId = c.getInt(BG_COLOR_ID_COLUMN);
@ -199,7 +229,9 @@ public class SqlNote {
mWidgetType = c.getInt(WIDGET_TYPE_COLUMN);
mVersion = c.getLong(VERSION_COLUMN);
}
/*
* content
* */
private void loadDataContent() {
Cursor c = null;
mDataList.clear();
@ -225,7 +257,8 @@ public class SqlNote {
c.close();
}
}
/*
* content*/
public boolean setContent(JSONObject js) {
try {
JSONObject note = js.getJSONObject(GTaskStringUtils.META_HEAD_NOTE);
@ -359,6 +392,8 @@ public class SqlNote {
return true;
}
/*
* contentnote*/
public JSONObject getContent() {
try {
JSONObject js = new JSONObject();
@ -406,40 +441,49 @@ public class SqlNote {
}
return null;
}
/*
* idid*/
public void setParentId(long id) {
mParentId = id;
mDiffNoteValues.put(NoteColumns.PARENT_ID, id);
}
/*
* idGtaskid*/
public void setGtaskId(String gid) {
mDiffNoteValues.put(NoteColumns.GTASK_ID, gid);
}
/*
* idid*/
public void setSyncId(long syncId) {
mDiffNoteValues.put(NoteColumns.SYNC_ID, syncId);
}
/*
* */
public void resetLocalModified() {
mDiffNoteValues.put(NoteColumns.LOCAL_MODIFIED, 0);
}
/*
* id*/
public long getId() {
return mId;
}
/*
* idid*/
public long getParentId() {
return mParentId;
}
/*
* 便*/
public String getSnippet() {
return mSnippet;
}
/*
* 便*/
public boolean isNoteType() {
return mType == Notes.TYPE_NOTE;
}
/*
* commit*/
public void commit(boolean validateVersion) {
if (mIsCreate) {
if (mId == INVALID_ID && mDiffNoteValues.containsKey(NoteColumns.ID)) {

@ -35,22 +35,22 @@ import org.json.JSONObject;
public class Task extends Node {
private static final String TAG = Task.class.getSimpleName();
private boolean mCompleted;
private boolean mCompleted;//是否完成
private String mNotes;
private JSONObject mMetaInfo;
private JSONObject mMetaInfo;//将在实例中存储数据的类型
private Task mPriorSibling;
private TaskList mParent;
private TaskList mParent;//所在的任务列表的指针
public Task() {
super();
mCompleted = false;
mNotes = null;
mPriorSibling = null;
mParent = null;
mPriorSibling = null;//TaskList中当前Task前面的Task的指针
mParent = null;//当前Task所在的TaskList
mMetaInfo = null;
}

@ -31,11 +31,11 @@ import java.util.ArrayList;
public class TaskList extends Node {
private static final String TAG = TaskList.class.getSimpleName();
private static final String TAG = TaskList.class.getSimpleName();//tag标记
private int mIndex;
private int mIndex;//当前TaskList的指针
private ArrayList<Task> mChildren;
private ArrayList<Task> mChildren;//类中主要的保存数据的单元用来实现一个以Task为元素的ArrayList
public TaskList() {
super();
@ -43,6 +43,7 @@ public class TaskList extends Node {
mIndex = 1;
}
//生成并返回一个包含了一定数据的JSONObject实体
public JSONObject getCreateAction(int actionId) {
JSONObject js = new JSONObject();
@ -74,6 +75,8 @@ public class TaskList extends Node {
return js;
}
//生成并返回一个包含了一定数据的JSONObject实体
public JSONObject getUpdateAction(int actionId) {
JSONObject js = new JSONObject();
@ -216,6 +219,8 @@ public class TaskList extends Node {
return SYNC_ACTION_ERROR;
}
//功能获得TaskList的大小即mChildren的大小
public int getChildTaskCount() {
return mChildren.size();
}
@ -233,7 +238,7 @@ public class TaskList extends Node {
}
return ret;
}
//功能:在当前任务表的指定位置添加新的任务
public boolean addChildTask(Task task, int index) {
if (index < 0 || index > mChildren.size()) {
Log.e(TAG, "add child task: invalid index");
@ -260,6 +265,7 @@ public class TaskList extends Node {
return true;
}
// 功能删除TaskList中的一个Task
public boolean removeChildTask(Task task) {
boolean ret = false;
int index = mChildren.indexOf(task);
@ -281,6 +287,7 @@ public class TaskList extends Node {
return ret;
}
//功能将当前TaskList中含有的某个Task移到index位置
public boolean moveChildTask(Task task, int index) {
if (index < 0 || index >= mChildren.size()) {
@ -298,7 +305,10 @@ public class TaskList extends Node {
return true;
return (removeChildTask(task) && addChildTask(task, index));
}
//利用已实现好的功能完成当下功能;
// 功能按gid寻找Task
public Task findChildTaskByGid(String gid) {
for (int i = 0; i < mChildren.size(); i++) {
Task t = mChildren.get(i);
@ -308,11 +318,13 @@ public class TaskList extends Node {
}
return null;
}
//功能返回指定Task的index
public int getChildTaskIndex(Task task) {
return mChildren.indexOf(task);
}
//功能返回指定index的Task
public Task getChildTaskByIndex(int index) {
if (index < 0 || index >= mChildren.size()) {
Log.e(TAG, "getTaskByIndex: invalid index");
@ -321,6 +333,8 @@ public class TaskList extends Node {
return mChildren.get(index);
}
//功能返回指定index的Task
public Task getChilTaskByGid(String gid) {
for (Task task : mChildren) {
if (task.getGid().equals(gid))

@ -14,14 +14,24 @@
* limitations under the License.
*/
// 支持小米便签运行过程中的运行异常处理
package net.micode.notes.gtask.exception;
public class ActionFailureException extends RuntimeException {
private static final long serialVersionUID = 4425249765923293627L;
/*
* serialVersionUIDjava
* serialVersionUID
*/
public ActionFailureException() {
super();
}
/*
* JAVA使superthis.
* new
*/
public ActionFailureException(String paramString) {
super(paramString);

@ -13,11 +13,20 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* Description便
*/
package net.micode.notes.gtask.exception;
public class NetworkFailureException extends Exception {
private static final long serialVersionUID = 2107610287180234136L;
// serialVersionUID作用是序列化时保持版本的兼容性即在版本升级时反序列化仍保持对象的唯一性。
/*
* JAVA使superthis.
* new
*/
public NetworkFailureException() {
super();

@ -28,6 +28,13 @@ import net.micode.notes.R;
import net.micode.notes.ui.NotesListActivity;
import net.micode.notes.ui.NotesPreferenceActivity;
/*GTask
*
* private void showNotification(int tickerId, String content)
* protected Integer doInBackground(Void... unused) 线
* protected void onProgressUpdate(String... progress) 使 线
* protected void onPostExecute(Integer result) Handler UI使doInBackground UI
*/
public class GTaskASyncTask extends AsyncTask<Void, String, Integer> {
@ -57,7 +64,7 @@ public class GTaskASyncTask extends AsyncTask<Void, String, Integer> {
mTaskManager.cancelSync();
}
public void publishProgess(String message) {
public void publishProgess(String message) {// 发布进度单位系统将会调用onProgressUpdate()方法更新这些值
publishProgress(new String[] {
message
});
@ -66,30 +73,29 @@ public class GTaskASyncTask extends AsyncTask<Void, String, Integer> {
private void showNotification(int tickerId, String content) {
Notification notification = new Notification(R.drawable.notification, mContext
.getString(tickerId), System.currentTimeMillis());
notification.defaults = Notification.DEFAULT_LIGHTS;
notification.defaults = Notification.DEFAULT_LIGHTS;// 调用系统自带灯光
notification.flags = Notification.FLAG_AUTO_CANCEL;
PendingIntent pendingIntent;
if (tickerId != R.string.ticker_success) {
pendingIntent = PendingIntent.getActivity(mContext, 0, new Intent(mContext,
NotesPreferenceActivity.class), 0);
NotesPreferenceActivity.class), 0);//如果同步不成功那么从系统取得一个用于启动一个NotesPreferenceActivity的PendingIntent对象
} else {
pendingIntent = PendingIntent.getActivity(mContext, 0, new Intent(mContext,
NotesListActivity.class), 0);
NotesListActivity.class), 0);//如果同步成功那么从系统取得一个用于启动一个NotesListActivity的PendingIntent对象
}
notification.setLatestEventInfo(mContext, mContext.getString(R.string.app_name), content,
pendingIntent);
mNotifiManager.notify(GTASK_SYNC_NOTIFICATION_ID, notification);
// notification.setLatestEventInfo(mContext, mContext.getString(R.string.app_name), content,
// pendingIntent);
mNotifiManager.notify(GTASK_SYNC_NOTIFICATION_ID, notification);//通过NotificationManager对象的notify方法来执行一个notification的消息
}
@Override
// @Override
protected Integer doInBackground(Void... unused) {
publishProgess(mContext.getString(R.string.sync_progress_login, NotesPreferenceActivity
.getSyncAccountName(mContext)));
return mTaskManager.sync(mContext, this);
return mTaskManager.sync(mContext, this); //进行后台同步具体操作
}
@Override
// @Override
protected void onProgressUpdate(String... progress) {
showNotification(R.string.ticker_syncing, progress[0]);
if (mContext instanceof GTaskSyncService) {
@ -97,8 +103,8 @@ public class GTaskASyncTask extends AsyncTask<Void, String, Integer> {
}
}
@Override
protected void onPostExecute(Integer result) {
//@Override
protected void onPostExecute(Integer result) {//用于在执行完后台任务后更新UI,显示结果
if (result == GTaskManager.STATE_SUCCESS) {
showNotification(R.string.ticker_success, mContext.getString(
R.string.success_sync_account, mTaskManager.getSyncAccount()));

@ -60,7 +60,10 @@ import java.util.zip.GZIPInputStream;
import java.util.zip.Inflater;
import java.util.zip.InflaterInputStream;
/*
* GTASKGTASK
* 使accountManager JSONObject HttpParams authToken Gid
*/
public class GTaskClient {
private static final String TAG = GTaskClient.class.getSimpleName();
@ -102,6 +105,10 @@ public class GTaskClient {
mUpdateArray = null;
}
/*
* 使 getInstance()
* mInstance
*/
public static synchronized GTaskClient getInstance() {
if (mInstance == null) {
mInstance = new GTaskClient();

@ -87,9 +87,9 @@ public class GTaskManager {
private HashMap<Long, String> mNidToGid;
private GTaskManager() {
mSyncing = false;
mCancelled = false;
private GTaskManager() { //对象初始化函数
mSyncing = false; //正在同步,flase代表未执行
mCancelled = false; //全局标识flase代表可以执行
mGTaskListHashMap = new HashMap<String, TaskList>();
mGTaskHashMap = new HashMap<String, Node>();
mMetaHashMap = new HashMap<String, MetaData>();
@ -113,7 +113,7 @@ public class GTaskManager {
public int sync(Context context, GTaskASyncTask asyncTask) {
if (mSyncing) {
Log.d(TAG, "Sync is in progress");
Log.d(TAG, "Sync is in progress");//创建日志文件调试信息debug
return STATE_SYNC_IN_PROGRESS;
}
mContext = context;
@ -128,7 +128,7 @@ public class GTaskManager {
mNidToGid.clear();
try {
GTaskClient client = GTaskClient.getInstance();
GTaskClient client = GTaskClient.getInstance();//getInstance即为创建一个实例,client--客户机
client.resetUpdateArray();
// login google task
@ -140,7 +140,7 @@ public class GTaskManager {
// get the task list from google
asyncTask.publishProgess(mContext.getString(R.string.sync_progress_init_list));
initGTaskList();
initGTaskList(); //获取Google上的JSONtasklist转为本地TaskList
// do content sync work
asyncTask.publishProgess(mContext.getString(R.string.sync_progress_syncing));
@ -168,12 +168,17 @@ public class GTaskManager {
return mCancelled ? STATE_SYNC_CANCELLED : STATE_SUCCESS;
}
/*
*GtaskListGoogleJSONtasklistTaskList
*mMetaListmGTaskListHashMapmGTaskHashMap
*/
private void initGTaskList() throws NetworkFailureException {
if (mCancelled)
return;
GTaskClient client = GTaskClient.getInstance();
try {
JSONArray jsTaskLists = client.getTaskLists();
JSONArray jsTaskLists = client.getTaskLists(); //getInstance即为创建一个实例client应指远端客户机
// init meta list first
mMetaList = null;
@ -247,6 +252,8 @@ public class GTaskManager {
}
}
//功能:本地内容同步操作
private void syncContent() throws NetworkFailureException {
int syncType;
Cursor c = null;

@ -42,6 +42,8 @@ public class GTaskSyncService extends Service {
private static String mSyncProgress = "";
////开始一个同步的工作
private void startSync() {
if (mSyncTask == null) {
mSyncTask = new GTaskASyncTask(this, new GTaskASyncTask.OnCompleteListener() {
@ -65,13 +67,14 @@ public class GTaskSyncService extends Service {
@Override
public void onCreate() {
mSyncTask = null;
}
}///初始化一个service
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Bundle bundle = intent.getExtras();
if (bundle != null && bundle.containsKey(ACTION_STRING_NAME)) {
switch (bundle.getInt(ACTION_STRING_NAME, ACTION_INVALID)) {
//两种情况,开始同步或者取消同步
case ACTION_START_SYNC:
startSync();
break;
@ -81,7 +84,7 @@ public class GTaskSyncService extends Service {
default:
break;
}
return START_STICKY;
return START_STICKY;//等待新的intent来是这个service继续运行
}
return super.onStartCommand(intent, flags, startId);
}

@ -1,4 +1,4 @@
/*
/*su
* Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net)
*
* Licensed under the Apache License, Version 2.0 (the "License");

@ -43,8 +43,8 @@ import java.io.IOException;
public class AlarmAlertActivity extends Activity implements OnClickListener, OnDismissListener {
private long mNoteId; //文本在数据存储中的ID号
private String mSnippet; //闹钟提示时出现的文本片段
private static final int SNIPPET_PREW_MAX_LEN = 60;
MediaPlayer mPlayer;
private static final int SNIPPET_PREW_MAX_LEN = 60; //闹钟提示对话框中的便签片段的最大长度
MediaPlayer mPlayer; //用于播放闹钟音效的MediaPlayer对象
@Override
protected void onCreate(Bundle savedInstanceState) {
@ -52,9 +52,10 @@ public class AlarmAlertActivity extends Activity implements OnClickListener, OnD
//Bundle 类型的数据与 Map类型的数据相似都是以keu-value的形式存储数据的
//on save InstanceState方法是用来保存Activity的状态的
//能从onCreate的参数savedInsanceState中获得状态数据
//不显示窗口标题
requestWindowFeature(Window.FEATURE_NO_TITLE);
//界面显示-无标题
//获取当前窗口的Window实例用于设置标志以在屏幕锁定时显示此Activity
final Window win = getWindow();
win.addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
@ -70,6 +71,7 @@ public class AlarmAlertActivity extends Activity implements OnClickListener, OnD
Intent intent = getIntent();
//从Intent的data中提取闹钟ID(mNoteId)和文本片段(mSnippet)
try {
mNoteId = Long.valueOf(intent.getData().getPathSegments().get(1));
mSnippet = DataUtils.getSnippetById(this.getContentResolver(), mNoteId);
@ -80,6 +82,7 @@ public class AlarmAlertActivity extends Activity implements OnClickListener, OnD
: mSnippet;
//判读标签片段是否达到符合长度
} catch (IllegalArgumentException e) {
//数据不合法,捕获异常并返回
e.printStackTrace();
return;
}
@ -105,22 +108,28 @@ public class AlarmAlertActivity extends Activity implements OnClickListener, OnD
}
}
//判断屏幕是否亮起
private boolean isScreenOn() {
PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
return pm.isScreenOn();
}
//播放默认的闹钟声音
private void playAlarmSound() {
//获取系统默认的闹钟声音URI
Uri url = RingtoneManager.getActualDefaultRingtoneUri(this, RingtoneManager.TYPE_ALARM);
//获取当前系统设置的闹钟流是否受静音模式影响
int silentModeStreams = Settings.System.getInt(getContentResolver(),
Settings.System.MODE_RINGER_STREAMS_AFFECTED, 0);
//如果闹钟声音在当前系统设置中受静音模式影响,则将其设置到相应的音频流
if ((silentModeStreams & (1 << AudioManager.STREAM_ALARM)) != 0) {
mPlayer.setAudioStreamType(silentModeStreams);
} else {
mPlayer.setAudioStreamType(AudioManager.STREAM_ALARM);
}
//尝试设置数据源,准备播放器,设置为循环播放,并开始播放
try {
mPlayer.setDataSource(this, url);
mPlayer.prepare();
@ -137,22 +146,28 @@ public class AlarmAlertActivity extends Activity implements OnClickListener, OnD
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
e.printStackTrace(); //捕捉到异常,输出堆栈跟踪信息并不做进一步处理
}
}
//显示操作对话框,让用户能够选择停止闹钟或查看便签
private void showActionDialog() {
AlertDialog.Builder dialog = new AlertDialog.Builder(this);
//设置对话框标题和消息,并提供一个"确定"按钮
dialog.setTitle(R.string.app_name);
dialog.setMessage(mSnippet);
dialog.setPositiveButton(R.string.notealert_ok, this);
//如果屏幕已经亮起,则提供一个"查看"按钮
if (isScreenOn()) {
dialog.setNegativeButton(R.string.notealert_enter, this);
}
//显示对话框,并设置监听器监听对话框消失事件
dialog.show().setOnDismissListener(this);
}
//当用户点击对话框按钮时调用这个方法
public void onClick(DialogInterface dialog, int which) {
//如果点击了"查看"按钮启动NoteEditActivity来查看并编辑便签
switch (which) {
case DialogInterface.BUTTON_NEGATIVE:
Intent intent = new Intent(this, NoteEditActivity.class);
@ -165,11 +180,13 @@ public class AlarmAlertActivity extends Activity implements OnClickListener, OnD
}
}
//当对话框消失时,停止播放声音并结束此活动
public void onDismiss(DialogInterface dialog) {
stopAlarmSound();
finish();
}
//停止并释放MediaPlayer资源
private void stopAlarmSound() {
if (mPlayer != null) {
mPlayer.stop();

@ -28,38 +28,50 @@ import net.micode.notes.data.Notes;
import net.micode.notes.data.Notes.NoteColumns;
//AlarmInitReceiver 类继承自BroadcastReceiver 广播接收者用于获取系统启动或其他特定事件的通知
public class AlarmInitReceiver extends BroadcastReceiver {
//数据库查询的列名数组只查询ID和提醒日期
private static final String [] PROJECTION = new String [] {
NoteColumns.ID,
NoteColumns.ALERTED_DATE
NoteColumns.ID, //便签的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();
Cursor c = context.getContentResolver().query(Notes.CONTENT_NOTE_URI,
//通过内容解析器查询便签寻找提醒时间大于当前时间且类型为TYPE_NOTE的便签
Cursor c = context.getContentResolver().query(Notes.CONTENT_NOTE_URI, // CONTENT_NOTE_URI是访问便签数据的URI
PROJECTION,
NoteColumns.ALERTED_DATE + ">? AND " + NoteColumns.TYPE + "=" + Notes.TYPE_NOTE,
new String[] { String.valueOf(currentDate) },
null);
//遍历查询出的结果
if (c != null) {
if (c.moveToFirst()) {
if (c.moveToFirst()) { //移动游标到第一条记录
do {
//读取提醒日期时间
long alertDate = c.getLong(COLUMN_ALERTED_DATE);
//创建指向AlarmReceiver的Intent
Intent sender = new Intent(context, AlarmReceiver.class);
sender.setData(ContentUris.withAppendedId(Notes.CONTENT_NOTE_URI, c.getLong(COLUMN_ID)));
//创建一个即将执行的PendingIntent
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, sender, 0);
//获取系统AlarmManager
AlarmManager alermManager = (AlarmManager) context
.getSystemService(Context.ALARM_SERVICE);
//使用AlarmManager设置一个闹钟当系统时间达到提醒日期时触发广播
alermManager.set(AlarmManager.RTC_WAKEUP, alertDate, pendingIntent);
} while (c.moveToNext());
} while (c.moveToNext()); //移动到下一条记录
}
c.close();
c.close(); //关闭游标
}
}
}

@ -20,11 +20,16 @@ import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
//AlarmReceiver 类继承自 BroadcastReceiver 广播接收者用于获取系统启动或其他特定事件的通知
public class AlarmReceiver extends BroadcastReceiver {
//当广播被执行时执行此方法
@Override
public void onReceive(Context context, Intent intent) {
//设置Intent的目标Activity为AlarmAlertActivity
intent.setClass(context, AlarmAlertActivity.class);
//添加FLAG_ACTIVITY_NEW_TASK标志用于启动一个新的任务栈
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
//启动目标ActivityAlarmAlertActivity
context.startActivity(intent);
}
}

@ -0,0 +1,78 @@
package net.micode.notes.ui;
import android.app.Activity;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.view.View;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import net.micode.notes.R;
public class Changepassword extends Activity{
EditText OldPassword;
EditText NewPassword;
EditText AckPassword;
Button Acknowledged;
@Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_change_password);
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE
| WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);
OldPassword=(EditText) findViewById(R.id.old_password);
NewPassword=(EditText) findViewById(R.id.new_password);
AckPassword=(EditText) findViewById(R.id.ack_password);
Acknowledged=(Button)findViewById(R.id.Acknowledged);
Acknowledged.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String old_password = OldPassword.getText().toString();
String new_password = NewPassword.getText().toString();
String ack_password = AckPassword.getText().toString();
SharedPreferences pref = getSharedPreferences("user
management",MODE_PRIVATE);
String login_password = pref.getString("password","");
if(old_password.equals("")==true || new_password.equals("")==true
|| ack_password.equals("")==true) {
Toast.makeText(ChangingPassword.this, "密码不能为空",
Toast.LENGTH_SHORT).show();
}
else if (new_password.equals(ack_password) == false) {
Toast.makeText(ChangingPassword.this, "
", Toast.LENGTH_SHORT).show();
AckPassword.setText("");
}
else if(old_password.equals(login_password) == false){
Toast.makeText(ChangingPassword.this, "
", Toast.LENGTH_SHORT).show();
OldPassword.setText("");
}
else if (new_password.equals(ack_password) == true &&
old_password.equals(login_password) == true){
SharedPreferences.Editor editor=getSharedPreferences("user
management", MODE_PRIVATE).edit();
editor.putString("password",new_password);
editor.apply();
Toast.makeText(ChangingPassword.this, "修改密码成功",
Toast.LENGTH_SHORT).show();
Intent intent=new
Intent(ChangingPassword.this,NotesListActivity.class);
startActivity(intent);
finish();
}
}
});
}
@Override
public void onBackPressed(){
Intent intent=new Intent(ChangingPassword.this,NotesListActivity.class);
startActivity(intent);
finish();
}
}

@ -0,0 +1,71 @@
package net.micode.notes.ui;
import android.app.Activity;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.view.View;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import net.micode.notes.R;
public class ChangingPassword extends Activity{
EditText OldPassword;
EditText NewPassword;
EditText AckPassword;
Button Acknowledged;
@Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_change_password);
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE
| WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);
OldPassword=(EditText) findViewById(R.id.old_password);
NewPassword=(EditText) findViewById(R.id.new_password);
AckPassword=(EditText) findViewById(R.id.ack_password);
Acknowledged=(Button)findViewById(R.id.Acknowledged);
Acknowledged.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String old_password = OldPassword.getText().toString();
String new_password = NewPassword.getText().toString();
String ack_password = AckPassword.getText().toString();
SharedPreferences pref = getSharedPreferences("user management",MODE_PRIVATE);
String login_password = pref.getString("password","");
if(old_password.equals("")==true || new_password.equals("")==true || ack_password.equals("")==true) {
Toast.makeText(ChangingPassword.this, "密码不能为空", Toast.LENGTH_SHORT).show();
}
else if (new_password.equals(ack_password) == false) {
Toast.makeText(ChangingPassword.this, "新建密码与重复密码不匹配,请重新输入密码", Toast.LENGTH_SHORT).show();
AckPassword.setText("");
}
else if(old_password.equals(login_password) == false){
Toast.makeText(ChangingPassword.this, "原有密码错误,请重新输入密码", Toast.LENGTH_SHORT).show();
OldPassword.setText("");
}
else if (new_password.equals(ack_password) == true &&
old_password.equals(login_password) == true){
SharedPreferences.Editor editor=getSharedPreferences("user management", MODE_PRIVATE).edit();
editor.putString("password",new_password);
editor.apply();
Toast.makeText(ChangingPassword.this, "修改密码成功",Toast.LENGTH_SHORT).show();
Intent intent=new
Intent(ChangingPassword.this,NotesListActivity.class);
startActivity(intent);
finish();
}
}
});
}
@Override
public void onBackPressed(){
Intent intent=new Intent(ChangingPassword.this,NotesListActivity.class);
startActivity(intent);
finish();
}
}

@ -28,42 +28,67 @@ import android.view.View;
import android.widget.FrameLayout;
import android.widget.NumberPicker;
//自定义的日期时间选择器控件继承自FrameLayout。
public class DateTimePicker extends FrameLayout {
//默认的启用状态
private static final boolean DEFAULT_ENABLE_STATE = true;
//一天中的小时数(半天和全天)
private static final int HOURS_IN_HALF_DAY = 12;
private static final int HOURS_IN_ALL_DAY = 24;
//一周当中的天数
private static final int DAYS_IN_ALL_WEEK = 7;
//根据一周的天数设置日期选择器(NumberPicker)的最大和最小值
private static final int DATE_SPINNER_MIN_VAL = 0;
private static final int DATE_SPINNER_MAX_VAL = DAYS_IN_ALL_WEEK - 1;
//定义24小时视图中小时选择器的最大和最小值
private static final int HOUR_SPINNER_MIN_VAL_24_HOUR_VIEW = 0;
private static final int HOUR_SPINNER_MAX_VAL_24_HOUR_VIEW = 23;
//定义12小时视图中小时选择器的最大和最小值
private static final int HOUR_SPINNER_MIN_VAL_12_HOUR_VIEW = 1;
private static final int HOUR_SPINNER_MAX_VAL_12_HOUR_VIEW = 12;
//分钟选择器的最大和最小值
private static final int MINUT_SPINNER_MIN_VAL = 0;
private static final int MINUT_SPINNER_MAX_VAL = 59;
//AM/PM 选择器的最大和最小值
private static final int AMPM_SPINNER_MIN_VAL = 0;
private static final int AMPM_SPINNER_MAX_VAL = 1;
//NumberPicker 控件的实例引用
private final NumberPicker mDateSpinner;
private final NumberPicker mHourSpinner;
private final NumberPicker mMinuteSpinner;
private final NumberPicker mAmPmSpinner;
//用于存储和处理日期的Calendar实例
private Calendar mDate;
//日期显示的数据,用于存储一周内每一天的描述
private String[] mDateDisplayValues = new String[DAYS_IN_ALL_WEEK];
//是否为上午的变量
private boolean mIsAm;
//是否为24小时视图的标志变量
private boolean mIs24HourView;
//控件的启用状态
private boolean mIsEnabled = DEFAULT_ENABLE_STATE;
//是否正在初始化的标志变量,避免在初始化过程中触发事件
private boolean mInitialising;
//日期变化监听器接口,用于在日期时间改变时通知用户
private OnDateTimeChangedListener mOnDateTimeChangedListener;
//日期改变监听器
private NumberPicker.OnValueChangeListener mOnDateChangedListener = new NumberPicker.OnValueChangeListener() {
@Override
public void onValueChange(NumberPicker picker, int oldVal, int newVal) {
@ -73,6 +98,7 @@ public class DateTimePicker extends FrameLayout {
}
};
//小时改变监听器
private NumberPicker.OnValueChangeListener mOnHourChangedListener = new NumberPicker.OnValueChangeListener() {
@Override
public void onValueChange(NumberPicker picker, int oldVal, int newVal) {
@ -115,6 +141,7 @@ public class DateTimePicker extends FrameLayout {
}
};
//分钟改变监听器
private NumberPicker.OnValueChangeListener mOnMinuteChangedListener = new NumberPicker.OnValueChangeListener() {
@Override
public void onValueChange(NumberPicker picker, int oldVal, int newVal) {
@ -144,6 +171,7 @@ public class DateTimePicker extends FrameLayout {
}
};
//AM/PM 改变监听器
private NumberPicker.OnValueChangeListener mOnAmPmChangedListener = new NumberPicker.OnValueChangeListener() {
@Override
public void onValueChange(NumberPicker picker, int oldVal, int newVal) {
@ -158,24 +186,30 @@ public class DateTimePicker extends FrameLayout {
}
};
//日期时间变化的监听器接口,需要被实现来响应日期时间的任何变化
public interface OnDateTimeChangedListener {
void onDateTimeChanged(DateTimePicker view, int year, int month,
int dayOfMonth, int hourOfDay, int minute);
}
//构造器1当没有指定日期时默认使用当前的系统时间
public DateTimePicker(Context context) {
this(context, System.currentTimeMillis());
}
//构造器2允许在创建控件时指定一个日期
public DateTimePicker(Context context, long date) {
this(context, date, DateFormat.is24HourFormat(context));
}
//构造器3最完整的构造器允许指定日期和是否以24小时格式显示时间
public DateTimePicker(Context context, long date, boolean is24HourView) {
super(context);
mDate = Calendar.getInstance();
mInitialising = true;
super(context); //调用父类构造器
mDate = Calendar.getInstance(); //初始化当前日期和时间的日历实例
mInitialising = true; //开始初始化流程的标志
//设置是否用上午/下午模式还是24小时制
mIsAm = getCurrentHourOfDay() >= HOURS_IN_HALF_DAY;
//通过XML布局文件创建视图
inflate(context, R.layout.datetime_picker, this);
mDateSpinner = (NumberPicker) findViewById(R.id.date);
@ -203,17 +237,20 @@ public class DateTimePicker extends FrameLayout {
updateHourControl();
updateAmPmControl();
//更新24小时播放视图
set24HourView(is24HourView);
// set to current time
// set to current time设置当前日期到指定的时间
setCurrentDate(date);
//更新控件的启用状态
setEnabled(isEnabled());
// set the content descriptions
mInitialising = false;
// set the content descriptions 设置内容描述
mInitialising = false; //初始化完成
}
//设置控件是否可用并且使内部的NumberPicker控件与之匹配
@Override
public void setEnabled(boolean enabled) {
if (mIsEnabled == enabled) {
@ -227,6 +264,7 @@ public class DateTimePicker extends FrameLayout {
mIsEnabled = enabled;
}
//检查控件是否可以与用户交互
@Override
public boolean isEnabled() {
return mIsEnabled;
@ -237,6 +275,8 @@ public class DateTimePicker extends FrameLayout {
*
* @return the current date in millis
*/
//获取当前的日期及时间
public long getCurrentDateInTimeMillis() {
return mDate.getTimeInMillis();
}
@ -246,6 +286,8 @@ public class DateTimePicker extends FrameLayout {
*
* @param date The current date in millis
*/
//设置当前日期和时间
public void setCurrentDate(long date) {
Calendar cal = Calendar.getInstance();
cal.setTimeInMillis(date);
@ -262,6 +304,8 @@ public class DateTimePicker extends FrameLayout {
* @param hourOfDay The current hourOfDay
* @param minute The current minute
*/
//设置具体的日期和时间
public void setCurrentDate(int year, int month,
int dayOfMonth, int hourOfDay, int minute) {
setCurrentYear(year);
@ -276,6 +320,8 @@ public class DateTimePicker extends FrameLayout {
*
* @return The current year
*/
//获取和设置当前的年份
public int getCurrentYear() {
return mDate.get(Calendar.YEAR);
}
@ -299,6 +345,8 @@ public class DateTimePicker extends FrameLayout {
*
* @return The current month in the year
*/
//获取和设置当前的月份
public int getCurrentMonth() {
return mDate.get(Calendar.MONTH);
}
@ -322,6 +370,8 @@ public class DateTimePicker extends FrameLayout {
*
* @return The day of the month
*/
//获取和设置当前的日期(天)
public int getCurrentDay() {
return mDate.get(Calendar.DAY_OF_MONTH);
}
@ -344,6 +394,8 @@ public class DateTimePicker extends FrameLayout {
* Get current hour in 24 hour mode, in the range (0~23)
* @return The current hour in 24 hour mode
*/
//获取和设置当前的小时(24时制)
public int getCurrentHourOfDay() {
return mDate.get(Calendar.HOUR_OF_DAY);
}
@ -394,6 +446,8 @@ public class DateTimePicker extends FrameLayout {
*
* @return The Current Minute
*/
//获取和设置当前的分钟数
public int getCurrentMinute() {
return mDate.get(Calendar.MINUTE);
}
@ -413,6 +467,8 @@ public class DateTimePicker extends FrameLayout {
/**
* @return true if this is in 24 hour view else false.
*/
//判断是否为24小时格式
public boolean is24HourView () {
return mIs24HourView;
}
@ -422,6 +478,8 @@ public class DateTimePicker extends FrameLayout {
*
* @param is24HourView True for 24 hour mode. False for AM/PM mode.
*/
//设置为24小时格式或者 AM/PM格式
public void set24HourView(boolean is24HourView) {
if (mIs24HourView == is24HourView) {
return;
@ -434,37 +492,40 @@ public class DateTimePicker extends FrameLayout {
updateAmPmControl();
}
//更新日期显示控制,以供日历滚动操作时显示正确日期
private void updateDateControl() {
Calendar cal = Calendar.getInstance();
cal.setTimeInMillis(mDate.getTimeInMillis());
cal.add(Calendar.DAY_OF_YEAR, -DAYS_IN_ALL_WEEK / 2 - 1);
mDateSpinner.setDisplayedValues(null);
Calendar cal = Calendar.getInstance(); //获取当前日期的日历实例
cal.setTimeInMillis(mDate.getTimeInMillis()); //设置日历时间为当前控件已选择的时间
cal.add(Calendar.DAY_OF_YEAR, -DAYS_IN_ALL_WEEK / 2 - 1); //将日历日期向后调整以便在选择器中心显示
mDateSpinner.setDisplayedValues(null); //清除显示值
for (int i = 0; i < DAYS_IN_ALL_WEEK; ++i) {
cal.add(Calendar.DAY_OF_YEAR, 1);
cal.add(Calendar.DAY_OF_YEAR, 1); //为日期数组的每一天累加一天
mDateDisplayValues[i] = (String) DateFormat.format("MM.dd EEEE", cal);
}
mDateSpinner.setDisplayedValues(mDateDisplayValues);
mDateSpinner.setValue(DAYS_IN_ALL_WEEK / 2);
mDateSpinner.invalidate();
mDateSpinner.setDisplayedValues(mDateDisplayValues); //设置日期选择器显示值为新的日期列表
mDateSpinner.setValue(DAYS_IN_ALL_WEEK / 2); //设置选择器的当前值为中间的日期
mDateSpinner.invalidate(); //刷新视图状态
}
//更新AM/PM显示控制以显示或隐藏AM/PM选择器具体取决于是否采用24小时视图
private void updateAmPmControl() {
if (mIs24HourView) {
mAmPmSpinner.setVisibility(View.GONE);
mAmPmSpinner.setVisibility(View.GONE); //如果是24小时制则隐藏AM/PM选择器
} else {
int index = mIsAm ? Calendar.AM : Calendar.PM;
mAmPmSpinner.setValue(index);
mAmPmSpinner.setVisibility(View.VISIBLE);
int index = mIsAm ? Calendar.AM : Calendar.PM; //确定当前是上午还是下午
mAmPmSpinner.setValue(index); //设置AM/PM选择器值为当前AM或者PM
mAmPmSpinner.setVisibility(View.VISIBLE); //显示AM/PM选择器
}
}
//更新小时显示控制调整小时选择器的最小和最大值以匹配所选择的24小时制或12小时制
private void updateHourControl() {
if (mIs24HourView) {
mHourSpinner.setMinValue(HOUR_SPINNER_MIN_VAL_24_HOUR_VIEW);
mHourSpinner.setMaxValue(HOUR_SPINNER_MAX_VAL_24_HOUR_VIEW);
mHourSpinner.setMinValue(HOUR_SPINNER_MIN_VAL_24_HOUR_VIEW); //如果24则小时选择器最小值设置为0/1
mHourSpinner.setMaxValue(HOUR_SPINNER_MAX_VAL_24_HOUR_VIEW); //小时选择器的最大值设置为23/24
} else {
mHourSpinner.setMinValue(HOUR_SPINNER_MIN_VAL_12_HOUR_VIEW);
mHourSpinner.setMaxValue(HOUR_SPINNER_MAX_VAL_12_HOUR_VIEW);
mHourSpinner.setMinValue(HOUR_SPINNER_MIN_VAL_12_HOUR_VIEW); // 如果12小时选择器的最小值 1
mHourSpinner.setMaxValue(HOUR_SPINNER_MAX_VAL_12_HOUR_VIEW); // 小时选择器的最大值 12
}
}
@ -472,14 +533,17 @@ public class DateTimePicker extends FrameLayout {
* Set the callback that indicates the 'Set' button has been pressed.
* @param callback the callback, if null will do nothing
*/
//设置一个回调函数,当用户点击"设置"时出发
public void setOnDateTimeChangedListener(OnDateTimeChangedListener callback) {
mOnDateTimeChangedListener = callback;
mOnDateTimeChangedListener = callback; //赋值回调接口
}
//调用回调函数,当日期或者时间发生改变时,这个方法通知订阅了监听器的客户端
private void onDateTimeChanged() {
if (mOnDateTimeChangedListener != null) {
mOnDateTimeChangedListener.onDateTimeChanged(this, getCurrentYear(),
getCurrentMonth(), getCurrentDay(), getCurrentHourOfDay(), getCurrentMinute());
getCurrentMonth(), getCurrentDay(), getCurrentHourOfDay(), getCurrentMinute()); //传递更新后的值给监听器
}
}
}

@ -29,61 +29,75 @@ import android.content.DialogInterface.OnClickListener;
import android.text.format.DateFormat;
import android.text.format.DateUtils;
//继承自 AlertDialog包含日期和时间选择的功能
public class DateTimePickerDialog extends AlertDialog implements OnClickListener {
//用于存储当前选择日期和时间
private Calendar mDate = Calendar.getInstance();
//标记是否使用24小时视图展示时间
private boolean mIs24HourView;
//回调接口定义,当日期和时间设定后激活
private OnDateTimeSetListener mOnDateTimeSetListener;
//本对话框包含的日期和时间选择器视图
private DateTimePicker mDateTimePicker;
//定义回调接口,用于通知调用者日期和时间已经设定
public interface OnDateTimeSetListener {
void OnDateTimeSet(AlertDialog dialog, long date);
}
//DateTimePickerDialog构造函数
public DateTimePickerDialog(Context context, long date) {
super(context);
mDateTimePicker = new DateTimePicker(context);
setView(mDateTimePicker);
super(context); //调用AlertDiaglog构造函数
mDateTimePicker = new DateTimePicker(context);//创建一个新的DateTimePicker实例
setView(mDateTimePicker);//将DateTimePicker视图添加到对话框中
//注册一个回调以在日期和时间改变时更新内部的Calendar实例
mDateTimePicker.setOnDateTimeChangedListener(new OnDateTimeChangedListener() {
public void onDateTimeChanged(DateTimePicker view, int year, int month,
int dayOfMonth, int hourOfDay, int minute) {
//更新Calendar实例的年、月、日、时、分
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());
updateTitle(mDate.getTimeInMillis()); //更新对话框标题显示的日期
}
});
mDate.setTimeInMillis(date);
mDate.set(Calendar.SECOND, 0);
mDateTimePicker.setCurrentDate(mDate.getTimeInMillis());
mDate.setTimeInMillis(date); // 将对话框初始化为传入的日期和时间值
mDate.set(Calendar.SECOND, 0); // 秒字段设为0
mDateTimePicker.setCurrentDate(mDate.getTimeInMillis()); // 将DateTimePicker初始化到当前日期
//设置对话框的'确定'和'取消'按钮
setButton(context.getString(R.string.datetime_dialog_ok), this);
setButton2(context.getString(R.string.datetime_dialog_cancel), (OnClickListener)null);
//设置是否使用24小时视图
set24HourView(DateFormat.is24HourFormat(this.getContext()));
updateTitle(mDate.getTimeInMillis());
updateTitle(mDate.getTimeInMillis()); // 初始对话框标题显示的日期和时间
}
//设置时间是否显示为24小时视图
public void set24HourView(boolean is24HourView) {
mIs24HourView = is24HourView;
}
//设置DateTimeSet监听回调
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;
flag |= mIs24HourView ? DateUtils.FORMAT_24HOUR : DateUtils.FORMAT_24HOUR;
setTitle(DateUtils.formatDateTime(this.getContext(), date, flag));
setTitle(DateUtils.formatDateTime(this.getContext(), date, flag)); // 格式化时间并设置标题
}
//点击对话框按钮调用,通知监听者时间已设置
public void onClick(DialogInterface arg0, int arg1) {
if (mOnDateTimeSetListener != null) {
mOnDateTimeSetListener.OnDateTimeSet(this, mDate.getTimeInMillis());
mOnDateTimeSetListener.OnDateTimeSet(this, mDate.getTimeInMillis()); // 激活回调传递当前设置的日期和时间
}
}

@ -0,0 +1,62 @@
package net.micode.notes.ui;
import android.app.Activity;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.view.View;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import net.micode.notes.R;
public class DeletingPassword extends Activity {
EditText Dt_password;
Button Acknowledged;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_delete_password);
getWindow().setSoftInputMode(
WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE
| WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);
Dt_password=(EditText) findViewById(R.id.thepassword);
Acknowledged=(Button)findViewById(R.id.Dt_Acknowledged);
Acknowledged.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String text02 = Dt_password.getText().toString();
if(text02.equals("")==true)
Toast.makeText(DeletingPassword.this, "密码不能为空",
Toast.LENGTH_SHORT).show();
SharedPreferences pref=getSharedPreferences("user management",MODE_PRIVATE);
String password = pref.getString("password","");
if(password.equals("")==false&&password.equals(text02)==true){
SharedPreferences.Editor editor=getSharedPreferences("user management", MODE_PRIVATE).edit();
editor.putBoolean("user",false);//false 表示已经设置登录密码
editor.putString("password","");
editor.apply();
Toast.makeText(DeletingPassword.this, "已经删除登录密码",
Toast.LENGTH_SHORT).show();
Intent intent=new
Intent(DeletingPassword.this,NotesListActivity.class);
startActivity(intent);
finish();
}
else{
Toast.makeText(DeletingPassword.this, "密码错误",
Toast.LENGTH_SHORT).show();
Dt_password.setText("");//把密码框内输入过的错误密码清空
}
}
});
}
@Override
public void onBackPressed() {
Intent intent=new Intent(DeletingPassword.this,NotesListActivity.class);
startActivity(intent);
finish();
}
}

@ -0,0 +1,55 @@
package net.micode.notes.ui;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.view.View;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import android.app.Activity;
import net.micode.notes.R;
public class LoginActivity extends Activity{
EditText lgn_password;
Button lgn_login;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
SharedPreferences pref = getSharedPreferences("user management", MODE_PRIVATE);
boolean User_boolean = pref.getBoolean("user", false); //检查用户是否设置了密码
if (!User_boolean) { //如果用户没有设置密码,则直接跳转到便签主界面
Intent intent = new Intent(LoginActivity.this, NotesListActivity.class);
startActivity(intent);
finish();
}
setContentView(R.layout.activity_login);
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE | WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
lgn_password = (EditText)findViewById(R.id.lgn_password);
lgn_login = (Button) findViewById(R.id.login);
lgn_login.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
SharedPreferences pref = getSharedPreferences("user management", MODE_PRIVATE);
String password = pref.getString("password", "");
if (password.equals(" ") == false && password.equals(lgn_password.getText().toString()) == true) {
Intent intent = new Intent(LoginActivity.this, NotesListActivity.class);
startActivity(intent);
finish();
} else {
Toast.makeText(LoginActivity.this, "密码错误", Toast.LENGTH_SHORT).show();
lgn_password.setText(""); //清空密码框内的输入
}
}
}
);
}
}

@ -47,6 +47,7 @@ import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
@ -71,13 +72,13 @@ import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
//该类主要针对标签的编辑,是Activity的一个子类
//实现了了系统内许多与监听有关的接口
public class NoteEditActivity extends Activity implements OnClickListener,
NoteSettingChangedListener, OnTextViewChangeListener {
//该类主要针对标签的编辑,是Activity的一个子类
//继承了系统内许多与监听有关的类
private class HeadViewHolder {
public TextView tvModified;
public TextView tvModified; //
public ImageView ivAlertIcon;
@ -85,67 +86,64 @@ 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);
sBgSelectorBtnsMap.put(R.id.iv_bg_red, ResourceParser.RED);
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函数是将指定值与指定键相连
sBgSelectorBtnsMap.put(R.id.iv_bg_white, ResourceParser.WHITE); //put函数是将指定值与指定键相连
}
private static final Map<Integer, Integer> sBgSelectorSelectionMap = new HashMap<Integer, Integer>();
static {
sBgSelectorSelectionMap.put(ResourceParser.YELLOW, R.id.iv_bg_yellow_select);
sBgSelectorSelectionMap.put(ResourceParser.RED, R.id.iv_bg_red_select);
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函数是将指定值与指定键相连
sBgSelectorSelectionMap.put(ResourceParser.WHITE, R.id.iv_bg_white_select); //put函数是将指定值与指定键相连
}
private static final Map<Integer, Integer> sFontSizeBtnsMap = new HashMap<Integer, Integer>();
static {
sFontSizeBtnsMap.put(R.id.ll_font_large, ResourceParser.TEXT_LARGE);
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函数是将指定值与指定键相连
sFontSizeBtnsMap.put(R.id.ll_font_super, ResourceParser.TEXT_SUPER); //put函数是将指定值与指定键相连
}
private static final Map<Integer, Integer> sFontSelectorSelectionMap = new HashMap<Integer, Integer>();
static {
sFontSelectorSelectionMap.put(ResourceParser.TEXT_LARGE, R.id.iv_large_select);
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函数是将指定值与指定键相连
sFontSelectorSelectionMap.put(ResourceParser.TEXT_SUPER, R.id.iv_super_select); //put函数是将指定值与指定键相连
}
private static final String TAG = "NoteEditActivity";
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;
private WorkingNote mWorkingNote;
//对模板WorkingNote的初始化
private SharedPreferences mSharedPrefs;
//私有化SharedPreferences的数据存储方式
//它的本质是基于XML文件存储key-value键值对数据
private int mFontSizeId;
//用于操作字体的大小
private View mHeadViewPanel; //私有化一个界面操作mHeadViewPanel对表头的操作
private View mNoteBgColorSelector; //私有化一个界面操作mNoteBgColorSelector对背景颜色的操作
private View mFontSizeSelector; //私有化一个界面操作mFontSizeSelector对标签字体的操作
private EditText mNoteEditor; //声明编辑控件,对文本操作
private View mNoteEditorPanel; //私有化一个界面操作mNoteEditorPanel文本编辑的控制板
private WorkingNote mWorkingNote; //对模板WorkingNote的初始化
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;
@ -153,8 +151,8 @@ public class NoteEditActivity extends Activity implements OnClickListener,
public static final String TAG_CHECKED = String.valueOf('\u221A');
public static final String TAG_UNCHECKED = String.valueOf('\u25A1');
private LinearLayout mEditTextList;
//线性布局
private LinearLayout mEditTextList; //线性布局
private String mUserQuery;
private Pattern mPattern;
@ -162,8 +160,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())) {
if (savedInstanceState == null && !initActivityState(getIntent())) { //对数据库的访问
finish();
return;
}
@ -185,7 +182,7 @@ public class NoteEditActivity extends Activity implements OnClickListener,
return;
}
Log.d(TAG, "Restoring from killed activity");
}//防止内存不足时的程序终止,保存现场的函数
} //防止内存不足时的程序终止,保存现场的函数
}
private boolean initActivityState(Intent intent) {
@ -193,31 +190,31 @@ public class NoteEditActivity extends Activity implements OnClickListener,
* If the user specified the {@link Intent#ACTION_VIEW} but not provided with id,
* then jump to the NotesListActivity
*/
// 在没有特定note ID的情况下Intent.ACTION VIEW被触发那么转向 NotesListActivity
mWorkingNote = null;
if (TextUtils.equals(Intent.ACTION_VIEW, intent.getAction())) {
long noteId = intent.getLongExtra(Intent.EXTRA_UID, 0);
long noteId = intent.getLongExtra(Intent.EXTRA_UID, 0); //如果用户实例化标签时系统并未给出标签ID
mUserQuery = "";
//如果用户实例化标签时系统并未给出标签ID
/**
* Starting from the searched result
*/
//根据键值查找ID
//根据键值查找ID,如果Intent~ 中存在搜索管理器的额外键值,则根据该键值检索 ID
if (intent.hasExtra(SearchManager.EXTRA_DATA_KEY)) {
noteId = Long.parseLong(intent.getStringExtra(SearchManager.EXTRA_DATA_KEY));
mUserQuery = intent.getStringExtra(SearchManager.USER_QUERY);
}
//如果没有在数据库中找到ID
// 如果该笔记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);
showToast(R.string.error_note_not_exist);//程序将跳转到声明的intent-jump
finish();
return false;
}
//如果在数据库中找到了ID
//如果在数据库中找到了ID,则加载笔记
else {
mWorkingNote = WorkingNote.load(this, noteId);
// 若加载失败,则记录错误并结束该 Activity
if (mWorkingNote == null) {
Log.e(TAG, "load note failed with note id" + noteId);
//打印出红色的错误信息
@ -225,15 +222,16 @@ public class NoteEditActivity extends Activity implements OnClickListener,
return false;
}
}
//setSoftInputMode-软键盘输入模式
//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())) {
} else if (TextUtils.equals(Intent.ACTION_INSERT_OR_EDIT, intent.getAction())) {
// New note
// intent.getAction()
// 大多用于broadcast发送广播时给机制intent设置一个action就是一个字符串
// 用户可以通过receive接受intent通过 getAction得到的字符串来决定做什么
// 在Intent.ACTION INSERT OR EDIT 的动作下创建新笔记或编辑现有笔记
long folderId = intent.getLongExtra(Notes.INTENT_EXTRA_FOLDER_ID, 0);
int widgetId = intent.getIntExtra(Notes.INTENT_EXTRA_WIDGET_ID,
AppWidgetManager.INVALID_APPWIDGET_ID);
@ -242,7 +240,7 @@ public class NoteEditActivity extends Activity implements OnClickListener,
int bgResId = intent.getIntExtra(Notes.INTENT_EXTRA_BACKGROUND_ID,
ResourceParser.getDefaultBgId(this));
// intent.getIntLong、StringExtra是对各变量的语法分析
// Parse call-record note
//解析来电记录笔记相关数据
String phoneNumber = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER);
long callDate = intent.getLongExtra(Notes.INTENT_EXTRA_CALL_DATE, 0);
if (callDate != 0 && phoneNumber != null) {
@ -250,33 +248,42 @@ public class NoteEditActivity extends Activity implements OnClickListener,
Log.w(TAG, "The call record number is null");
}
long noteId = 0;
//通过电话号码和通话日期查询笔记ID
if ((noteId = DataUtils.getNoteIdByPhoneNumberAndCallDate(getContentResolver(),
phoneNumber, callDate)) > 0) {
//如果查询成功,则加载来电记录笔记
mWorkingNote = WorkingNote.load(this, noteId);
//加载失败则记录错误并结束Activity
if (mWorkingNote == null) {
Log.e(TAG, "load call note failed with note id" + noteId);
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
} //创建一个新的WorkingNote
// 初始化软键盘输入模式,保持软键盘可见,同时在需要时调整布局大小
getWindow().setSoftInputMode(
WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE
| WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);
} else {
//如果'Intent'不包含已知动作则记录错误并结束Activity
Log.e(TAG, "Intent not specified action, should not support");
finish();
return false;
}
//为工作笔记设置状态改变监听器
mWorkingNote.setOnSettingStatusChangedListener(this);
return true;
}
@ -284,59 +291,76 @@ public class NoteEditActivity extends Activity implements OnClickListener,
@Override
protected void onResume() {
super.onResume();
initNoteScreen();
initNoteScreen(); //调用方法初始化笔记屏幕
}
//初始化笔记界面的方法
private void initNoteScreen() {
//设置笔记编辑器的文字样式
mNoteEditor.setTextAppearance(this, TextAppearanceResources
.getTexAppearanceResource(mFontSizeId));
//判断是否是清单模式,进行相应的试图转换
if (mWorkingNote.getCheckListMode() == TextNote.MODE_CHECK_LIST) {
switchToListMode(mWorkingNote.getContent());
} else {
//设置文本编辑器的文本并突出显示查询结果
mNoteEditor.setText(getHighlightQueryResult(mWorkingNote.getContent(), mUserQuery));
//将光标设置到文本末尾
mNoteEditor.setSelection(mNoteEditor.getText().length());
}
//隐藏所有背景选择器试图
for (Integer id : sBgSelectorSelectionMap.keySet()) {
findViewById(sBgSelectorSelectionMap.get(id)).setVisibility(View.GONE);
}
//设置标题和笔记编辑器面板的背景资源
mHeadViewPanel.setBackgroundResource(mWorkingNote.getTitleBgResId());
mNoteEditorPanel.setBackgroundResource(mWorkingNote.getBgColorResId());
//设置笔记头部信息,显示修改日期
mNoteHeaderHolder.tvModified.setText(DateUtils.formatDateTime(this,
mWorkingNote.getModifiedDate(), DateUtils.FORMAT_SHOW_DATE
| DateUtils.FORMAT_NUMERIC_DATE | DateUtils.FORMAT_SHOW_TIME
| DateUtils.FORMAT_SHOW_YEAR));
/**
/*
* TODO: Add the menu for setting alert. Currently disable it because the DateTimePicker
* is not ready
*/
showAlertHeader();
showAlertHeader(); //显示或隐藏笔记的提醒图标和提醒日期
}
//显示提醒头部的方法
private void showAlertHeader() {
//判断笔记是否有提醒时间
if (mWorkingNote.hasClockAlert()) {
//如果当前时间超过了提醒时间,则显示过期信息
long time = System.currentTimeMillis();
if (time > mWorkingNote.getAlertDate()) {
mNoteHeaderHolder.tvAlertDate.setText(R.string.note_alert_expired);
} 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);
};
}
;
}
//当活动通过意图重新初始化时调用
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
//用新的意图初始化活动状态
initActivityState(intent);
}
//在活动可能被系统销毁前调用,保存状态
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
@ -345,44 +369,54 @@ public class NoteEditActivity extends Activity implements OnClickListener,
* generate a id. If the editing note is not worth saving, there
* is no id which is equivalent to create new note
*/
//对于尚未在数据库中保存的新笔记先保存以生成ID
if (!mWorkingNote.existInDatabase()) {
saveNote();
}
//将笔记ID保存到状态Bundle中
outState.putLong(Intent.EXTRA_UID, mWorkingNote.getNoteId());
Log.d(TAG, "Save working note id: " + mWorkingNote.getNoteId() + " onSaveInstanceState");
}
//分发触摸事件的方法
@Override
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];
int[] location = new int[2];
//获取视图在屏幕上的位置
view.getLocationOnScreen(location);
int x = location[0];
int y = location[1];
//根据位置和触摸坐标判断是否在视图内
if (ev.getX() < x
|| ev.getX() > (x + view.getWidth())
|| ev.getY() < y
|| ev.getY() > (y + view.getHeight())) {
return false;
}
return false;
}
return true;
}
//初始化资源的方法
private void initResources() {
//找到并设置相关视图的引用
mHeadViewPanel = findViewById(R.id.note_title);
mNoteHeaderHolder = new HeadViewHolder();
mNoteHeaderHolder.tvModified = (TextView) findViewById(R.id.tv_modified_date);
@ -393,16 +427,20 @@ public class NoteEditActivity extends Activity implements OnClickListener,
mNoteEditor = (EditText) findViewById(R.id.note_edit_view);
mNoteEditorPanel = findViewById(R.id.sv_note_edit);
mNoteBgColorSelector = findViewById(R.id.note_bg_color_selector);
//为背景选择器中的按钮设置点击监听器
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);
/**
@ -410,46 +448,59 @@ public class NoteEditActivity extends Activity implements OnClickListener,
* The id may larger than the length of resources, in this case,
* return the {@link ResourceParser#BG_DEFAULT_FONT_SIZE}
*/
if(mFontSizeId >= TextAppearanceResources.getResourcesSize()) {
//如果字体大小ID超出资源数组大小设置为默认字体大小
if (mFontSizeId >= TextAppearanceResources.getResourcesSize()) {
mFontSizeId = ResourceParser.BG_DEFAULT_FONT_SIZE;
}
//初始化笔记编辑列表视图
mEditTextList = (LinearLayout) findViewById(R.id.note_edit_list);
}
//当活动暂停时调用
@Override
protected void onPause() {
super.onPause();
if(saveNote()) {
//尝试保存笔记,如果成功则记录保存的长度
if (saveNote()) {
Log.d(TAG, "Note data was saved with length:" + mWorkingNote.getContent().length());
}
//清除设置状态
clearSettingState();
}
//用于更新小部件
private void updateWidget() {
//创建一个更新小部件的intent
Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
//根据笔记的小部件类型决定使用哪个小部件提供器
if (mWorkingNote.getWidgetType() == Notes.TYPE_WIDGET_2X) {
intent.setClass(this, NoteWidgetProvider_2x.class);
} else if (mWorkingNote.getWidgetType() == Notes.TYPE_WIDGET_4X) {
intent.setClass(this, NoteWidgetProvider_4x.class);
} else {
//如果小部件类型不支持,则记录错误并返回
Log.e(TAG, "Unspported widget type");
return;
}
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, new int[] {
mWorkingNote.getWidgetId()
//添加小部件ID到intent中
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, new int[]{
mWorkingNote.getWidgetId()
});
//发送广播以通知小部件更新
sendBroadcast(intent);
//设置结果为OK
setResult(RESULT_OK, intent);
}
//处理点击事件
public void onClick(View v) {
int id = v.getId();
//如果点击的是设置背景颜色按钮,则显示颜色选择器
if (id == R.id.btn_set_bg_color) {
mNoteBgColorSelector.setVisibility(View.VISIBLE);
findViewById(sBgSelectorSelectionMap.get(mWorkingNote.getBgColorId())).setVisibility(
- View.VISIBLE);
-View.VISIBLE);
//更改背景颜色或字体大小的逻辑
} else if (sBgSelectorBtnsMap.containsKey(id)) {
findViewById(sBgSelectorSelectionMap.get(mWorkingNote.getBgColorId())).setVisibility(
View.GONE);
@ -471,17 +522,21 @@ public class NoteEditActivity extends Activity implements OnClickListener,
}
}
//当用户按下返回按钮时调用
@Override
public void onBackPressed() {
if(clearSettingState()) {
//清除设置状态,如果已经处理则返回
if (clearSettingState()) {
return;
}
//保存笔记然后正常处理返回事件
saveNote();
super.onBackPressed();
}
//清楚设置状态的辅助方法
private boolean clearSettingState() {
//如果背景颜色或字体大小选择器可见则隐藏他们并返回true表示状态已清除
if (mNoteBgColorSelector.getVisibility() == View.VISIBLE) {
mNoteBgColorSelector.setVisibility(View.GONE);
return true;
@ -492,15 +547,19 @@ public class NoteEditActivity extends Activity implements OnClickListener,
return false;
}
//当背景色改变时更新UI
public void onBackgroundColorChanged() {
//设置编辑面板和头部面板的背景
findViewById(sBgSelectorSelectionMap.get(mWorkingNote.getBgColorId())).setVisibility(
View.VISIBLE);
mNoteEditorPanel.setBackgroundResource(mWorkingNote.getBgColorResId());
mHeadViewPanel.setBackgroundResource(mWorkingNote.getTitleBgResId());
}
//准备选项菜单
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
//如果Activity正在结束则直接返回根据不同的情况填充不同的菜单
if (isFinishing()) {
return true;
}
@ -524,8 +583,10 @@ public class NoteEditActivity extends Activity implements OnClickListener,
return true;
}
//当选项被选中时调用
@Override
public boolean onOptionsItemSelected(MenuItem item) {
//处理菜单项的点击事件,如创建新笔记、删除笔记、更改字体大小等
int itemId = item.getItemId();
if (itemId == R.id.menu_new_note) {
createNewNote();
@ -562,13 +623,18 @@ 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);
//当用户设置了日期时间后,将这个时间保存为提醒的时间
mWorkingNote.setAlertDate(date, true);
}
});
//显示日期时间选择对话框
d.show();
}
@ -577,67 +643,86 @@ public class NoteEditActivity extends Activity implements OnClickListener,
* and {@text/plain} type
*/
private void sendTo(Context context, String info) {
//创建发送行为的Intent用于分享
Intent intent = new Intent(Intent.ACTION_SEND);
//将要分享的文本信息放入Intent
intent.putExtra(Intent.EXTRA_TEXT, info);
//设置分享的类型为纯文本
intent.setType("text/plain");
//开始执行分享行为
context.startActivity(intent);
}
private void createNewNote() {
// Firstly, save current editing notes
// Firstly, save current editing notes 保存正在编辑的笔记
saveNote();
// For safety, start a new NoteEditActivity
// For safety, start a new NoteEditActivity 结束当前的编辑活动并启动新的编辑活动
finish();
Intent intent = new Intent(this, NoteEditActivity.class);
intent.setAction(Intent.ACTION_INSERT_OR_EDIT);
//传递当前工作笔记所在的文件夹的ID到新的编辑活动
intent.putExtra(Notes.INTENT_EXTRA_FOLDER_ID, mWorkingNote.getFolderId());
startActivity(intent);
}
//删除当前编辑的笔记
private void deleteCurrentNote() {
//检查工作笔记是否存在于数据库中
if (mWorkingNote.existInDatabase()) {
HashSet<Long> ids = new HashSet<Long>();
long id = mWorkingNote.getNoteId();
if (id != Notes.ID_ROOT_FOLDER) {
//如果不是根文件夹则加入到需要删除的笔记ID集合中
ids.add(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);
}
private boolean isSyncMode() {
//获取同步账号名如果长度大于0表明存在同步账号即处于同步模式
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();
saveNote(); //如果笔记在数据库中不存在,则保存它
}
if (mWorkingNote.getNoteId() > 0) {
//创建一个AlarmReceiver的Intent将笔记ID附加到数据URI
Intent intent = new Intent(this, AlarmReceiver.class);
intent.setData(ContentUris.withAppendedId(Notes.CONTENT_NOTE_URI, mWorkingNote.getNoteId()));
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, intent, 0);
AlarmManager alarmManager = ((AlarmManager) getSystemService(ALARM_SERVICE));
//显示提醒的头部信息
showAlertHeader();
if(!set) {
if (!set) {
//如果set为false取消任何现有的闹钟
alarmManager.cancel(pendingIntent);
} else {
//如果set为true设置一个新的闹钟以唤醒设备并执行pendingIntent
alarmManager.set(AlarmManager.RTC_WAKEUP, date, pendingIntent);
}
} else {
@ -646,84 +731,94 @@ public class NoteEditActivity extends Activity implements OnClickListener,
* not worthy saving), we have no note id, remind the user that he
* should input something
*/
//如果笔记ID小于或等于0表示没有内容记录错误并显示提示
Log.e(TAG, "Clock alert setting error");
showToast(R.string.error_note_empty_for_clock);
}
}
//当小部件状态发生变化时的回调方法,可能是用来触发状态更新或视图刷新
public void onWidgetChanged() {
updateWidget();
updateWidget(); //更新小部件
}
//当编辑框中的文本被删除时的回调方法
public void onEditTextDelete(int index, String text) {
int childCount = mEditTextList.getChildCount();
if (childCount == 1) {
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);
}
mEditTextList.removeViewAt(index);
mEditTextList.removeViewAt(index);//移除指定索引处的编辑框视图
NoteEditText edit = null;
if(index == 0) {
if (index == 0) { //如果删除的是第一个编辑框
edit = (NoteEditText) mEditTextList.getChildAt(0).findViewById(
R.id.et_edit_text);
} else {
} else {//否则,获取欠一个编辑框
edit = (NoteEditText) mEditTextList.getChildAt(index - 1).findViewById(
R.id.et_edit_text);
}
//将删除的文本追加到当前聚焦的编辑框中
int length = edit.length();
edit.append(text);
edit.requestFocus();
edit.setSelection(length);
edit.requestFocus();//请求焦点
edit.setSelection(length);//设置光标位置
}
//当按下回车键时的回调方法,用于添加新的编辑框
public void onEditTextEnter(int index, String text) {
/**
* Should not happen, check for debug
*/
if(index > mEditTextList.getChildCount()) {
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");
mEditTextList.removeAllViews();//移除所有视图
String[] items = text.split("\n");//按换行符拆分文本成多个项
int index = 0;
for (String item : items) {
if(!TextUtils.isEmpty(item)) {
mEditTextList.addView(getListItem(item, index));
if (!TextUtils.isEmpty(item)) { //跳过空项
mEditTextList.addView(getListItem(item, index));//添加列表项
index++;
}
}
mEditTextList.addView(getListItem("", 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实例
SpannableString spannable = new SpannableString(fullText == null ? "" : fullText);
if (!TextUtils.isEmpty(userQuery)) {
mPattern = Pattern.compile(userQuery);
Matcher m = mPattern.matcher(fullText);
mPattern = Pattern.compile(userQuery);//编译用户的查询文本为正则模式
Matcher m = mPattern.matcher(fullText);//对全文进行匹配搜索
int start = 0;
while (m.find(start)) {
//对匹配到的结果设置高亮背景颜色
spannable.setSpan(
new BackgroundColorSpan(this.getResources().getColor(
R.color.user_query_highlight)), m.start(), m.end(),
@ -731,16 +826,21 @@ public class NoteEditActivity extends Activity implements OnClickListener,
start = m.end();
}
}
return spannable;
return spannable;//返回包含高亮查询结果的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) {
//根据复选框状态改变文本样式,如添加删除线
if (isChecked) {
edit.setPaintFlags(edit.getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG);
} else {
@ -748,7 +848,7 @@ public class NoteEditActivity extends Activity implements OnClickListener,
}
}
});
//根据复选框的状态初始化编辑框的文本和样式
if (item.startsWith(TAG_CHECKED)) {
cb.setChecked(true);
edit.setPaintFlags(edit.getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG);
@ -759,64 +859,77 @@ public class NoteEditActivity extends Activity implements OnClickListener,
item = item.substring(TAG_UNCHECKED.length(), item.length()).trim();
}
edit.setOnTextViewChangeListener(this);
edit.setIndex(index);
edit.setOnTextViewChangeListener(this);//设置文本变化监听器
edit.setIndex(index);//设置编辑框的索引
//设置并显示高亮查询结果
edit.setText(getHighlightQueryResult(item, mUserQuery));
return view;
}
//当文本内容发生改变且编辑框不为空时,会显示或隐藏复选框的方法
public void onTextChange(int index, boolean hasText) {
if (index >= mEditTextList.getChildCount()) {
if (index >= mEditTextList.getChildCount()) {//索引非法检查
Log.e(TAG, "Wrong index, should not happen");
return;
}
if(hasText) {
//根据文本是否存在来设置复选框的可见性
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;
if (mWorkingNote.getCheckListMode() == TextNote.MODE_CHECK_LIST) {
StringBuilder sb = new StringBuilder();
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 (!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;
} else {
//如果未勾选,同样将文本添加到工作文本中,但不进行标记
sb.append(TAG_UNCHECKED).append(" ").append(edit.getText()).append("\n");
}
}
}
//设置笔记的工作文本
mWorkingNote.setWorkingText(sb.toString());
} else {
//如果不在复选框列表模式中,直接从编辑器获取文本
mWorkingNote.setWorkingText(mNoteEditor.getText().toString());
}
return hasChecked;
return hasChecked; //返回是否有勾选项的标志
}
//保存笔记的方法,该方法会首先获取工作文本,然后保存笔记
private boolean saveNote() {
getWorkingText();
boolean saved = mWorkingNote.saveNote();
getWorkingText();//获取当前的编辑框文本数据
boolean saved = mWorkingNote.saveNote();//保存笔记,并获取结果
if (saved) {
/**
* There are two modes from List view to edit view, open one note,
@ -825,34 +938,46 @@ 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
*/
//设置保存成功的结果,以便正确处理返回时的列表位置
setResult(RESULT_OK);
}
return saved;
return saved;//返回保存是否成功的标志
}
private void sendToDesktop() {
/**
* Before send message to home, we should make sure that current
* editing note is exists in databases. So, for new note, firstly
* save it
* saveNote
*/
if (!mWorkingNote.existInDatabase()) {
saveNote();
}
//如果已保存的笔记存在有效的ID准备创建快捷方式
if (mWorkingNote.getNoteId() > 0) {
Intent sender = new Intent();
//意图指向NoteEditActivity代表要打开的编辑笔记的组件
Intent shortcutIntent = new Intent(this, NoteEditActivity.class);
shortcutIntent.setAction(Intent.ACTION_VIEW);
//将笔记ID作为额外的信息附加到意图上
shortcutIntent.putExtra(Intent.EXTRA_UID, mWorkingNote.getNoteId());
//将定义好的编辑笔记的意图作为快捷方式的意图进行设置
sender.putExtra(Intent.EXTRA_SHORTCUT_INTENT, shortcutIntent);
//设置快捷方式的名称
sender.putExtra(Intent.EXTRA_SHORTCUT_NAME,
makeShortcutIconTitle(mWorkingNote.getContent()));
//设置快捷方式图标的资源
sender.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE,
Intent.ShortcutIconResource.fromContext(this, R.drawable.icon_app));
//避免快捷方式重复,设定"duplicate"为true
sender.putExtra("duplicate", true);
//设置该动作用于告诉启动器创建一个新的快捷方式
sender.setAction("com.android.launcher.action.INSTALL_SHORTCUT");
//显示提示已发送到桌面的信息
showToast(R.string.info_note_enter_desktop);
//发送广播以创建快捷方式
sendBroadcast(sender);
} else {
/**
@ -860,23 +985,45 @@ public class NoteEditActivity extends Activity implements OnClickListener,
* not worthy saving), we have no note id, remind the user that he
* should input something
*/
//如果为输入任何内容则不存在笔记ID提示用户输入一些内容
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;
}
//显示一个短时间长度的Toast消息具体消息由资源ID指定
private void showToast(int resId) {
showToast(resId, Toast.LENGTH_SHORT);
}
//显示一个Toast消息可以指定消息的资源ID和持续时间
private void showToast(int resId, int duration) {
Toast.makeText(this, resId, duration).show();
}
final ImageButton add_img_btn = (ImageButton) findViewById(R.id.add_img_btn);
add_img_btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
log.d(TAG, "onClick: click add image button");
Intent loadImage = new Intent(Intent.ACTION_GET_CONTENT);
loadImage.addCategory(Intent.CATEGORY_OPENABLE);
loadImage.setType("image/*");
startActivityForResult(loadImage, PHOTO_REQUESt);
}
});
}

@ -37,17 +37,22 @@ import net.micode.notes.R;
import java.util.HashMap;
import java.util.Map;
//NoteEditText类拓展自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:" ;
//协议模式和资源ID映射用于创建上下文菜单项
private static final Map<String, Integer> sSchemaActionResMap = new HashMap<String, Integer>();
static {
//将电话、网页、邮箱对应的文本资源ID填充到映射
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);
@ -56,6 +61,7 @@ public class NoteEditText extends EditText {
/**
* Call by the {@link NoteEditActivity} to delete or add edit text
*/
//接口,用于监听文本视图的改变事件,例如删除和输入
public interface OnTextViewChangeListener {
/**
* Delete current edit text when {@link KeyEvent#KEYCODE_DEL} happens
@ -74,33 +80,39 @@ public class NoteEditText extends EditText {
*/
void onTextChange(int index, boolean hasText);
}
//用于通知文本视图更改的监听器
private OnTextViewChangeListener mOnTextViewChangeListener;
//构造函数初始化编辑框设置索引值为0
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
// TODO Auto-generated constructor stub 未实现的
}
//触摸事件的处理,主要是为了处理文本选择
@Override
public boolean onTouchEvent(MotionEvent event) {
//处理用户的触摸事件,设置了文本的选择位置
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
@ -121,6 +133,7 @@ public class NoteEditText extends EditText {
return super.onTouchEvent(event);
}
//键盘按键事件的处理,主要是监听删除键和回车键
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
switch (keyCode) {
@ -138,6 +151,7 @@ public class NoteEditText extends EditText {
return super.onKeyDown(keyCode, event);
}
//松开按键事件的处理
@Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
switch(keyCode) {
@ -167,51 +181,60 @@ public class NoteEditText extends EditText {
return super.onKeyUp(keyCode, event);
}
//当编辑框焦点改变时,比如失去或者获取焦点时的处理
@Override
protected void onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect) {
if (mOnTextViewChangeListener != null) {
if (!focused && TextUtils.isEmpty(getText())) {
mOnTextViewChangeListener.onTextChange(mIndex, false);
} else {
}
else {
mOnTextViewChangeListener.onTextChange(mIndex, true);
}
}
super.onFocusChanged(focused, direction, previouslyFocusedRect);
}
//上下文菜单创建时的处理,可以在编辑框中添加特定行为的菜单项,例如打电话、打开网页或发送邮箱
@Override
protected void onCreateContextMenu(ContextMenu menu) {
//检查文本内容是否为Spanned类型
if (getText() instanceof Spanned) {
int selStart = getSelectionStart();
int selEnd = getSelectionEnd();
int selStart = getSelectionStart();//获取选择文本起始位置
int selEnd = getSelectionEnd();// 结束位置
int min = Math.min(selStart, selEnd);
int max = Math.max(selStart, selEnd);
//从选择文本中获取URLSpan对象数组
final URLSpan[] urls = ((Spanned) getText()).getSpans(min, max, URLSpan.class);
//如果只有一个URLSpan存在
if (urls.length == 1) {
int defaultResId = 0;
//遍历所有已定义的模式(schema)
for(String schema: sSchemaActionResMap.keySet()) {
//如果URLSpan的URL中包含该模式
if(urls[0].getURL().indexOf(schema) >= 0) {
//获取该模式对应的资源ID
defaultResId = sSchemaActionResMap.get(schema);
break;
}
}
//如果没有找到匹配的模式对应的资源ID则使用R.string.note_link_other作为默认资源ID
if (defaultResId == 0) {
defaultResId = R.string.note_link_other;
}
//像上下文菜单中添加菜单项,并设置点击事件
menu.add(0, 0, 0, defaultResId).setOnMenuItemClickListener(
new OnMenuItemClickListener() {
public boolean onMenuItemClick(MenuItem item) {
// goto a new intent
// goto a new intent 执行URLSpan中定义的点击操作
urls[0].onClick(NoteEditText.this);
return true;
}
});
}
}
super.onCreateContextMenu(menu);
super.onCreateContextMenu(menu); //调用父类的方法创建上下文菜单
}
}

@ -0,0 +1,66 @@
package net.micode.notes.ui;
import static android.content.Context.MODE_PRIVATE;
import android.app.Activity;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import net.micode.notes.R;
public class SettingPassword extends Activity {
EditText password;
EditText password_ack;
Button acknowledge;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_set_loginpassword);
getWindow().setSoftInputMode(
WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE
| WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);
password = (EditText) findViewById(R.id.password);
password_ack = (EditText) findViewById(R.id.password_ack);
acknowledge = (Button)findViewById(R.id.acknowledge);
acknowledge.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String text02 = password.getText().toString();
String text03 = password_ack.getText().toString();
if(text02.equals("")==true) {
Toast.makeText(SettingPassword.this, "密码不能为空", Toast.LENGTH_SHORT).show();
}
else if (text02.equals(text03) == false) {
Toast.makeText(SettingPassword.this, "密码错误,请重新输入密码 ", Toast.LENGTH_SHORT).show();
password_ack.setText("");
}
else if (text02.equals(text03) == true){
SharedPreferences.Editor editor=getSharedPreferences("user management", MODE_PRIVATE).edit();
editor.putBoolean("user",true); //true 表示已经设置登录密码
editor.putString("password",text02);
editor.apply();
Log.d("RegisterLoginPassword","password is "+text02);
Toast.makeText(SettingPassword.this, "密码设置成功",
Toast.LENGTH_SHORT).show();
Intent intent=new
Intent(SettingPassword.this,NotesListActivity.class);
startActivity(intent);
finish();
}
}
});
}
@Override
public void onBackPressed() {
Intent intent=new Intent(SettingPassword.this,NotesListActivity.class);
startActivity(intent);
finish();
}
}

@ -0,0 +1,29 @@
package net.micode.notes.ui;
import android.annotation.SuppressLint;
import android.content.Intent;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.view.MotionEvent;
import android.view.View;
import android.view.WindowInsets;
import net.micode.notes.R;
public class SplashActivity extends AppCompatActivity {
Handler mHandler=new Handler();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); //加载启动界面
setContentView(R.layout.activity_splash); //加载启动
// 当计时结束时,跳转至 NotesListActivity
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
Intent intent = new Intent();
intent.setClass(SplashActivity.this, LoginActivity.class);
startActivity(intent);
finish(); //销毁欢迎页面
}
}, 2000); // 2 秒后跳转}

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- 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.
-->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true" android:color="#88555555" />
<item android:state_selected="true" android:color="#ff999999" />
<item android:color="#ff000000" />
</selector>

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- 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.
-->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="#50000000" />
</selector>

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 245 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 443 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 554 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 87 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 116 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- 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.
-->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true"
android:drawable="@drawable/new_note_pressed" />
<item
android:drawable="@drawable/new_note_normal" />
</selector>

@ -0,0 +1,43 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- 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.
-->
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
xmlns:android="http://schemas.android.com/apk/res/android">
<TextView
android:id="@+id/account_dialog_title"
style="?android:attr/textAppearanceMedium"
android:singleLine="true"
android:ellipsize="end"
android:gravity="center"
android:layout_marginTop="-2.7dip"
android:layout_marginBottom="-2.7dip"
android:layout_width="fill_parent"
android:layout_height="wrap_content"/>
<TextView
android:id="@+id/account_dialog_subtitle"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="5dip"
android:layout_marginBottom="1dip"
android:gravity="center"/>
</LinearLayout>

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save