You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Notes-master/NotesListActivity.java

368 lines
13 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

/*
* Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net)
*
* 根据Apache License, Version 2.0(以下简称“许可证”)授权;
* 您可能不会使用此文件,除非遵守许可证。
* 您可以在以下网址获得许可证的副本:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* 除非适用法律要求或书面同意,否则按照许可证分发的软件
* 按“原样”分发,不附带任何明示或暗示的保证或条件。
* 请参阅控制权限和许可证下的限制的具体语言的许可证。
*/
package net.micode.notes.ui;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.appwidget.AppWidgetManager;
import android.content.AsyncQueryHandler;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.os.AsyncTask;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.text.Editable;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.util.Log;
import android.view.ActionMode;
import android.view.ContextMenu;
import android.view.Display;
import android.view.HapticFeedbackConstants;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MenuItem.OnMenuItemClickListener;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnCreateContextMenuListener;
import android.view.View.OnTouchListener;
import android.view.inputmethod.InputMethodManager;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AdapterView.OnItemLongClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.PopupMenu;
import android.widget.TextView;
import android.widget.Toast;
import net.micode.notes.R;
import net.micode.notes.data.Notes;
import net.micode.notes.data.Notes.NoteColumns;
import net.micode.notes.gtask.remote.GTaskSyncService;
import net.micode.notes.model.WorkingNote;
import net.micode.notes.tool.BackupUtils;
import net.micode.notes.tool.DataUtils;
import net.micode.notes.tool.ResourceParser;
import net.micode.notes.ui.NotesListAdapter.AppWidgetAttribute;
import net.micode.notes.widget.NoteWidgetProvider_2x;
import net.micode.notes.widget.NoteWidgetProvider_4x;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.HashSet;
// NotesListActivity 是一个用于显示便签列表的 Activity。
public class NotesListActivity extends Activity implements OnClickListener, OnItemLongClickListener {
// 定义查询令牌,用于处理数据库查询。
private static final int FOLDER_NOTE_LIST_QUERY_TOKEN = 0;
private static final int FOLDER_LIST_QUERY_TOKEN = 1;
// 定义菜单项的常量。
private static final int MENU_FOLDER_DELETE = 0;
private static final int MENU_FOLDER_VIEW = 1;
private static final int MENU_FOLDER_CHANGE_NAME = 2;
// 定义 SharedPreferences 中保存的“添加介绍”的键。
private static final String PREFERENCE_ADD_INTRODUCTION = "net.micode.notes.introduction";
// 枚举类,表示当前列表的编辑状态。
private enum ListEditState {
NOTE_LIST, SUB_FOLDER, CALL_RECORD_FOLDER
};
private ListEditState mState;
// 后台查询处理器。
private BackgroundQueryHandler mBackgroundQueryHandler;
// 便签列表适配器。
private NotesListAdapter mNotesListAdapter;
// 便签列表视图。
private ListView mNotesListView;
// 添加新便签的按钮。
private Button mAddNewNote;
// 处理触摸事件的变量。
private boolean mDispatch;
private int mOriginY;
private int mDispatchY;
// 标题栏。
private TextView mTitleBar;
// 当前文件夹ID。
private long mCurrentFolderId;
// 内容解析器。
private ContentResolver mContentResolver;
// 模式回调。
private ModeCallback mModeCallBack;
// 日志标签。
private static final String TAG = "NotesListActivity";
// 便签列表视图滚动速率。
public static final int NOTES_LISTVIEW_SCROLL_RATE = 30;
// 焦点便签数据项。
private NoteItemData mFocusNoteDataItem;
// 普通选择和根文件夹选择的SQL语句。
private static final String NORMAL_SELECTION = NoteColumns.PARENT_ID + "=?";
private static final String ROOT_FOLDER_SELECTION = "(" + NoteColumns.TYPE + "<>"
+ Notes.TYPE_SYSTEM + " AND " + NoteColumns.PARENT_ID + "=?)" + " OR ("
+ NoteColumns.ID + "=" + Notes.ID_CALL_RECORD_FOLDER + " AND "
+ NoteColumns.NOTES_COUNT + ">0)";
// 请求代码常量。
private final static int REQUEST_CODE_OPEN_NODE = 102;
private final static int REQUEST_CODE_NEW_NODE = 103;
// onCreate 方法,初始化 Activity。
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.note_list);
initResources();
/**
* 当用户首次使用此应用程序时插入介绍。
*/
setAppInfoFromRawRes();
}
// onActivityResult 方法,处理 Activity 结果。
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK
&& (requestCode == REQUEST_CODE_OPEN_NODE || requestCode == REQUEST_CODE_NEW_NODE)) {
mNotesListAdapter.changeCursor(null);
} else {
super.onActivityResult(requestCode, resultCode, data);
}
}
// 从 raw 资源文件中设置应用程序信息。
private void setAppInfoFromRawRes() {
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this);
if (!sp.getBoolean(PREFERENCE_ADD_INTRODUCTION, false)) {
StringBuilder sb = new StringBuilder();
InputStream in = null;
try {
in = getResources().openRawResource(R.raw.introduction);
if (in != null) {
InputStreamReader isr = new InputStreamReader(in);
BufferedReader br = new BufferedReader(isr);
char [] buf = new char[1024];
int len = 0;
while ((len = br.read(buf)) > 0) {
sb.append(buf, 0, len);
}
} else {
Log.e(TAG, "Read introduction file error");
return;
}
} catch (IOException e) {
e.printStackTrace();
return;
} finally {
if(in != null) {
try {
in.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
WorkingNote note = WorkingNote.createEmptyNote(this, Notes.ID_ROOT_FOLDER,
AppWidgetManager.INVALID_APPWIDGET_ID, Notes.TYPE_WIDGET_INVALIDE,
ResourceParser.RED);
note.setWorkingText(sb.toString());
if (note.saveNote()) {
sp.edit().putBoolean(PREFERENCE_ADD_INTRODUCTION, true).commit();
} else {
Log.e(TAG, "Save introduction note error");
return;
}
}
}
}
/**
* 当 Activity 开始时调用此方法。
*/
@Override
protected void onStart() {
super.onStart(); // 调用父类的 onStart 方法。
startAsyncNotesListQuery(); // 开始异步查询便签列表。
}
/**
* 初始化资源的方法。
*/
private void initResources() {
mContentResolver = this.getContentResolver(); // 获取内容解析器。
mBackgroundQueryHandler = new BackgroundQueryHandler(this.getContentResolver()); // 创建后台查询处理器。
mCurrentFolderId = Notes.ID_ROOT_FOLDER; // 设置当前文件夹ID为根文件夹。
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); // 设置列表项长按事件监听器。
mNotesListAdapter = new NotesListAdapter(this); // 创建便签列表适配器。
mNotesListView.setAdapter(mNotesListAdapter); // 设置列表适配器。
mAddNewNote = (Button) findViewById(R.id.btn_new_note); // 获取添加新便签的按钮。
mAddNewNote.setOnClickListener(this); // 设置按钮点击事件监听器。
mAddNewNote.setOnTouchListener(new NewNoteOnTouchListener()); // 设置按钮触摸事件监听器。
mDispatch = false; // 初始化 dispatch 变量。
mDispatchY = 0; // 初始化 dispatchY 变量。
mOriginY = 0; // 初始化 originY 变量。
mTitleBar = (TextView) findViewById(R.id.tv_title_bar); // 获取标题栏。
mState = ListEditState.NOTE_LIST; // 初始化列表编辑状态。
mModeCallBack = new ModeCallback(); // 创建模式回调对象。
}
/**
* ModeCallback 内部类,实现 ListView 多选模式监听器和菜单项点击事件。
*/
private class ModeCallback implements ListView.MultiChoiceModeListener, OnMenuItemClickListener {
private DropdownMenu mDropDownMenu; // 下拉菜单。
private ActionMode mActionMode; // 动作模式。
private MenuItem mMoveMenu; // 移动菜单项。
/**
* 创建动作模式时调用。
* @param mode 动作模式。
* @param menu 菜单。
* @return 是否创建成功。
*/
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
// 省略部分代码...
}
/**
* 更新菜单项。
*/
private void updateMenu() {
// 省略部分代码...
}
/**
* 准备动作模式时调用。
* @param mode 动作模式。
* @param menu 菜单。
* @return 是否准备成功。
*/
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
// TODO Auto-generated method stub
return false;
}
/**
* 动作模式中的菜单项被点击时调用。
* @param mode 动作模式。
* @param item 菜单项。
* @return 是否处理成功。
*/
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
// TODO Auto-generated method stub
return false;
}
/**
* 动作模式销毁时调用。
* @param mode 动作模式。
*/
public void onDestroyActionMode(ActionMode mode) {
// 省略部分代码...
}
/**
* 结束动作模式。
*/
public void finishActionMode() {
mActionMode.finish();
}
/**
* 列表项选中状态改变时调用。
* @param mode 动作模式。
* @param position 位置。
* @param id ID。
* @param checked 是否选中。
*/
public void onItemCheckedStateChanged(ActionMode mode, int position, long id, boolean checked) {
// 省略部分代码...
}
/**
* 菜单项点击事件。
* @param item 菜单项。
* @return 是否处理成功。
*/
public boolean onMenuItemClick(MenuItem item) {
// 省略部分代码...
}
}
/**
* NewNoteOnTouchListener 内部类,处理添加新便签按钮的触摸事件。
*/
private class NewNoteOnTouchListener implements OnTouchListener {
/**
* 触摸事件处理。
* @param v 视图。
* @param event 触摸事件。
* @return 是否处理成功。
*/
public boolean onTouch(View v, MotionEvent event) {
// 省略部分代码...
}
}
/**
* 开始异步查询便签列表。
*/
private void startAsyncNotesListQuery() {
// 省略部分代码...
}
/**
* BackgroundQueryHandler 内部类,继承自 AsyncQueryHandler处理后台查询。
*/
private final class BackgroundQueryHandler extends AsyncQueryHandler {
/**
* 构造函数。
* @param contentResolver 内容解析器。
*/
public BackgroundQueryHandler(ContentResolver contentResolver) {
super(contentResolver);
}
/**
* 查询完成时调用。
* @param token 令牌。
* @param cookie 饼干。
* @param cursor 游标。
*/
@Override
protected void onQueryComplete(int token, Object cookie, Cursor cursor) {
// 省略部分代码...
}
}