|
|
|
@ -84,9 +84,9 @@ import java.util.HashSet;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public class NotesListActivity extends AppCompatActivity implements OnClickListener, OnItemLongClickListener {
|
|
|
|
|
private static final int FOLDER_NOTE_LIST_QUERY_TOKEN = 0;
|
|
|
|
|
private static final int FOLDER_NOTE_LIST_QUERY_TOKEN = 0;//查询文件夹中的便签列表
|
|
|
|
|
|
|
|
|
|
private static final int FOLDER_LIST_QUERY_TOKEN = 1;
|
|
|
|
|
private static final int FOLDER_LIST_QUERY_TOKEN = 1;//查询文件夹列表
|
|
|
|
|
|
|
|
|
|
private static final int MENU_FOLDER_DELETE = 0;
|
|
|
|
|
|
|
|
|
@ -217,17 +217,17 @@ public class NotesListActivity extends AppCompatActivity implements OnClickListe
|
|
|
|
|
private void initResources() {
|
|
|
|
|
mContentResolver = this.getContentResolver();
|
|
|
|
|
mBackgroundQueryHandler = new BackgroundQueryHandler(this.getContentResolver());
|
|
|
|
|
mCurrentFolderId = Notes.ID_ROOT_FOLDER;
|
|
|
|
|
mCurrentFolderId = Notes.ID_ROOT_FOLDER;//0
|
|
|
|
|
mNotesListView = (ListView) findViewById(R.id.notes_list);
|
|
|
|
|
mNotesListView.addFooterView(LayoutInflater.from(this).inflate(R.layout.note_list_footer, null),
|
|
|
|
|
null, false);
|
|
|
|
|
mNotesListView.setOnItemClickListener(new OnListItemClickListener());
|
|
|
|
|
mNotesListView.setOnItemLongClickListener(this);
|
|
|
|
|
mNotesListView.setOnItemClickListener(new OnListItemClickListener());//单击监听器
|
|
|
|
|
mNotesListView.setOnItemLongClickListener(this);//长按监听器
|
|
|
|
|
mNotesListAdapter = new NotesListAdapter(this);
|
|
|
|
|
mNotesListView.setAdapter(mNotesListAdapter);
|
|
|
|
|
mAddNewNote = (Button) findViewById(R.id.btn_new_note);
|
|
|
|
|
mAddNewNote.setOnClickListener(this);
|
|
|
|
|
mAddNewNote.setOnTouchListener(new NewNoteOnTouchListener());
|
|
|
|
|
mAddNewNote.setOnClickListener(this);//“添加便签”按钮的监听器
|
|
|
|
|
mAddNewNote.setOnTouchListener(new NewNoteOnTouchListener());//给按钮绑定自定义的触摸监听器
|
|
|
|
|
mDispatch = false;
|
|
|
|
|
mDispatchY = 0;
|
|
|
|
|
mOriginY = 0;
|
|
|
|
@ -235,14 +235,15 @@ public class NotesListActivity extends AppCompatActivity implements OnClickListe
|
|
|
|
|
mState = ListEditState.NOTE_LIST;
|
|
|
|
|
mModeCallBack = new ModeCallback();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//内部类
|
|
|
|
|
private class ModeCallback implements ListView.MultiChoiceModeListener, OnMenuItemClickListener {
|
|
|
|
|
private DropdownMenu mDropDownMenu;
|
|
|
|
|
private ActionMode mActionMode;
|
|
|
|
|
private MenuItem mMoveMenu;
|
|
|
|
|
|
|
|
|
|
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
|
|
|
|
|
getMenuInflater().inflate(R.menu.note_list_options, menu);
|
|
|
|
|
getMenuInflater().inflate(R.menu.note_list_options, menu);//通过调用 getMenuInflater().inflate() 方法加载菜单布局文件 R.menu.note_list_options,
|
|
|
|
|
// 并将菜单项添加到 menu 中。
|
|
|
|
|
menu.findItem(R.id.delete).setOnMenuItemClickListener(this);
|
|
|
|
|
mMoveMenu = menu.findItem(R.id.move);
|
|
|
|
|
if (mFocusNoteDataItem.getParentId() == Notes.ID_CALL_RECORD_FOLDER
|
|
|
|
@ -253,8 +254,8 @@ public class NotesListActivity extends AppCompatActivity implements OnClickListe
|
|
|
|
|
mMoveMenu.setOnMenuItemClickListener(this);
|
|
|
|
|
}
|
|
|
|
|
mActionMode = mode;
|
|
|
|
|
mNotesListAdapter.setChoiceMode(true);
|
|
|
|
|
mNotesListView.setLongClickable(false);
|
|
|
|
|
mNotesListAdapter.setChoiceMode(true);//设置列表适配器的选择模式为 true,以启用多选模式。
|
|
|
|
|
mNotesListView.setLongClickable(false);//将列表视图的长按点击功能禁用。
|
|
|
|
|
mAddNewNote.setVisibility(View.GONE);
|
|
|
|
|
|
|
|
|
|
View customView = LayoutInflater.from(NotesListActivity.this).inflate(
|
|
|
|
@ -274,10 +275,13 @@ public class NotesListActivity extends AppCompatActivity implements OnClickListe
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 用于更新菜单项和下拉菜单。
|
|
|
|
|
*/
|
|
|
|
|
private void updateMenu() {
|
|
|
|
|
int selectedCount = mNotesListAdapter.getSelectedCount();
|
|
|
|
|
int selectedCount = mNotesListAdapter.getSelectedCount();//多选时选的项数
|
|
|
|
|
// Update dropdown menu
|
|
|
|
|
String format = getResources().getString(R.string.menu_select_title, selectedCount);
|
|
|
|
|
String format = getResources().getString(R.string.menu_select_title, selectedCount);//第二个参数是换第一个参数的占位符的
|
|
|
|
|
mDropDownMenu.setTitle(format);
|
|
|
|
|
MenuItem item = mDropDownMenu.findItem(R.id.action_select_all);
|
|
|
|
|
if (item != null) {
|
|
|
|
@ -286,7 +290,7 @@ public class NotesListActivity extends AppCompatActivity implements OnClickListe
|
|
|
|
|
item.setTitle(R.string.menu_deselect_all);
|
|
|
|
|
} else {
|
|
|
|
|
item.setChecked(false);
|
|
|
|
|
item.setTitle(R.string.menu_select_all);
|
|
|
|
|
item.setTitle(R.string.menu_select_all);//全选
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -311,6 +315,14 @@ public class NotesListActivity extends AppCompatActivity implements OnClickListe
|
|
|
|
|
mActionMode.finish();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 被勾选了,或取消勾选了,就改变hashmap里的该项的value的boolean值
|
|
|
|
|
* @param mode The {@link ActionMode} providing the selection mode
|
|
|
|
|
* @param position Adapter position of the item that was checked or unchecked
|
|
|
|
|
* @param id Adapter ID of the item that was checked or unchecked
|
|
|
|
|
* @param checked <code>true</code> if the item is now checked, <code>false</code>
|
|
|
|
|
* if the item is now unchecked.
|
|
|
|
|
*/
|
|
|
|
|
public void onItemCheckedStateChanged(ActionMode mode, int position, long id,
|
|
|
|
|
boolean checked) {
|
|
|
|
|
mNotesListAdapter.setCheckedItem(position, checked);
|
|
|
|
@ -320,11 +332,11 @@ public class NotesListActivity extends AppCompatActivity implements OnClickListe
|
|
|
|
|
public boolean onMenuItemClick(MenuItem item) {
|
|
|
|
|
if (mNotesListAdapter.getSelectedCount() == 0) {
|
|
|
|
|
Toast.makeText(NotesListActivity.this, getString(R.string.menu_select_none),
|
|
|
|
|
Toast.LENGTH_SHORT).show();
|
|
|
|
|
Toast.LENGTH_SHORT).show();//没有选中项,操作无效
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
switch (item.getItemId()) {
|
|
|
|
|
switch (item.getItemId()) {//选中的下拉菜单中的菜单项
|
|
|
|
|
case R.id.delete:
|
|
|
|
|
AlertDialog.Builder builder = new AlertDialog.Builder(NotesListActivity.this);
|
|
|
|
|
builder.setTitle(getString(R.string.alert_title_delete));
|
|
|
|
@ -422,19 +434,32 @@ public class NotesListActivity extends AppCompatActivity implements OnClickListe
|
|
|
|
|
}, NoteColumns.TYPE + " DESC," + NoteColumns.MODIFIED_DATE + " DESC");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
自定义异步处理查询类,用于在后台执行查询操作并处理查询结果
|
|
|
|
|
这个类是为了避免在主线程中执行耗时的数据库查询或与内容提供者交互的操作,以确保应用程序的界面响应性能。
|
|
|
|
|
*/
|
|
|
|
|
private final class BackgroundQueryHandler extends AsyncQueryHandler {
|
|
|
|
|
public BackgroundQueryHandler(ContentResolver contentResolver) {
|
|
|
|
|
super(contentResolver);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* token 参数表示查询操作的标识符,用于区分不同的查询操作。
|
|
|
|
|
* cookie 参数是一个可选的对象,用于在发起查询时传递额外的数据,在查询完成后原样返回,可以用于标识查询操作的上下文或其他需要的信息。
|
|
|
|
|
* cursor 参数是查询返回的结果集,它是一个游标对象(Cursor),用于遍历查询结果的数据。
|
|
|
|
|
* @param token the token to identify the query, passed in from
|
|
|
|
|
* {@link #startQuery}.
|
|
|
|
|
* @param cookie the cookie object passed in from {@link #startQuery}.
|
|
|
|
|
* @param cursor The cursor holding the results from the query.
|
|
|
|
|
*/
|
|
|
|
|
@Override
|
|
|
|
|
protected void onQueryComplete(int token, Object cookie, Cursor cursor) {
|
|
|
|
|
switch (token) {
|
|
|
|
|
case FOLDER_NOTE_LIST_QUERY_TOKEN:
|
|
|
|
|
case FOLDER_NOTE_LIST_QUERY_TOKEN://0 对文件夹内的笔记列表进行查询操作
|
|
|
|
|
mNotesListAdapter.changeCursor(cursor);
|
|
|
|
|
break;
|
|
|
|
|
case FOLDER_LIST_QUERY_TOKEN:
|
|
|
|
|
if (cursor != null && cursor.getCount() > 0) {
|
|
|
|
|
case FOLDER_LIST_QUERY_TOKEN://1 对文件夹列表进行查询操作
|
|
|
|
|
if (cursor != null && cursor.getCount() > 0) {//有文件夹
|
|
|
|
|
showFolderListMenu(cursor);
|
|
|
|
|
} else {
|
|
|
|
|
Log.e(TAG, "Query folder failed");
|
|
|
|
@ -448,7 +473,7 @@ public class NotesListActivity extends AppCompatActivity implements OnClickListe
|
|
|
|
|
|
|
|
|
|
private void showFolderListMenu(Cursor cursor) {
|
|
|
|
|
AlertDialog.Builder builder = new AlertDialog.Builder(NotesListActivity.this);
|
|
|
|
|
builder.setTitle(R.string.menu_title_select_folder);
|
|
|
|
|
builder.setTitle(R.string.menu_title_select_folder);//选择文件夹
|
|
|
|
|
final FoldersListAdapter adapter = new FoldersListAdapter(this, cursor);
|
|
|
|
|
builder.setAdapter(adapter, new DialogInterface.OnClickListener() {
|
|
|
|
|
|
|
|
|
@ -458,9 +483,9 @@ public class NotesListActivity extends AppCompatActivity implements OnClickListe
|
|
|
|
|
Toast.makeText(
|
|
|
|
|
NotesListActivity.this,
|
|
|
|
|
getString(R.string.format_move_notes_to_folder,
|
|
|
|
|
mNotesListAdapter.getSelectedCount(),
|
|
|
|
|
mNotesListAdapter.getSelectedCount(),//选中的要移到的便签数量
|
|
|
|
|
adapter.getFolderName(NotesListActivity.this, which)),
|
|
|
|
|
Toast.LENGTH_SHORT).show();
|
|
|
|
|
Toast.LENGTH_SHORT).show();//当把文件夹中的便签移到文件夹外时,显示Toast消息“”已将所选+n+条便签移到上一级文件夹
|
|
|
|
|
mModeCallBack.finishActionMode();
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
@ -886,21 +911,21 @@ public class NotesListActivity extends AppCompatActivity implements OnClickListe
|
|
|
|
|
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
|
|
|
|
|
if (view instanceof NotesListItem) {
|
|
|
|
|
NoteItemData item = ((NotesListItem) view).getItemData();
|
|
|
|
|
if (mNotesListAdapter.isInChoiceMode()) {
|
|
|
|
|
if (item.getType() == Notes.TYPE_NOTE) {
|
|
|
|
|
if (mNotesListAdapter.isInChoiceMode()) {//处于选择状态
|
|
|
|
|
if (item.getType() == Notes.TYPE_NOTE) {//是便签被选中,则修改它的被选择的状态
|
|
|
|
|
position = position - mNotesListView.getHeaderViewsCount();
|
|
|
|
|
mModeCallBack.onItemCheckedStateChanged(null, position, id,
|
|
|
|
|
!mNotesListAdapter.isSelectedItem(position));
|
|
|
|
|
}
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//以下是不处于选择模式
|
|
|
|
|
switch (mState) {
|
|
|
|
|
case NOTE_LIST:
|
|
|
|
|
if (item.getType() == Notes.TYPE_FOLDER
|
|
|
|
|
if (item.getType() == Notes.TYPE_FOLDER//是文件夹被选中,则打开文件夹
|
|
|
|
|
|| item.getType() == Notes.TYPE_SYSTEM) {
|
|
|
|
|
openFolder(item);
|
|
|
|
|
} else if (item.getType() == Notes.TYPE_NOTE) {
|
|
|
|
|
} else if (item.getType() == Notes.TYPE_NOTE) {//是便签被选中,则打开该便签
|
|
|
|
|
openNode(item);
|
|
|
|
|
} else {
|
|
|
|
|
Log.e(TAG, "Wrong note type in NOTE_LIST");
|
|
|
|
|