我发现,小米便签会自动显示出每条便签的第一行内容。而在我们日常生活使用便签的时候,出于方便往往会在里面记录一些重要(例如账号密码)或者比较隐私的内容。因此,我打算为它增添一个隐私模式——不显示便签的第一行内容和不显示文件夹的名称(但是会保留最近一次的修改时间和闹钟标记)。
目录
一、操作步骤
1、首先要知道我们是在主界面加入“私密模式”和“退出私密模式”这两个选项,因此首先我们要在menu/note_list.xml中加入两个item,然后分别在values/strings/下的三个.xml文件中对这两个值进行声明(这里中文简体和繁体可以一样),但是仅仅这样是不对的,此处先挖一个坑,大家可以先想想为什么,后面再解释。
<item
android:id="@+id/menu_secret"
android:title="@string/menu_secret"/>
<item
android:id="@+id/menu_quit_secret"
android:title="@string/menu_quit_secret"/>
<string name="menu_secret">secret model</string>
<string name="menu_quit_secret">quit secret model</string>
<string name="menu_secret">私密模式</string>
<string name="menu_quit_secret">退出私密模式</string>
2、然后因为我们是要对便签的所有标题进行修改,因此我们主要是在NotesListActivity类中加入代码。首先是在NotesListActivity()方法中声明一个变量secret_mode。当它值为0时代表未进入私密模式,为1时代表进入了私密模式。这里我初始化为0。
public static int secret_mode = 0;
接着在onPrepareOptionMenu()方法中设置两个按钮是否可见。即私密模式下“私密模式”按钮不可见,非私密模式下“退出私密模式”按钮不可见,这样界面上看起来更符合逻辑一些。
if(secret_mode == 1)
menu.findItem(R.id.menu_secret).setVisible(false);
else
menu.findItem(R.id.menu_quit_secret).setVisible(false);
3、接下来的重点就是startAsyncNotesListQuery()方法了。通过前期的代码精度我们知道,这个函数主要是用于同步便签列表之前的准备工作。在这个方法中我们要修改的就是startQuery()函数中的第四个变量:NoteIemData.PROJECTION。
首先我们来看看他有什么东西,ctrl+左键,我们进入了NoteItemData类,可以发现,这是个字符串数组,存储的就是那一行标题的内容!!!而我们需要修改的就是SNIPPET这一项!!!这样一来问题就迎刃而解了。
public class NoteItemData {
static final String [] PROJECTION = new String [] {
NoteColumns.ID,
NoteColumns.ALERTED_DATE,
NoteColumns.BG_COLOR_ID,
NoteColumns.CREATED_DATE,
NoteColumns.HAS_ATTACHMENT,
NoteColumns.MODIFIED_DATE,
NoteColumns.NOTES_COUNT,
NoteColumns.PARENT_ID,
NoteColumns.SNIPPET,
NoteColumns.TYPE,
NoteColumns.WIDGET_ID,
NoteColumns.WIDGET_TYPE,
};
修改startAsyncNotesListQuery()方法,在他初始化前首先对secret_mode的值进行判断,若为0,则按之前的方法继续调用NoteItemData中的PROJECTION数组;但是如果secret_mode值为1,即此时进入了私密模式,那么我们就需要定义一个新的PROJECTION数组,然后把SNIPPET修改为我们想要修改的字符串就可以了,最后再调用这个数组。
private void startAsyncNotesListQuery() {
String selection = (mCurrentFolderId == Notes.ID_ROOT_FOLDER) ? ROOT_FOLDER_SELECTION
: NORMAL_SELECTION;
if(secret_mode == 0) {
mBackgroundQueryHandler.startQuery(FOLDER_NOTE_LIST_QUERY_TOKEN, null,
Notes.CONTENT_NOTE_URI, NoteItemData.PROJECTION, selection, new String[]{
String.valueOf(mCurrentFolderId)
}, NoteColumns.TYPE + " DESC," + NoteColumns.MODIFIED_DATE + " DESC");
}
else{
String str1 = "520";
String [] PROJECTION = new String [] { //定义一个新的PROJECTION数组,只换掉SNIPPET
NoteColumns.ID,
NoteColumns.ALERTED_DATE,
NoteColumns.BG_COLOR_ID,
NoteColumns.CREATED_DATE,
NoteColumns.HAS_ATTACHMENT,
NoteColumns.MODIFIED_DATE,
NoteColumns.NOTES_COUNT,
NoteColumns.PARENT_ID,
// NoteColumns.SNIPPET,
str1,
NoteColumns.TYPE,
NoteColumns.WIDGET_ID,
NoteColumns.WIDGET_TYPE,
};
mBackgroundQueryHandler.startQuery(FOLDER_NOTE_LIST_QUERY_TOKEN, null,
Notes.CONTENT_NOTE_URI, PROJECTION, selection, new String[]{
String.valueOf(mCurrentFolderId)
}, NoteColumns.TYPE + " DESC," + NoteColumns.MODIFIED_DATE + " DESC");
}
}
4、接着,找到onOptionsItemSelected()方法,在switch()下加入两个新的case。这里为了更人性化一些,我加入了Toast和dialog方法。
case R.id.menu_secret: { //进入私密模式
secret_mode = 1;
AlertDialog.Builder dialog = new AlertDialog.Builder(NotesListActivity.this);
dialog.setTitle("重要提醒");
dialog.setMessage("您确认进入私密模式吗?");
dialog.setCancelable(false);
dialog.setPositiveButton("确认", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
startAsyncNotesListQuery();
Toast.makeText(NotesListActivity.this,"您已进入私密模式",Toast.LENGTH_SHORT).show();
}
});
dialog.setNegativeButton("取消", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which){}
});
dialog.show();
startAsyncNotesListQuery();
Toast.makeText(this,"您已进入私密模式",Toast.LENGTH_SHORT).show();
break;
}
case R.id.menu_quit_secret:{ //退出私密模式
secret_mode = 0;
AlertDialog.Builder dialog = new AlertDialog.Builder(NotesListActivity.this);
dialog.setTitle("重要提醒");
dialog.setMessage("您确认退出私密模式吗?");
dialog.setCancelable(false);
dialog.setPositiveButton("确认", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
startAsyncNotesListQuery();
Toast.makeText(NotesListActivity.this,"您已退出私密模式",Toast.LENGTH_SHORT).show();
}
});
dialog.setNegativeButton("取消", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which){}
});
dialog.show();
break;
}
现在代码写的差不多了,于是我们开始测试这个私密模式。点着点着,我们突然发现,在进入文件夹后,如果这个时候点击菜单按钮,程序居然崩溃了!显示“很抱歉,便签已停止运行”,并且试了很多次也是这样。
但是别慌,其实AS提供了一个很强大的类似于debug的工具——logcat。我们用logcat查看并定位到错误的地方,发现居然是两个按钮切换的地方报错了。再联想到刚刚是文件夹的菜单,于是我们就可以得出结论,应该是文件夹下的菜单出了问题。
难道是因为这里没有加入按钮?我们尝试着在menu_sub_folder.xml中加入了之前两个按钮的声明。
<item
android:id="@+id/menu_secret"
android:title="@string/menu_secret"/>
<item
android:id="@+id/menu_quit_secret"
android:title="@string/menu_quit_secret"/>
重新运行,我们就发现bug解决掉了。所以应该就是之前没有考虑到在文件夹下的菜单情况。所以说,我们在写代码的时候,一定要尽可能的考虑到各个方面,不然就容易出错。
不过就算出错了也没有关系,善于运用AS自带的logcat可以帮助我们解决很多问题。
二、最终效果
三、总结
其实一开始写这个私密模式功能的时候,我是从NotesListAdapter类出发来写的,但是写了很久发现一直因为刷新问题解决不了。后来和大佬交流,换了一个思路,才得以解决。这里也建议大家在写功能的时候,可以多和之前精度代码看ui包的同学交流一下,应该会有意想不到的收获。