|
|
|
|
@ -148,6 +148,15 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
|
|
|
|
|
|
|
|
|
|
/** 模式回调 */
|
|
|
|
|
private ModeCallback mModeCallBack;
|
|
|
|
|
|
|
|
|
|
/** 是否分发触摸事件 */
|
|
|
|
|
private boolean mDispatch;
|
|
|
|
|
|
|
|
|
|
/** 原始Y坐标 */
|
|
|
|
|
private int mOriginY;
|
|
|
|
|
|
|
|
|
|
/** 分发Y坐标 */
|
|
|
|
|
private int mDispatchY;
|
|
|
|
|
|
|
|
|
|
/** 日志标签 */
|
|
|
|
|
private static final String TAG = "NotesListActivity";
|
|
|
|
|
@ -298,12 +307,10 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
|
|
|
|
|
mNotesListView.setAdapter(mNotesListAdapter);
|
|
|
|
|
mAddNewNote = (Button) findViewById(R.id.btn_new_note);
|
|
|
|
|
mAddNewNote.setOnClickListener(this);
|
|
|
|
|
// 移除复杂的OnTouchListener,简化触摸事件处理
|
|
|
|
|
// mAddNewNote.setOnTouchListener(new NewNoteOnTouchListener());
|
|
|
|
|
// 移除不再需要的触摸事件相关变量
|
|
|
|
|
// mDispatch = false;
|
|
|
|
|
// mDispatchY = 0;
|
|
|
|
|
// mOriginY = 0;
|
|
|
|
|
mAddNewNote.setOnTouchListener(new NewNoteOnTouchListener());
|
|
|
|
|
mDispatch = false;
|
|
|
|
|
mDispatchY = 0;
|
|
|
|
|
mOriginY = 0;
|
|
|
|
|
mTitleBar = (TextView) findViewById(R.id.tv_title_bar);
|
|
|
|
|
mState = ListEditState.NOTE_LIST;
|
|
|
|
|
mModeCallBack = new ModeCallback();
|
|
|
|
|
@ -354,6 +361,11 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
|
|
|
|
|
mMoveMenu.setVisible(true);
|
|
|
|
|
mMoveMenu.setOnMenuItemClickListener(this);
|
|
|
|
|
}
|
|
|
|
|
// 添加置顶菜单初始化
|
|
|
|
|
MenuItem pinMenu = menu.findItem(R.id.pin);
|
|
|
|
|
if (pinMenu != null) {
|
|
|
|
|
pinMenu.setOnMenuItemClickListener(this);
|
|
|
|
|
}
|
|
|
|
|
mActionMode = mode;
|
|
|
|
|
mNotesListAdapter.setChoiceMode(true);
|
|
|
|
|
mNotesListView.setLongClickable(false);
|
|
|
|
|
@ -513,6 +525,9 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
|
|
|
|
|
case R.id.move:
|
|
|
|
|
startQueryDestinationFolders();
|
|
|
|
|
break;
|
|
|
|
|
case R.id.pin:
|
|
|
|
|
togglePinnedStatus();
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
@ -520,10 +535,93 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 删除不再使用的NewNoteOnTouchListener内部类
|
|
|
|
|
// private class NewNoteOnTouchListener implements OnTouchListener {
|
|
|
|
|
// // ... 内部类内容 ...
|
|
|
|
|
// };
|
|
|
|
|
/**
|
|
|
|
|
* 新建笔记按钮触摸监听器
|
|
|
|
|
* <p>
|
|
|
|
|
* 该类实现了OnTouchListener接口,用于处理新建笔记按钮的触摸事件,
|
|
|
|
|
* 特别是处理按钮透明部分的触摸事件,将其分发给下方的列表视图
|
|
|
|
|
* </p>
|
|
|
|
|
*/
|
|
|
|
|
private class NewNoteOnTouchListener implements OnTouchListener {
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 处理触摸事件
|
|
|
|
|
* <p>
|
|
|
|
|
* 该方法完成以下工作:
|
|
|
|
|
* 1. 处理ACTION_DOWN事件:
|
|
|
|
|
* - 获取屏幕高度和新建笔记按钮高度
|
|
|
|
|
* - 计算触摸事件的Y坐标
|
|
|
|
|
* - 如果当前状态是SUB_FOLDER,减去标题栏高度
|
|
|
|
|
* - 检查触摸点是否在按钮的透明部分(根据公式y=-0.12x+94判断)
|
|
|
|
|
* - 如果是,将触摸事件分发给下方的列表视图
|
|
|
|
|
* 2. 处理ACTION_MOVE事件:
|
|
|
|
|
* - 如果已经开始分发事件,更新事件坐标并继续分发给列表视图
|
|
|
|
|
* 3. 处理其他事件:
|
|
|
|
|
* - 如果已经开始分发事件,结束分发并将事件分发给列表视图
|
|
|
|
|
* </p>
|
|
|
|
|
* @param v 被触摸的视图
|
|
|
|
|
* @param event 触摸事件
|
|
|
|
|
* @return 是否消费了该事件,返回true表示已消费
|
|
|
|
|
*/
|
|
|
|
|
public boolean onTouch(View v, MotionEvent event) {
|
|
|
|
|
switch (event.getAction()) {
|
|
|
|
|
case MotionEvent.ACTION_DOWN: {
|
|
|
|
|
Display display = getWindowManager().getDefaultDisplay();
|
|
|
|
|
int screenHeight = display.getHeight();
|
|
|
|
|
int newNoteViewHeight = mAddNewNote.getHeight();
|
|
|
|
|
int start = screenHeight - newNoteViewHeight;
|
|
|
|
|
int eventY = start + (int) event.getY();
|
|
|
|
|
/**
|
|
|
|
|
* Minus TitleBar's height
|
|
|
|
|
*/
|
|
|
|
|
if (mState == ListEditState.SUB_FOLDER) {
|
|
|
|
|
eventY -= mTitleBar.getHeight();
|
|
|
|
|
start -= mTitleBar.getHeight();
|
|
|
|
|
}
|
|
|
|
|
/**
|
|
|
|
|
* HACKME:When click the transparent part of "New Note" button, dispatch
|
|
|
|
|
* the event to the list view behind this button. The transparent part of
|
|
|
|
|
* "New Note" button could be expressed by formula y=-0.12x+94(Unit:pixel)
|
|
|
|
|
* and the line top of the button. The coordinate based on left of the "New
|
|
|
|
|
* Note" button. The 94 represents maximum height of the transparent part.
|
|
|
|
|
* Notice that, if the background of the button changes, the formula should
|
|
|
|
|
* also change. This is very bad, just for the UI designer's strong requirement.
|
|
|
|
|
*/
|
|
|
|
|
if (event.getY() < (event.getX() * (-0.12) + 94)) {
|
|
|
|
|
View view = mNotesListView.getChildAt(mNotesListView.getChildCount() - 1
|
|
|
|
|
- mNotesListView.getFooterViewsCount());
|
|
|
|
|
if (view != null && view.getBottom() > start
|
|
|
|
|
&& (view.getTop() < (start + 94))) {
|
|
|
|
|
mOriginY = (int) event.getY();
|
|
|
|
|
mDispatchY = eventY;
|
|
|
|
|
event.setLocation(event.getX(), mDispatchY);
|
|
|
|
|
mDispatch = true;
|
|
|
|
|
return mNotesListView.dispatchTouchEvent(event);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case MotionEvent.ACTION_MOVE: {
|
|
|
|
|
if (mDispatch) {
|
|
|
|
|
mDispatchY += (int) event.getY() - mOriginY;
|
|
|
|
|
event.setLocation(event.getX(), mDispatchY);
|
|
|
|
|
return mNotesListView.dispatchTouchEvent(event);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
default: {
|
|
|
|
|
if (mDispatch) {
|
|
|
|
|
event.setLocation(event.getX(), mDispatchY);
|
|
|
|
|
mDispatch = false;
|
|
|
|
|
return mNotesListView.dispatchTouchEvent(event);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 启动异步笔记列表查询
|
|
|
|
|
@ -537,7 +635,7 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
|
|
|
|
|
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");
|
|
|
|
|
}, NoteColumns.PINNED + " DESC," + NoteColumns.TYPE + " DESC," + NoteColumns.MODIFIED_DATE + " DESC");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
@ -670,6 +768,54 @@ public class NotesListActivity extends Activity implements OnClickListener, OnIt
|
|
|
|
|
}.execute();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 切换选中便签的置顶状态
|
|
|
|
|
*/
|
|
|
|
|
private void togglePinnedStatus() {
|
|
|
|
|
final HashSet<Long> selectedIds = mNotesListAdapter.getSelectedItemIds();
|
|
|
|
|
final int selectedCount = mNotesListAdapter.getSelectedCount();
|
|
|
|
|
|
|
|
|
|
new AsyncTask<Void, Void, Void>() {
|
|
|
|
|
protected Void doInBackground(Void... unused) {
|
|
|
|
|
for (Long noteId : selectedIds) {
|
|
|
|
|
// 查询当前便签的置顶状态
|
|
|
|
|
Cursor cursor = mContentResolver.query(Notes.CONTENT_NOTE_URI,
|
|
|
|
|
new String[]{NoteColumns.PINNED},
|
|
|
|
|
NoteColumns.ID + "=?",
|
|
|
|
|
new String[]{String.valueOf(noteId)},
|
|
|
|
|
null);
|
|
|
|
|
|
|
|
|
|
if (cursor != null && cursor.moveToFirst()) {
|
|
|
|
|
int currentPinned = cursor.getInt(0);
|
|
|
|
|
// 切换置顶状态
|
|
|
|
|
int newPinned = currentPinned == 1 ? 0 : 1;
|
|
|
|
|
|
|
|
|
|
ContentValues values = new ContentValues();
|
|
|
|
|
values.put(NoteColumns.PINNED, newPinned);
|
|
|
|
|
|
|
|
|
|
mContentResolver.update(Notes.CONTENT_NOTE_URI,
|
|
|
|
|
values,
|
|
|
|
|
NoteColumns.ID + "=?",
|
|
|
|
|
new String[]{String.valueOf(noteId)});
|
|
|
|
|
|
|
|
|
|
cursor.close();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
protected void onPostExecute(Void unused) {
|
|
|
|
|
Toast.makeText(NotesListActivity.this,
|
|
|
|
|
"已更新 " + selectedCount + " 个便签",
|
|
|
|
|
Toast.LENGTH_SHORT).show();
|
|
|
|
|
// 重新查询数据,更新列表
|
|
|
|
|
startAsyncNotesListQuery();
|
|
|
|
|
mModeCallBack.finishActionMode();
|
|
|
|
|
}
|
|
|
|
|
}.execute();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 删除文件夹
|
|
|
|
|
* <p>
|
|
|
|
|
|